Android 14 Root设备Java应用无法执行Shell命令求助
问题排查与修复步骤
1. 修复命令参数拆分错误
Runtime.getRuntime().exec(String)不会自动拆分命令和参数,直接传入"cat /sdcard/myfile.txt"会被系统当作一个完整的可执行文件名查找,自然找不到对应命令,返回退出码1。必须用字符串数组拆分命令与参数:
// 修改调用逻辑,传入数组形式的命令 public static void testShellCmd() { String[] command = {"cat", "/sdcard/myfile.txt"}; String output = executeCommand(command); } // 同步修改executeCommand方法支持数组参数 public static String executeCommand(String[] command) { try { Process process = Runtime.getRuntime().exec(command); // 后续读取逻辑不变 } catch (IOException | InterruptedException e) { e.printStackTrace(); return "Exception: " + e.getMessage(); } }
2. 读取错误输出定位具体原因
当前代码仅读取标准输出,无法获取命令执行失败的具体错误信息,添加错误输出读取逻辑:
public static String executeCommand(String[] command) { try { Process process = Runtime.getRuntime().exec(command); BufferedReader stdoutReader = new BufferedReader(new InputStreamReader(process.getInputStream())); BufferedReader stderrReader = new BufferedReader(new InputStreamReader(process.getErrorStream())); StringBuilder output = new StringBuilder(); String line; // 读取标准输出 while ((line = stdoutReader.readLine()) != null) { output.append(line).append("\n"); } // 追加错误输出 while ((line = stderrReader.readLine()) != null) { output.append("Error: ").append(line).append("\n"); } int exitCode = process.waitFor(); if (exitCode == 0) { return output.toString(); } else { return "Error executing command. Exit code: " + exitCode + "\nDetails:\n" + output; } } catch (IOException | InterruptedException e) { e.printStackTrace(); return "Exception: " + e.getMessage(); } }
3. 确认权限与Root身份
- 存储权限:Android 14中,APP需申请对应存储权限才能访问外部存储文件,在Manifest中声明并动态申请:
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" android:minSdkVersion="30" /> - Root权限:如果adb shell是以root身份执行命令,APP需通过
su切换到root身份执行:String[] command = {"su", "-c", "cat /sdcard/myfile.txt"}; String output = executeCommand(command);
4. 检查SELinux限制
Android 14强化了SELinux规则,即使设备Root,APP进程的SELinux上下文可能限制文件访问。可临时执行su -c "setenforce 0"关闭SELinux测试,若问题解决,需为APP配置对应SELinux规则,或切换到shell上下文执行命令:
String[] command = {"su", "--context=u:r:shell:s0", "-c", "cat /sdcard/myfile.txt"};
内容的提问来源于stack exchange,提问作者gmmo
相关产品推荐
相关产品推荐

