1

我采用了 Code Aurora 的 FM Radio 代码并与我的 Android Gingerbread 代码库合并。

FM 应用程序框架尝试使用 JNI 访问 fm 无线电设备 ( /dev/radio ),该 JNI 在名为 android_hardware_fm.cpp 的文件中实现。该文件中有一个函数尝试在读/写模式下使用 open() 获取设备节点的文件描述符。但是,调用失败并出现错误代码 -13 : Permission denied。

我还制作了一个小的 C 可执行文件,它试图打开 /dev/radio 文件(在 RDWR 模式下),打印它的 fd 并关闭它。它从目标系统中的 /system/bin 运行并显示有效的 fd。

顺便说一句,JNI 实现是 android 核心库的一部分。它位于 frameworks/base/core/jni 并作为 libandroid_runtime.so 的一部分编译

有什么想法/解决方案吗?提前致谢。

4

1 回答 1

1

显然,您无权从用户空间打开设备。在第二种情况下,当您从终端运行可执行文件时,您可能拥有权限,因为您su在运行可执行文件之前已经完成。

对于您的问题,可以做两件事。

1)从终端更改节点的权限。

涉及的步骤:

  • 打开终端 ( adb shell)

  • su(为了做到这一点,您的设备必须植根)

  • chmod 777 /dev/radio在终端做

完成此操作后,您的无线电节点将拥有适当的权限供用户读写。所以你现在可以open()打电话了,它会起作用的。

2)您可以通过调用以下函数以编程方式实现此目的(假设您的设备已植根并且 su 正在您的设备上运行) - changePerm()。这是我编写的一个小函数,它将更改设备节点的权限,或者更确切地说是任何没有用户访问权限的系统文件。获得权限后,您可以从用户空间打开它。open() 调用将在此之后正常工作。

void changePerm()
{
    Process chperm;
    try {
        chperm=Runtime.getRuntime().exec("su");


   DataOutputStream os = 
          new DataOutputStream(chperm.getOutputStream());
        os.writeBytes("chmod 777 /dev/radio\n");
        os.flush();

        os.writeBytes("exit\n");
        os.flush();

          chperm.waitFor();

} catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
} catch (InterruptedException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
}
}

我已经对其他节点进行了测试。所以它也应该适用于广播。如果您遇到任何困难,请告诉我。谢谢

于 2012-05-08T04:44:06.160 回答