Android:无法在JNI实现中打开设备文件
我已经采取代码极光的调频广播代码,并与我的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的一部分进行编译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运行,
有什么想法/解决方案吗?提前感谢。很明显,您没有从用户空间打开设备的权限。在第二种情况下,当您从终端运行可执行文件时,您拥有权限,这可能是因为您在运行可执行文件之前执行了
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我想我用了一个变通方法。请参阅下面答案中的我的评论。