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

Android root设备调用Runtime.exec执行dumpsys命令无输出如何解决

问题根因

  • Runtime.getRuntime().exec() 本身不支持解析shell语法,包括管道符|、引号转义、重定向等逻辑,你传入的带管道的完整命令会被当成su的单一参数执行,系统无法识别该指令,自然没有输出。你之前执行echo能成功是因为这是无特殊语法的单一命令,不需要shell参与解析。
  • 你没有等待进程执行完成就直接读取输入流,可能进程还未完成输出就读取结束,导致拿到空字符串。同时你没有读取进程的错误流,无法捕获执行过程中的报错信息,很难排查问题。
  • 部分root环境下直接把完整命令拼在su后的调用方式本身不兼容,需要显式启动root shell再执行命令。

正确实现方案

先启动root权限的shell进程,再把需要执行的命令写入shell的输入流执行,示例代码如下:

private fun test() {
    try {
        // 启动root权限的shell
        val process = Runtime.getRuntime().exec("su")
        val outputStream = DataOutputStream(process.outputStream)
        // 写入要执行的命令,加\n表示触发执行,最后加exit表示执行完退出shell
        outputStream.writeBytes("dumpsys telephony.registry | grep \"mCi=\"\n")
        outputStream.writeBytes("exit\n")
        outputStream.flush()

        // 等待进程执行完成,确认执行结果
        val exitCode = process.waitFor()
        if (exitCode == 0) {
            // 读取正常输出
            BufferedReader(InputStreamReader(process.inputStream)).use { reader ->
                val result = reader.readText()
                Timber.d("output: $result")
            }
        } else {
            // 读取错误信息排查问题
            BufferedReader(InputStreamReader(process.errorStream)).use { reader ->
                val errorMsg = reader.readText()
                Timber.d("执行错误: $errorMsg")
            }
        }
        outputStream.close()
        process.destroy()
    } catch (e: Exception) {
        e.printStackTrace()
    }
}

补充说明

  • 关于你问的流关闭问题:所有IO流使用完必须主动关闭避免资源泄漏,上面代码里用了Kotlin的use扩展方法,会在执行结束后自动关闭流,不需要手动写close逻辑。
  • 如果想要简化写法,也可以尝试使用su -c参数:Runtime.getRuntime().exec("su -c \"dumpsys telephony.registry | grep 'mCi='\""),但这种写法在不同的su实现(Magisk、SuperSU等)上兼容性不一致,更推荐上面显式写入命令的方案。
  • 要提前确认你已经给当前应用授予了root权限,部分root管理工具默认会拦截应用的root申请。

内容的提问来源于stack exchange,提问作者michpohl

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 22:45:03