I am trying to interface with a USB OTG device on Android. Since code is a bit lengthy, I will just outline the basics:
USB_DEVICE_ATTACHED
(filtered for the device IDs I am interested in) declared in the manifest.USB_DEVICE_DETACHED
, then connects to the device and starts interacting with it (which currently generates some log output).close()
is called on the USB device connection and the service stops.The device is a Si4701 USB FM tuner, which presents itself as a USB HID device.
When I first plug in the device, I see my service connects to it, can change channels and receives RDS data.
However, when I unplug it and plug it back in, I see the service connecting to it again (and again apparently successfully reading the device registers), but it fails to change frequencies and I never see any RDS data.
If I force the app to stop between unplugging and replugging the device, the device works normally after geing plugged back in.
This suggests some cleanup fails to take place, or some resource isn’t being released properly. However:
What do I need to do to make the USB device work after an unplug/replug cycle?
I still don’t fully understand what is happening here, but it seems to work now.
I should mention that the app is multi-threaded and the Si470x wrapper class is getting called from multiple threads.
Since this has resulted in race conditions (one thread accessing the device when another thread had just closed it), I properly declared all methods as synchronized
so that no two threads can access methods of the tuner class at the same time. Plugged the device in, unplugged it, plugged it back in—and lo and behold, it changes frequencies and spits out RDS data the way it is supposed to.
Suspicion:
UsbDeviceConnection#close()
might not be thread-safe.
Conclusions:
UsbDeviceConnection#close()
when you’re done with the device (including when the device is detached).