我正在尝试与Android上的USB OTG设备接口。由于代码有点冗长,我将概述基础知识:
- 有一个用于
USB_DEVICE_ATTACHED
的意图过滤器的活动(对我感兴趣的设备ID进行了过滤(。 - 当该活动以该特定意图启动时,它启动了一项服务,并通过参数传递USB设备。
- Servie启动时,它会为
USB_DEVICE_DETACHED
注册广播接收器,然后连接到设备并开始与它进行交互(目前会生成一些日志输出(。 - 当收到USB断开广播和时,该设备是当前使用的设备时,
close()
在USB设备连接上被调用,服务停止。
该设备是SI4701 USB FM调谐器,它以USB HID设备表示。
首次插入设备时,我看到我的服务连接到它,可以更改频道并接收RDS数据。
但是,当我拔下插头并将其插入后,我看到该服务再次连接到它(显然是成功读取设备寄存器(,但是它无法更改频率,我从未看到任何RDS数据。p>如果我强迫应用程序在拔下设备和换插之间停止,则该设备在Geing插入后正常工作。
这表明一些清理未能进行,或者某些资源未正确发布。但是:
- 我不保留任何数据结构与连接之间的设备相关。与USB连接相关的所有内容都是在检测到设备时创建的类实例,并且这些类的所有静态成员都是最终的。
- 重复设备后有些事情可以使用,例如为设备类型和固件版本阅读寄存器(通过获取USB HID功能报告来起作用(。初始化还设置了一些寄存器(通过发送USB功能报告(,该寄存器不会返回错误,但是更改频率(也涉及设置寄存器(不起作用。
- 拔出插头和重击之间的一个〜15分钟的间隔没有效果(设备不起作用(。另一方面,如果我拔下设备,杀死服务并将其插入后,它可以立即工作 - 因此,问题肯定在Android侧而不是设备侧。
在拔出/重新插入周期后,我需要做什么才能使USB设备工作?
我仍然不完全了解这里发生的事情,但现在似乎有效。
我应该提到该应用是多线程,而SI470X包装器类正在从多个线程中调用。
由于这导致了竞赛条件(另一个线程刚刚关闭时,一个线程访问设备(,所以我将所有方法正确声明为synchronized
,这样没有两个线程可以同时访问调谐器类的方法。将设备插入,将其插入,将其插入并插入并观察,它会更改频率并按照应有的方式吐出RDS数据。
怀疑:
UsbDeviceConnection#close()
可能不是线程安全。
结论:
- 完成设备后,请始终致电
UsbDeviceConnection#close()
(包括设备分离时(。 - 如果您的应用程序是多线程的,请确保正确同步(直接或间接(访问USB连接的所有内容。