如何优雅的实现Android Ethernet 以太网的开启与关闭

815次阅读
没有评论

背景
最近产品提了一个网络管理的需求,其中要求有以太网的开启/关闭功能。这里总结一下整个开发过程中遇到的坑。

EthernetManager 不可用
在 android.net 包下面其实有一个 EthernetManager 类负责以太网的管理,然而这个 Api 并没有对我们开放使用,官方标记为隐藏。自然这种方法是不适用的,遂弃之。

/**

  • A class representing the IP configuration of the Ethernet network.
    *
  • @hide
    */
    @SystemService(Context.ETHERNET_SERVICE)
    public class EthernetManager {
    }

    使用 Shell
    本文讲解的实现方法按是使用 shell 命令来控制以太网的开启与关闭。在介绍重要代码前,先介绍下在adb shell中我们可能使用到的命令,如下。

打开/关闭以太网
netcfg eth0 down/up

判断以太网网线插拔状态,1 为插上,0 为拔掉。
cat /sys/class/net/eth0/carrier

获取指定网卡的信息
getprop dhcp.eth0.mask // eth0 的子网掩码
getprop dhcp.eth0.gateway // eth0 的网关

打开/关闭 wifi
svc wifi enable/disable

Note: 上述命令中,eth0 是我设备上的以太网卡名称,不同设备的以太网卡名称可能不一样。也可能有多块网卡,具体以你自己的为准。

运行 Shell 命令,控制以太网的开/关
Note: 有些 shell 命令是需要 root 权限的,如果你的 android 设备已经 root 了,那么可以发送如 netcfg eth0 down/up 等需要 root 权限的命令,但是如果没有 root 。那么你只能执行一些不需要 root 权限的命令了,如 getprop dhcp.eth0.mask 可以获取 eht0 的子网掩码。 所以这种方法来开启/关闭以太网的一个前提是:你的设备已经root了。否则在你发送需要root权限的命令时,通过断点,你会得到如下的一个异常信息:

java.io.IOException Error running exec().Command: [su] Working Directory: null Environment: null

这里以 netcfg eth0 up 为例,介绍开启以太网的实现过程,其他命令都是类似的,区别在于有的命令有结果返回,而有的没有。

在 build.gradle 添加如下依赖,这个依赖包中有很多 Android 常用的工具类,很好用。
implementation ‘com.blankj:utilcode:1.25.9’

使用依赖包中的 ShellUtils 发送如下命令,这样就执行了以太网的开启命令。和在adb shell中执行netcfg eth0 up的效果是一样的
ShellUtils.execCmd(“netcfg eth0 up”,true)

下面是在adb shell 中执行该命令的结果,实际设备也确实开启了以太网

已连接 Wifi 的子网掩码为 0.0.0.0 ?
上一小节已经介绍完了获取以太网信息的操作步骤。那么我觉得可以讲一讲这个坑了,其实这个坑是 Android 一直以来存在的,直到现在官方还没有很好地解决,这个问题的链接如下:
netmask of WifiManager.getDhcpInfo() is always zero on Android 5.0

在 StackOverflow 上也有该问题的讨论:
Find netMask on Android device

总结一下就是通过 WifiManager 拿到 DhcpInfo 后获取到的 Wifi 子网掩码为 0,显然不对。

那么如何解决呢?好家伙,不用想也知道用 Shell 了吧。

一行代码搞定

ShellUtils.execCmd(“getprop dhcp.wlan0.mask”,false).successMsg

再次提醒一下,我的设备的无线网卡名叫wlan0,具体以你的设备为准。

总结
前方请注意,这只是一个踩坑记录,没有什么高大上的知识点。你可能需要踩的坑,我这里都帮你踩完了。如果你有更好的实现方法,非常欢迎你与我交流。

参考文档
Android中常用的adb shell命令
Android Debug Bridge (adb)
Android常用命令
How can i enable/disable the Ethernet connection on Android?

正文完
可以使用微信扫码关注公众号(ID:xzluomor)
post-qrcode
 
评论(没有评论)