You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 10:52:09