问题描述
我正在尝试从Java代码运行shell命令(netstat -an -pt
,cat /proc/net/tcp
),以便检查Android设备上是否打开了TCP端口。该设备是非root用户的(在root用户的设备上,这没有问题)。
我发现有两种类型可以从Java代码调用Shell命令。
要获取我尝试使用的过程对象:
-
Runtime.getRuntime().exec(command);
-
new ProcessBuilder().command("sh","-c",command).start();
稍后,我正在处理InputStream对象并输出结果。
问题是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
命令的标题。
直接在Android Shell中运行上述命令时(通过在无根设备中打开adb shell
),一切正常,并且命令的输出显示在控制台中。
我怀疑权限存在一些问题,因为这在有根设备上有效。
运行以下命令之一时的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
如果这是权限问题,是否还有另一种方法可以通过我的应用程序读取非root用户的Android设备上当前打开的TCP端口?
解决方法
我部分找到了足够的答案。基本上,问题首先在于权限。
如in documentation所述:从Android版本10 /proc/net
开始,文件系统受到限制,无法访问。不幸的是(我应该说幸运的)我的无根测试设备是Android 10,因此进程对象将返回状态1,因为它没有读取/proc/net
文件系统的权限。
我在Android 8上测试了相同的代码,并且一切正常。
我仍然没有弄清楚如何访问使用的端口,但是我将研究先前链接的文档中提到的NetworkStatsManager和ConnectivityManager类。