android - 从 Android USB 附件读取会抛出 ENODEV IOException

标签 android usb libusb

因此,我已经实现了 Android USB Accessory API,这样我就可以将手机插入运行 Linux 的笔记本电脑,并将手机置于 USB Accessory 模式。然后我可以访问配件,打开它,然后开始阅读对它的写作。我的代码看起来与 the documentation 中的示例几乎相同.主要区别在于我使用单独的读取和写入方法并通过 JNI 从 native 代码访问它们。

这就是它变得有趣的地方。在成功读取/写入一两秒后,从我的笔记本电脑进行的批量传输写入开始出现超时错误,然后在 Android 中对 USB 附件的读取调用抛出一个带有 ENODEV 错误代码的 IOException。这是电缆仍然连接并且 UsbManager 仍然在列表中列出配件,我仍然拥有它的权限。

更奇怪的是,我发现如果我在读取循环中休眠 100 毫秒,问题基本上就会消失(尽管偶尔仍会发生)。睡在那里不仅会造成可怕的困惑,还会给我的应用程序带来无法忍受的延迟。休眠时间越短,hack 的效果就越差,直到 10 毫秒的休眠时间无效。

我正在使用批量传输传输大约 20-30kbps 的实时数据(但不是实时到批量传输是不够的),传输大小范围为 50 到 800 字节,大约 20- 30赫兹。会不会是USB的限制?我没有太多的经验,所以我基本上把它当作网络套接字来对待。我是否应该将较小的消息排队,然后以频率较低但传输量较大的方式将它们一起发送出去?小的、高频的批量传输有问题吗?我会调查这个,但我基本上是在捕获救命稻草。

硬件:

  • 笔记本电脑正在运行 Ubuntu 10.04 并使用 libusb 1.0.0。
  • 手机是运行原装 Android 4.1.2 的 Galaxy Nexus S。

最佳答案

因此,虽然我仍然不明白正在发生的一切,但实现双缓冲方案解决了我的问题。

我发现全速读取的 Java Android 应用程序没有遇到 ENODEV 问题,这使我得出结论,Java native 接口(interface)是问题的根源。

以前,我以轮询方式直接从 JNI 调用的方法中读取 UsbAccessory。从 native 代码到 Java,然后从 Java 向下到 native Android 内核的过渡显然让一切变得脾气暴躁。

我的解决方法是从纯 Java 线程(无 JNI 调用)读取/写入 UsbAccessory,然后缓冲该数据以从 JNI 调用的方法读取/写入。

似乎很有魅力。之前我一直在附件端发送超时,然后最终如上所述在 Android 端发送 IOExeception,现在我没有超时,没有 IOExceptions。我仍然有点好奇到底是什么导致了这种行为,但我怀疑这需要强大的 JNI 功夫才能理解。

关于android - 从 Android USB 附件读取会抛出 ENODEV IOException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13161406/

相关文章:

c - 在 linux 上用 libusb 编译 c 代码的问题

c - 内存泄漏同步读取中断通过libUSB传输数据

python - 使用 PyUSB 从 Tenma 72-7732 万用表读取数据

android - Google map v2 的自定义信息窗口

java - Usb4java 库,在 Windows 机器上声明接口(interface)时出错

java - Image Adapter + Gallery 成像循环

linux - 如何在 Linux 上安装 Wireshark 并捕获 USB 流量?

Android USB与PC通讯

java - 在 Java Android 应用程序中使用 Kotlin 代码

java - Android 共享 Intent - 某些文件不会共享