Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/149.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android:无法在JNI实现中打开设备文件_Android_C++_Android Ndk_Java Native Interface_Android Framework - Fatal编程技术网

Android:无法在JNI实现中打开设备文件

Android:无法在JNI实现中打开设备文件,android,c++,android-ndk,java-native-interface,android-framework,Android,C++,Android Ndk,Java Native Interface,Android Framework,我已经采取代码极光的调频广播代码,并与我的Android姜饼代码库合并 FM应用程序框架尝试使用JNI访问FM无线电设备(/dev/radio),JNI在名为android_hardware_FM.cpp的文件中实现。此文件中有一个函数,它尝试在读/写模式下使用open()获取设备节点的文件描述符。但是,调用失败,错误代码为-13:权限被拒绝 我还制作了一个小的C可执行文件,它尝试打开/dev/radio文件(在RDWR模式下),打印它的fd并关闭它。它从目标系统中的/system/bin运行,

我已经采取代码极光的调频广播代码,并与我的Android姜饼代码库合并

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

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

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


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

很明显,您没有从用户空间打开设备的权限。在第二种情况下,当您从终端运行可执行文件时,您拥有权限,这可能是因为您在运行可执行文件之前执行了
su

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

1)从terimnal更改节点的权限

涉及的步骤:

  • 打开终端(
    adb外壳

  • 执行
    su
    (要执行此操作,您的设备必须根目录)

  • 在终端中执行
    chmod 777/dev/radio

完成此操作后,您的无线节点将拥有用户读写的适当权限。因此,您现在可以执行
open()
调用,它将正常工作

2)通过调用下面的函数-
changePerm()
,您可以通过编程实现这一点(假设您的设备是根设备并且su正在设备上运行)。这是我编写的一个小函数,它将更改设备节点或任何没有用户访问权限的系统文件的权限。拥有权限后,可以从用户空间打开它。在此之后,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();
}
}

我已经对其他节点进行了测试。因此,它也应该适用于无线电。如果你遇到任何困难,请告诉我。谢谢

很明显,您没有从用户空间打开设备的权限。在第二种情况下,当您从终端运行可执行文件时,您拥有权限,这可能是因为您在运行可执行文件之前执行了
su

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

1)从terimnal更改节点的权限

涉及的步骤:

  • 打开终端(
    adb外壳

  • 执行
    su
    (要执行此操作,您的设备必须根目录)

  • 在终端中执行
    chmod 777/dev/radio

完成此操作后,您的无线节点将拥有用户读写的适当权限。因此,您现在可以执行
open()
调用,它将正常工作

2)通过调用下面的函数-
changePerm()
,您可以通过编程实现这一点(假设您的设备是根设备并且su正在设备上运行)。这是我编写的一个小函数,它将更改设备节点或任何没有用户访问权限的系统文件的权限。拥有权限后,可以从用户空间打开它。在此之后,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();
}
}

我已经对其他节点进行了测试。因此,它也应该适用于无线电。如果你遇到任何困难,请告诉我。谢谢

一个使用adb shell的用户拥有我的默认root权限。你建议我在init.rc中添加命令“chmod 777/dev/radio0”,但这只是一个临时修复。要使init.rc中的更改生效,你需要重新编译android和falash itOh。在这种情况下,如果默认情况下你拥有root权限,你的设备上可能不存在su。那么只有使用adb shell的第1种方法(不适用su)具有根权限(默认情况下)。你建议我在init.rc中添加命令“chmod 777/dev/radio0”,但这只是一个临时修复。要使init.rc中的更改生效,你需要重新编译android和falash itOh。在这种情况下,如果默认情况下你拥有root权限,你的设备上可能不存在su。4年后,只有第1种方法(不适用su)我遇到了一个非常类似的问题:我甚至以与应用程序相同的UID运行了我的可执行文件,并且它可以工作,当然,我做了下面答案中的所有事情。你找到解决办法了吗?@jkoreska我想我用了一个变通方法。在下面的答案中看到我的评论。4年后,我遇到了一个非常类似的问题:我甚至以与应用程序相同的UID运行我的可执行文件,并且它可以工作,当然,我做了下面答案中的所有事情。你找到解决办法了吗?@jkoreska我想我用了一个变通方法。请参阅下面答案中的我的评论。