运行 Android shell 命令来自 Java 代码 returns 空输出

Running Android shell command from Java code returns empty output

我正在尝试从我的 Java 代码中执行 运行 shell 命令(netstat -an -ptcat /proc/net/tcp)以检查打开的 TCP 端口Android 设备。该设备是non-rooted(在root设备上,这没有问题)。

我发现有 2 种类型可以从 Java 代码调用 shell 命令。

要获取进程 object 我尝试使用:

  1. Runtime.getRuntime().exec(command);

  2. new ProcessBuilder().command("sh", "-c", command).start();

稍后,我将获取进程 InputStream object 并输出结果。

问题是 cat /proc/net/tcp 命令的结果是空字符串,而 netstat -an -pt 的结果是:

Active Internet connections (w/o servers) Proto Recv-Q Send-Q Local Address           Foreign Address         State       Active UNIX domain sockets (w/o servers) Proto RefCnt Flags    Type       State       I-Node Path

...这是 netstat 命令的 header。

当 运行 直接在 Android shell 中执行上述命令时(通过在 non-rooted 设备中打开 adb shell)一切正常,命令输出显示在控制台中。

我怀疑权限有问题,因为这适用于 root 设备。

Logcat 当 运行 执行以下命令之一时的输出:

 W cat     : type=1400 audit(0.0:3***4): avc: denied { read } for name="tcp" dev="proc" ino=4*2653***6 scontext=u:r:untrusted_app:s*:c**9,c**7,c5**,c*6* tcontext=u:object_r:proc_net_tcp_udp:s0 tclass=file permissive=0

如果这是权限问题,是否有另一种方法可以使用我的应用程序读取 non-rooted Android 设备上当前打开的 TCP 端口?

我部分找到了足够的答案。基本上问题出在首先怀疑的权限上。

如前所述in documentation:来自Android版本10 /proc/net的文件系统受到限制,无法访问。不幸的是(或者我应该说幸运)我的非 root 测试设备是 Android 10,因此进程对象将返回状态 1,因为它没有读取 /proc/net 文件系统的权限。

我在 Android 8 上测试了相同的代码,一切都按预期工作。

我仍然没有弄清楚如何访问已用端口,但我会研究 NetworkStatsManager and ConnectivityManager 类,如先前链接的文档中所述。