0

我正在做一个根植于手机的小型概念验证,它依赖于能够读取dumpsys输出。

如果我像这样在运行 Android 11 的(根)手机上调用 dumpsys,使用 adb:

adb shell dumpsys telephony.registry | grep "mCi="

我得到一个很长的打印输出。包含手机信号塔 ID 的行的grep过滤器,但这在这里不应该很重要(这只是一个示例)。现在我试图在一个非常简单的应用程序中执行相同的命令,并记录它的输出,如下所示:

private  fun test() {
       
        try {
            val process = Runtime.getRuntime().exec("su dumpsys telephony.registry | grep \"mCi=\"")
            val bufferedReader = BufferedReader(InputStreamReader(process.inputStream))
            val string = bufferedReader.readText()
            Timber.d("output: $string")
            bufferedReader.close() // do I need this?
        } catch (e: IOException) {
            // handle Exception
        }
    }

我根本没有输出(string长度为0)。如果我用类似这样的简单命令替换我的进程命令:Runtime.getRuntime().exec("echo 'abcde'")输出按预期记录(output: 'abcde')。

我还尝试缩短可能的输出,以防问题通过附加--max-count=1grep 仅输出找到的第一行。同样,它使用 adb 工作,在代码中不起作用。

我究竟做错了什么?

(如果有人不知道示例中的那一行是什么,我正在使用Timber打印我的日志。)

4

1 回答 1

0

您应该做的第一件事是记录stderr可用于您的进程的流。这将为您提供有关您的命令有什么问题的信息。

您的命令未正确处理,因为它被视为一个命令。这个答案解释了原因。

解决方案是使用 aString[]作为参数exec并使用 shell 显式执行命令。我写了一些代码来执行你的命令,但它是在一个无根设备上的 Java 中。尽管如此,它仍然会生成输出并且 grep 可以工作。

            String[] arrayCommand = {"sh", "-c","dumpsys telephony.registry | grep \"permission\""};
            
            Runtime r = Runtime.getRuntime();
            Process process = r.exec(arrayCommand);

            String stdoutString = convertInputStreamToString(process.getInputStream());
            String stderrString = convertInputStreamToString(process.getErrorStream());

于 2021-11-21T22:43:19.367 回答