从 Android USB 附件读取会引发 ENODEV IOException
Posted
技术标签:
【中文标题】从 Android USB 附件读取会引发 ENODEV IOException【英文标题】:Reading from Android USB Accessory throws ENODEV IOException 【发布时间】:2012-10-21 02:46:18 【问题描述】:所以我实现了 android USB 附件 API,这样我就可以将手机插入运行 linux 的笔记本电脑,并将手机置于 USB 附件模式。然后我可以访问附件,打开它,然后开始读取它的内容。我的代码看起来几乎与the documentation 中的示例相同。主要区别在于我使用单独的读取和写入方法并通过 JNI 从本机代码访问它们。
这就是有趣的地方。在成功读/写一两秒后,从我的笔记本电脑进行的批量传输写入开始出现超时错误,然后在 Android 中对 USB 附件的读取调用会引发带有 ENODEV 错误代码的 IOException。这是在电缆仍然连接并且 UsbManager 仍然在列表中列出附件的情况下,并且我仍然拥有它的权限。
更奇怪的是,我发现如果我在读取循环中设置 100 毫秒的睡眠时间,问题基本上就消失了(尽管有时仍会发生)。在那里睡觉不仅是一件可怕的事情,而且会给我的应用程序带来无法忍受的延迟。睡眠时间越短,黑客攻击的效果就越差,在 10 毫秒的睡眠时间就无效了。
我正在使用批量传输传输大约 20-30kbps 的实时数据(但不是实时到批量传输不够),传输大小范围从 50 到 800 字节,大约 20- 30赫兹。会不会是 USB 的限制?我没有太多的经验,所以我基本上把它当作网络套接字来对待。我是否应该将较小的消息排队并以较低频率但较大的传输一起发送?小型高频批量传输是否存在问题?我会调查一下,但我基本上是在抓住稻草。
硬件:
笔记本电脑正在运行 Ubuntu 10.04 并使用 libusb 1.0.0。 手机是 Galaxy Nexus S 运行的 Android 4.1.2。【问题讨论】:
【参考方案1】:所以,虽然我仍然不了解正在发生的一切,但实施双缓冲方案解决了我的问题。
我发现全速读取的 Java Android 应用程序没有遇到 ENODEV 问题,这使我得出结论,Java 原生接口是我问题的根源。
以前,我直接从从 JNI 以轮询方式调用的方法读取 UsbAccessory。从本机代码到 Java,然后从 Java 到本机 Android 内核的转变显然让一切变得暴躁。
我的解决方法是从纯 Java 线程(无 JNI 调用)读取/写入 UsbAccessory,然后缓冲该数据以从 JNI 调用的方法读取/写入。
看起来像一个魅力。在我在附件端非常一致地收到发送超时之前,然后最终在 Android 端出现如上所述的 IOExeception,现在我没有超时,也没有 IOExceptions。我仍然有点好奇究竟是什么导致了这种行为,但我怀疑它需要强大的 JNI 功夫才能理解。
【讨论】:
以上是关于从 Android USB 附件读取会引发 ENODEV IOException的主要内容,如果未能解决你的问题,请参考以下文章
从适用于 Android 的 USB RFID 阅读器读取数据