我已授权访问UsbDevice,获取设备名称(/dev/bus/usb/002/002
)并将其传递给已执行的进程以使用USB设备( avrdude 更详细)
Process process = Runtime.getRuntime().exec(commandArray);
并获取“权限被拒绝”错误:
W/System.err( 9368): avrdude: ser_open(): can't open device "/dev/bus/usb/002/002": Permission denied
W/System.err( 9368): ioctl("TIOCMGET"): Invalid argument
Avrdude位于应用沙箱(/data/data/%package%
)中,因此不需要只需执行avrdude(肯定)。我相信如果我授予访问UsbDevice android应用程序进程的权限,并且所有子进程(avrdude)都可以访问相应的USB设备文件。
有什么想法?生根是不受欢迎的。
答案 0 :(得分:2)
看来Android USB主机API是访问USB设备所必需的,您可能无法像在普通Linux系统上那样直接从本机代码访问设备文件。
鉴于此限制,我认为有一些可能的解决方法。您的ArduinoDroid应用程序需要从Java读取/写入USB,因此问题是如何在avrdude和ArduinoDroid之间传递数据。根据我的经验,一种好的方法是通过网络连接。例如,以下avrdude命令将使用端口6800上的localhost对Arduino进行编程。
avrdude -v -patmega328p -carduino -Pnet:localhost:6800 -D -Uflash:w:firmware.hex:i
我通过连接到我的串行镜像应用程序并通过蓝牙编程Arduino,在Linux-on-Android上运行avrdude时自己完成了这项工作。我在本演讲中解释了这个程序。
http://jeffboody.net/sparkfun-lunch-and-learn-20130124.pdf
我的串行镜像应用程序的源代码也可以在这里找到。
https://github.com/jeffboody/spp-mirror
如果使用“exec”调用avrdude不提供网络权限,您可能需要将avrdude构建为库,以便它具有与您的应用相同的权限。 Android本机代码支持套接字。
我能想到的第二个选择是提供一个JNI接口来avrdude通过Java读/写USB。我认为这会更加困难,因为它可能需要对avrdude做出重大改变。
答案 1 :(得分:1)
关于文件描述符,您可以使用JNI将其传递给native。
// java
private native void NativePassFd(int fd);
// c
JNIEXPORT void JNICALL Java_com_MyName_MyPackage_MyClass_NativePassFd(JNIEnv * env,jobject obj,jint fd);
从本机代码中,您应该能够使用读/写功能。这些应该与fread / fwrite相同,除非它们使用fd而不是FILE指针。重要的是fd在另一个进程中无效(除非通过Android的Binder机制等特殊机制传递。
ssize_t read(int fd,void * buf,size_t count);
ssize_t write(int fd,const void * buf,size_t count);