【问题标题】:Does process executed from android app have the same rights as android app?从 android 应用程序执行的进程是否具有与 android 应用程序相同的权利?
【发布时间】:2013-06-04 04:55:37
【问题描述】:

我已授予对 UsbDevice 的访问权限,获得了他的设备名称 (/dev/bus/usb/002/002) 并将其传递给执行进程以使用 USB 设备(avrdude 更详细)

Process process = Runtime.getRuntime().exec(commandArray);

并得到“permission denied”错误:

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%) 中,因此它不需要 root 即可执行 avrdude(当然)。我相信如果我授予对 UsbDevice android 应用程序进程的访问权限,并且所有子进程 (avrdude) 都可以访问相应的 USB 设备文件。

有什么想法吗?不希望生根。

【问题讨论】:

  • 更新:应用程序即使在获得 UsbDevice 的权限后也无法读取/写入 USB 设备文件:File usbDeviceFile = new File(usbDevice.getDeviceName()); logger.debug("{}exists, canRead={}, canWrite={}", new Object[] { usbDeviceFile.exists() ? "" : "NOT ", usbDeviceFile.canRead(), usbDeviceFile.canWrite() }); 返回:D/ArduinoDroid( 2350): device name = /dev/bus/usb/002/002 D/ArduinoDroid( 2350): exists, canRead=false, canWrite=false
  • 是的,它们是相同的,但这里的问题是您正在尝试在本机端使用不同的 API,应用程序和在其 UID 下运行的可执行文件都无法使用该 API .除了少数在 unix 组级别(例如网络)实现的权限之外,所有权限实际上都是基于 Binder IPC 的 API 的启用程序,除非您能找到某种方法将其注册到 Binder,否则本机可执行文件无法使用这些权限。
  • 根据我的 UPDATE android 应用程序本身没有该文件的权限。所以无论如何尝试从子进程(avrdude)访问它是没有意义的。不可能?

标签: android permissions usb avrdude


【解决方案1】:

似乎需要 Android USB 主机 API 才能访问 USB 设备,并且您可能无法像在普通 Linux 系统上所期望的那样直接从本机代码访问设备文件。

鉴于此限制,我认为有几种可能的解决方法。您的 ArduinoDroid 应用程序需要从 Java 读取/写入 USB,所以问题是如何在 avrdude 和 ArduinoDroid 之间传递数据。根据我的经验,一个好的方法是通过网络连接。例如,以下 avrdude 命令将使用 localhost 的 6800 端口对 Arduino 进行编程。

avrdude -v -patmega328p -carduino -Pnet:localhost:6800 -D -Uflash:w:firmware.hex:i

我自己在 Linux-on-Android 中运行 avrdude 时通过连接到我的 Serial Mirror 应用程序并通过蓝牙对 Arduino 进行编程。我已在此演示文稿中解释了此过程。

http://jeffboody.net/sparkfun-lunch-and-learn-20130124.pdf

我的 Serial Mirror 应用程序的源代码也可以在这里找到。

https://github.com/jeffboody/spp-mirror

如果使用“exec”调用 avrdude 不授予网络权限,您可能需要将 avrdude 构建为库,以便它具有与您的应用相同的权限。 Android 本机代码支持套接字。

我能想到的第二个选项是为 avrdude 提供一个 JNI 接口,以通过 Java 读/写 USB。我认为这会更加困难,因为它可能需要对 avrdude 进行重大更改。

【讨论】:

  • 通常更简洁地使用 unix 域套接字而不是 TCP,并避免需要网络权限,但是可以。至于执行与链接,Linux 级别的权限(例如网络)将与 UID 相同。
  • 感谢您的建议!但是这一切似乎都没有用,因为我已经用纯 java 编写了上传器,所以它似乎以与 avrdude 完全相同的方式实现 stk500,并且它不适用于某些硬件配置(android 设备 + arduino 板)。所以低级(文件访问)似乎是我需要的
  • 我没有想到域套接字,但你可能不得不破解 avrdude 来替换 TCP 套接字。
  • 您能否详细说明您在 avrdude 的 Java 实现中遇到的问题类型?您是否确认这些 Android 设备支持 USB Host 模式?
  • 我已经实现了 stk500 用于上传,并且非常适合我的硬件配置(任何 2 个设备和 3 个我的 arduino 板中的任何一个),但对于某些用户来说,引导加载程序不会在 1000 毫秒内回复。我查看了 avrdude 源代码并使用了它的技巧,例如双重 dtr/rts 和三重同步尝试。问题似乎出在 Android USB API 中,所以我只想使用低级 USB 访问
【解决方案2】:

关于文件描述符,您可以使用 JNI 将其传递给本机。

//java

私有原生 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);

【讨论】:

  • 最好使用javah 实用程序生成标头以避免错误
猜你喜欢
  • 2012-06-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-03-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多