14

我正在开发一个通过 jni 使用 libusb 的应用程序。此应用程序目前仅针对有根、USB 主机的 Android 3+ 机器。

场景如下:

<java Activity>
       loads <jni_wrapper.so>
               which wraps <my_main_lib.so>
                       that uses <libusb.so>
                               that needs rw access to: /dev/bus/usb/<device>

所有 .so 本机库都是我在 /system/lib 上安装(以 root 身份)的基础架构的一部分,然后可由简单用户运行的 java 活动使用。

这意味着整个 USB 通信必须从本机端完成。

我得到了一切正常工作,除了一个问题 - USB 权限:/dev/bus/usb/ 条目的默认权限是(0660,uid=root,gid=usb)。

显然,运行本机代码的标准 java 进程不满足上述任何要求,迫使我“chmod 666”相应的 /dev 条目,以使其正常工作。

但是,此解决方案不是很好,因为它无法在重新启动或拔出/重新插入设备后继续存在(权限返回 0660)。

我正在寻找的解决方案需要:

  • 在重新启动/重新插入后幸存
  • 由root安装~一次~,而不是每次都打扰用户获得权限
  • 通用并在所有(/大多数)android 3+机器上运行
  • [非强制性] 提供必要的最少凭据

我想到的方向:

  • 更改 /init.rc 或 /ueventd.rc 中的权限 --> 每次重新启动时都会覆盖两者
  • 使用 devmode=0666 安装 usbfs /proc/bus/usb --> 可以重新插入,但不能重新启动
  • 让我的进程加入“usb”组?--> 我尝试了 android.permission.ACCESS_USB,但它不起作用/不支持...:/

有任何想法吗?:-)

谢谢!

4

4 回答 4

2

libusb 开发团队有一些方法。就我而言,我选择第一种方法。

来自:https ://github.com/libusb/libusb/blob/master/android/README

运行时权限:

大多数 Android 设备上的默认系统配置不允许访问 USB 设备。有几个选项可以改变这一点。

如果你有系统镜像的控制权那么你可以修改镜像中使用的ueventd.rc来改变/dev/bus/usb//的权限。如果使用这种方法,那么建议创建一个新的 Android 权限来保护对这些文件的访问。不建议为所有应用程序授予对这些文件的读写权限。

对于 root 设备,使用 libusb 的代码可以使用“su”命令以 root 身份执行。另一种方法是使用“su”命令更改相应 /dev/bus/usb/ 文件的权限。

用户反馈使用 android.hardware.usb.UsbManager 请求使用 UsbDevice 的权限,然后打开设备成功。这种方法的难点在于不能保证它会在未来的 Android 版本中继续工作,它需要调用 Java API 并运行代码来匹配每个 android.hardware.usb.UsbDevice 到一个 libusb_device。

于 2015-02-11T15:47:49.067 回答
2

我有同样的问题,我在 ndk 中解决了这个问题,将 /proc/bus/usb 更改为你的情况下安装 usb 的位置。希望能帮助到你。

r = system("su -c \"chmod -R 777 /proc/bus/usb/\"");
if(r!=0) {
    LOGD("Could not grant permissions to USB\n");
    eturn CANT_GRAN_PERMISSION_USB;
}
于 2011-10-28T12:52:20.683 回答
1

编辑:

重新阅读问题后,很明显我误解了主机运行的是Android。由于 udev 在 Android 中不存在,因此下面的答案不能回答问题。如果有人正在寻找有关让非 Android linux 主机 PC 识别 Android 设备的信息,我将在这里留下这个答案。

结束编辑

这些驱动程序 (/dev/bus/usb/###/###) 的默认权限由 udev 确定。特别是,它会按数字顺序解析 /etc/udev/rules.d 和 /lib/udev/rules.d 中的配置文件以确定默认值。

要覆盖默认值,您需要创建自己的 udev .rules 文件。为此,您需要要授予权限的设备的供应商 ID。lsusb 将打印出任何特定设备的设备 ID,如果你想要所有供应商的列表,你可以试试这个

因此,在您的 /etc/udev/rules.d/99-android.rules 文件中,为您要支持的每个供应商填写以下行:

SUBSYSTEM=="usb", ATTRS{idVendor}=="04e8", MODE:="0666"

请注意,在上面链接的示例中,他们使用 = 而不是 := 和 SYSFS 而不是 ATTRS。我不知道为什么,但我发现该文件在我的机器上无法逐字运行。

写入文件后,

restart usbserial 

并重新插入您的设备。它现在应该默认为 666 权限。

于 2011-12-06T23:13:15.113 回答
1

我找到了解决方案而无需植根设备。

在 Android 4.2.2 内核版本 3.3.39 上测试

您需要做的就是将您的应用程序添加到“usb”组中

如果没有 root,您可以使用 /system/etc/permissions/platform.xml 中的权限文件

选择一项您不使用的权限,例如“android.permission.CAMERA”。

像这样修改/system/etc/permissions/platform.xml:

<permissions>
...
    <permission name="android.permission.CAMERA" >
        <group gid="camera" />
    </permission>

    <permission name="android.permission.CAMERA" >
        <group gid="usb" />
    </permission>
...
</permissions>

因此,添加<uses-permission android:name="android.permission.CAMERA" />到您的应用程序清单文件,并享受 libusb 可访问的 USB!

于 2014-06-04T08:44:19.553 回答