I was able to read up here about how to launch my app when a USB accessory is attached, and that much all works fine: I have an IntentFilter built into my manifest which will launch the appropriate activity each time the specified accessory is attached. Here is how that looks:
<activity
android:name=".MainActivity"
android:label="@string/app_name"
android:exported="true">
<intent-filter>
<action android:name="android.hardware.usb.action.USB_ACCESSORY_ATTACHED" />
</intent-filter>
<meta-data
android:name="android.hardware.usb.action.USB_ACCESSORY_ATTACHED"
android:resource="@xml/accessory_filter" />
</activity>
However, I am having issues if my Activity is already running when the accessory is attached. Within MainActivity, I look for the USB_ACCESSORY_ATTACHED Intent in two places: onCreate, and onNewIntent, like so:
protected void onCreate(Bundle savedInstanceState) {
//Check for some other actions first
if (UsbManager.ACTION_USB_ACCESSORY_ATTACHED.equals(intent.getAction()))
usbAttached(intent);
}
protected void onNewIntent(Intent intent) {
if (UsbManager.ACTION_USB_ACCESSORY_ATTACHED.equals(intent.getAction()))
usbAttached(intent);
}
However, neither onCreate nor onNewIntent is being called when the accessory is plugged in if MainActivity is already running. In that case, I need to close my app before plugging in the accessory, which would be a hassle for users. What would be the appropriate way to receive the Intent from my USB accessory if my activity is already running? Would I need to implement a separate listener within the activity itself?
If you look at the documentation of onNewIntent()
it reads:
protected void onNewIntent (Intent intent)
Added in API level 1
This is called for activities that set launchMode to "singleTop" in their package, or if a client used the FLAG_ACTIVITY_SINGLE_TOP flag when calling startActivity(Intent). In either case, when the activity is re-launched while at the top of the activity stack instead of a new instance of the activity being started, onNewIntent() will be called on the existing instance with the Intent that was used to re-launch it.
...
So you need to set the launchMode
of your Activity
to singleTop
in your manifest, otherwise you will receive no calls to onNewIntent()
. The result should look something like this:
<activity
android:name=".MainActivity"
android:label="@string/app_name"
android:launchMode="singleTop"
android:exported="true">
...
</activity>
If you think about it that behavior actually makes a lot of sense. Next time look at the documentation before asking here. Don't assume how stuff works if you don't know.