I have an application that uses a proprietary USB device (android in host mode).
I have a BroadcastReceiver
which I register in the constructor
// this block is in the constructor
usbConnectionReceiver = new UsbConnectionReceiver();
IntentFilter filter = new IntentFilter();
filter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED);
filter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED);
context.registerReceiver(usbConnectionReceiver, filter);
public class UsbConnectionReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (UsbManager.ACTION_USB_DEVICE_ATTACHED.equals(action)) {
UsbDevice device = intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
if (device != null) onDeviceAttached(device);
} else if (UsbManager.ACTION_USB_DEVICE_DETACHED.equals(action)) {
UsbDevice device = intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
if (device != null) onDeviceDetached(device);
}
}
}
public void onDeviceAttached(UsbDevice device) {
usbDevice = device;
intf = usbDevice.getInterface(0);
endpoint = intf.getEndpoint(0);
if (usbManager.hasPermission(usbDevice)) {
usbDeviceConnection = usbManager.openDevice(usbDevice);
boolean status = usbDeviceConnection.claimInterface(intf, true);
if (status) {
startPollingThread();
}
} else {
// I used to have code here that would programmatically prompt for permissions.
}
}
Everything works great, except that every time the device is detached and reattached, the end-user is prompted for permissions. The "Use by default for this USB device" checkbox is completely ignored.
After some research, it appears that if I ask for permissions via code, that is indeed the case.
So I've switched my activity to use an intent filter. I no longer get the permissions box after the first time, so the checkbox is working. Instead, every time the device is reattached, it calls onCreate()
of my app, crashing it.
I have the launchMode="singleInstance"
(in fact, I've tried all varieties), and while the app is up and running and top on the screen, the onCreate()
is called instead of the onNewIntent()
(which the documentation seems to suggest should happen).
I also read that I need to set android:launchMode="singleInstance"
I also read I need to set android:taskAffinity=""
All to no avail. I know there are tons of similar posts, but none of them seem to work. Any advice is appreciated.
Here is my AndroidManifest.xml:
<?xml version="1.0" encoding="utf-8"?>
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
package="com.me.myapp" >
<application
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:theme="@android:style/Theme.Holo.NoActionBar.Fullscreen"
android:launchMode="singleInstance" >
<activity
android:name=".MainActivity"
android:taskAffinity=""
android:label="@string/app_name"
android:configChanges="keyboard" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" />
</intent-filter>
<meta-data
android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED"
android:resource="@xml/device_filter" />
</activity>
</application>
</manifest>
I believe this is the best solution ... if anyone has a comment, I'd love to hear it because Usb handling in android has always been a headache!
I used this post as a reference USB device access pop-up supression?
I created the following Activity
And added it to the manifest
with the following style.xml