如何在 android studio 中监听来自 shell 命令的响应?

How do I listen for a response from shell command in android studio?

在 android 终端仿真器中,我可以键入以下命令:

> su
> echo $(</sys/class/power_supply/battery/charge_rate)

并且根据 phone 的充电方式,输出将是 "None"、"Normal" 或 "Turbo"。我希望能够检索此输出并将其 作为字符串值 存储在我的程序中。

所以我对此做了一些研究,我想出的代码如下:

    String chargeRate = "None";
    try {
        Runtime rt = Runtime.getRuntime();
        Process process = rt.exec("su \"\"echo $(</sys/class/power_supply/battery/charge_rate)");

        BufferedReader stdInput = new BufferedReader(new InputStreamReader(process.getInputStream()));

        if ((chargeRate = stdInput.readLine()) == null)
            chargeRate = "None";
    }
    catch (Exception e) {
        // TODO
    }

这是从许多不同的答案中摘录的,我不太确定它有什么问题。调试时我无法跨过或越过这一行:

if ((chargeRate = stdInput.readLine()) == null)

一旦调试器到达这一行,它就会说 "The application is running"

UPDATE : 解决方案在 Unable using Runtime.exec() to execute shell command "echo" in Android Java code :

Runtime.getRuntime.exec() doesn't execute a shell command directly, it executes an executable with arguments. "echo" is a builtin shell command. It is actually a part of the argument of the executable sh with the option -c. Commands like ls are actual executables. You can use type echo and type ls command in adb shell to see the difference.

So final code is:

String[] cmdline = { "sh", "-c", "echo $..." }; 
Runtime.getRuntime().exec(cmdline);

cat 也可以从 Runtime.exec() 中执行而无需调用 sh

这个在https://www.javaworld.com/article/2071275/when-runtime-exec---won-t.html?page=2段落Assuming a command is an executable program

中也有分析

Execute shell commands and get output in a TextView中的代码很好,尽管它使用了可直接执行的命令(ls,请参阅上面的更新):

try {
        // Executes the command.
        Process process = Runtime.getRuntime().exec("ls -l");

        // Reads stdout.
        // NOTE: You can write to stdin of the command using
        //       process.getOutputStream().
        BufferedReader reader = new BufferedReader(
                new InputStreamReader(process.getInputStream()));

        int read;
        char[] buffer = new char[4096];
        StringBuffer output = new StringBuffer();
        while ((read = reader.read(buffer)) > 0) {
            output.append(buffer, 0, read);
        }
        reader.close();

        // Waits for the command to finish.
        process.waitFor();

        return output.toString();
    } catch (IOException e) {
        throw new RuntimeException(e);
    } catch (InterruptedException e) {
        throw new RuntimeException(e);
    }