背景

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

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中我们可能使用到的命令,如下。

  1. 打开/关闭以太网
netcfg eth0 down/up
  1. 判断以太网网线插拔状态,1 为插上,0 为拔掉。
cat /sys/class/net/eth0/carrier
  1. 获取指定网卡的信息
getprop dhcp.eth0.mask // eth0 的子网掩码
getprop dhcp.eth0.gateway // eth0 的网关
  1. 打开/关闭 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 为例,介绍开启以太网的实现过程,其他命令都是类似的,区别在于有的命令有结果返回,而有的没有。

  1. build.gradle 添加如下依赖,这个依赖包中有很多 Android 常用的工具类,很好用。
implementation 'com.blankj:utilcode:1.25.9'
  1. 使用依赖包中的 ShellUtils 发送如下命令,这样就执行了以太网的开启命令。和在adb shell中执行netcfg eth0 up的效果是一样的
ShellUtils.execCmd("netcfg eth0 up",true)

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

Android以太网设置 安卓以太网自动关闭_android

已连接 Wifi 的子网掩码为 0.0.0.0 ?

上一小节已经介绍完了获取以太网信息的操作步骤。那么我觉得可以讲一讲这个坑了,其实这个坑是 Android 一直以来存在的,直到现在官方还没有很好地解决,

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

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

Android以太网设置 安卓以太网自动关闭_Android以太网设置_02

一行代码搞定

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

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

总结

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