I have an app which interacts with a USB OTG device:
IntentFilter
in the manifest.onCreate()
method populates an IntentFilter
, adding the actions to which the service should react when running, including UsbManager.ACTION_USB_DEVICE_DETACHED
. Adding extra debug output tells me the method runs when I expect it to, i.e. the IntentFilter
is populated when I register the receiver.onStartCommand()
method calls an internal method which registers the BroadcastReceiver
for the intent filter (if the service was started with the start intent, and has the necessary permissions—else the service terminates).UsbManager.ACTION_USB_DEVICE_DETACHED
and the device reported is the one that is currently connected, it stops the service.Now, if I plug in the USB device, I get the confirmation and the service starts, and when I unplug the device, the service stops again. So far, so good.
However, in some cases the service keeps running even after the device is unplugged. I have noticed this always happens when the main activity was open when I connected the device. Logs show me that the service never receives the UsbManager.ACTION_USB_DEVICE_DETACHED
broadcast.
While doing further tests (open main activity and navigate away from it before connecting the device), I found evidence that there may be two instances of the service running for some reason.
What is happening here, and how can I reliably detect that the USB device was disconnected?
This behavior appears to be caused by two factors:
!=
to compare the two UsbDevice
instances, which fails to catch two different class instances referring to the same device.So we need to do two things:
UsbDevice#equals()
rather than the equality operator for comparison.