Android端运行C/C++/Java代码出现error=13权限错误如何解决?
问题分析与解决方案
你遇到的error=13 permission denied错误和代码逻辑问题可以从以下维度定位和修改:
现有问题说明
- 权限规则问题:安卓10及以上系统默认禁止对外置公共存储的文件授予可执行权限,也不允许执行公共存储路径下的可执行文件。如果你当前的
path指向的是外置公共存储,本身就不符合系统权限要求,必然会触发权限拒绝错误。 - 代码逻辑错误:你把
p.waitFor()放在了读取输出的while循环内部,只会读取一行输出就会阻塞等待进程结束,若进程输出内容超过1行,会直接卡住,甚至因为输出缓冲区占满导致进程僵死。 - 缺少权限授予步骤:就算路径符合系统要求,你也没有主动给目标执行文件添加可执行权限,没有执行权限的文件运行时也会抛出13错误。
- 缺少错误流读取逻辑:你只读取了进程的标准输出流,没有读取错误流,进程运行时的报错信息会输出到错误流,缓冲区满后会直接阻塞进程运行。
具体修改方案
1. 调整存储路径
把编译生成的可执行文件放到应用内部私有目录下,只有该目录下的文件可以被授予可执行权限,获取内部私有目录的方式为getFilesDir()。
2. 完整修改后代码
try { // 改用应用内部私有目录下的可执行文件 File execFile = new File(getFilesDir(), "/PocketIDE/JavaPrograms/"+ filename); // 先校验文件是否存在 if (!execFile.exists()) { output.setText("目标程序文件不存在"); return; } // 主动授予可执行权限 execFile.setExecutable(true); // 执行程序 p = Runtime.getRuntime().exec(execFile.getAbsolutePath()); // 分别读取标准输出流和错误流 BufferedReader stdReader = new BufferedReader(new InputStreamReader(p.getInputStream())); BufferedReader errReader = new BufferedReader(new InputStreamReader(p.getErrorStream())); StringBuilder output2 = new StringBuilder(); String line; // 读取标准输出 while ((line = stdReader.readLine()) != null) { output2.append(line).append("\n"); } // 读取错误输出 while ((line = errReader.readLine()) != null) { output2.append("[错误]").append(line).append("\n"); } // 所有流读取完成后再等待进程结束 int exitCode = p.waitFor(); output2.append("程序执行完成,退出码:").append(exitCode); output.setText(output2.toString()); // 关闭流资源 stdReader.close(); errReader.close(); } catch (IOException | InterruptedException e) { output.setText(e.toString()); e.printStackTrace(); }
3. 额外适配说明
如果需要兼容安卓10以下版本且需要读写外置存储,需要在AndroidManifest.xml中声明WRITE_EXTERNAL_STORAGE、READ_EXTERNAL_STORAGE权限,安卓6.0及以上版本还需要动态申请存储权限。
内容的提问来源于stack exchange,提问作者Sahil
相关产品推荐
相关产品推荐

