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

Android调用ip neigh show命令进程返回退出码1且InputStreamReader无输出

问题原因

  1. 权限差异:你在adb shell下执行命令时,身份是高权限的shell用户,而App运行时是普通第三方应用的独立UID,权限等级完全不同。从Android 10(API 29)开始,系统严格限制普通应用读取ARP缓存表的权限,ip neigh show命令正好需要该权限,所以执行时返回退出码1,无正常输出。
  2. 未读取错误流:你当前只读取了进程的inputStream(正常输出流),命令执行的报错信息全部在errorStream中,所以看不到具体报错原因。
  3. 命令解析坑:直接向Runtime.exec()传入带空格的整串命令,部分场景下系统会解析错误,更稳妥的方式是用字符串数组拆分命令和参数。

解决方案

第一步:添加并动态申请必要权限

在AndroidManifest.xml中添加权限声明:

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

注意:定位权限属于Android危险权限,需要在代码中动态申请,用户同意后才能生效。

第二步:调整代码逻辑,增加错误流读取

修改后的执行代码示例:

// 用数组拆分命令和参数,避免解析错误
val p = Runtime.getRuntime().exec(arrayOf("/system/bin/ip", "neigh", "show"))
// 先读取错误流排查问题
val errorInfo = InputStreamReader(p.errorStream).buffered().readText()
Log.d("IP_CMD_ERROR", errorInfo)
// 读取正常输出
InputStreamReader(p.inputStream).buffered().forEachLine fori@{ line ->
    val teDhenat = line.split("\\s+".toRegex())
    if (teDhenat[0] == ip) {
        if (teDhenat.size < 4) {
            return@fori
        } else {
            uGjet = true
            macAddress = teDhenat[4]
            return@fori
        }
    }
}
// 等待进程执行完毕,确认退出码
val exitCode = p.waitFor()
Log.d("IP_CMD", "执行完毕,退出码:$exitCode")

你可以通过打印的errorInfo确认具体报错原因,90%以上的概率是权限不足的提示。

替代方案(适配高版本系统限制)

如果申请权限后依旧无法执行,说明你测试的ROM对ip命令做了额外限制,可改为直接读取ARP缓存文件实现相同需求:

try {
    BufferedReader(FileReader("/proc/net/arp")).use { reader ->
        var line: String?
        // 跳过表头第一行
        reader.readLine()
        while (reader.readLine().also { line = it } != null) {
            val split = line?.split("\\s+".toRegex()) ?: continue
            if (split.size < 4) continue
            val currentIp = split[0]
            val currentMac = split[3]
            if (currentIp == ip) {
                uGjet = true
                macAddress = currentMac
                break
            }
        }
    }
} catch (e: Exception) {
    e.printStackTrace()
}

如果连/proc/net/arp也无法读取,那就是Android 11+的强制权限限制,普通第三方应用无法绕过,需要使用系统级API实现对应需求。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.23 15:54:06