2017-06-02 139 views
1

我正尝试在Android上与USB OTG设备进行连接。由于代码是一个有点冗长,我只概述基础:USB OTG设备在拔出并重新插入后不起作用

  • 有与USB_DEVICE_ATTACHED(过滤的设备ID我感兴趣的)意图过滤器的活动在清单中声明。
  • 当活动以该特定意图启动时,它启动服务并将USB设备作为参数传递。
  • 当服务启动时,它为USB_DEVICE_DETACHED注册广播接收器,然后连接到设备并开始与它进行交互(当前生成一些日志输出)。
  • 当收到USB断开广播时设备是当前正在使用的设备,在USB设备连接上调用close()并停止服务。

该设备是一个Si4701 USB FM调谐器,它表现为USB HID设备。

当我第一次插入设备时,我看到我的服务连接到它,可以更换频道并接收RDS数据。但是,当我拔下插头并重新插入时,我看到服务再次连接到它(并且显然已成功读取设备寄存器),但它无法更改频率,并且我从未看到任何RDS数据。

如果我强迫应用拔出并重新插入设备之间的停止,该设备在geing插回后正常工作。

这表明一些清理工作无法进行,或者一些资源没有被正确释放。但是:

  • 我不保留任何数据结构与设备之间的连接。与USB连接相关的所有内容都是在检测到设备时创建的类实例中,并且这些类的所有静态成员都是最终的。
  • 有些东西在重新插入设备后有效,例如读取设备类型和固件版本的寄存器(通过获取USB HID功能报告来工作)。初始化还会设置一些寄存器(通过发送USB特性报告),该寄存器不会返回错误 - 但频率变化(也涉及设置寄存器)不起作用。
  • 拔出和重新插入之间约15分钟的间隔不起作用(设备不起作用)。另一方面,如果我拔掉设备,杀掉服务并重新插入服务器,它会立即生效 - 所以问题肯定在Android端,而不是在设备端。

我需要做些什么才能使USB设备在拔出/重新接通循环后工作?

回答

0

我还没有完全理解这里发生了什么,但它现在似乎工作。

我应该提到该应用程序是多线程的,并且Si470x封装类正在从多线程中调用。

由于这导致竞争条件(一个线程在另一个线程关闭时访问设备),我正确地声明所有方法为​​,以便两个线程不能同时访问tuner类的方法。将设备插入,拔出插头,插入并观察,它会改变频率并按照预期的方式吐出RDS数据。

怀疑:

UsbDeviceConnection#close()可能不是线程安全的。

结论:

  • 总是调用UsbDeviceConnection#close()当你与设备(包括当设备断开)来完成。
  • 如果您的应用程序是多线程的,请确保访问USB连接(直接或间接)的所有内容都已正确同步。