Android设置WIFI静态IP

1,782 阅读1分钟

想要在代码中实现设置 WIFI 静态 IP 需要有系统权限,要在 manifest 文件添加 android:sharedUserId=“android.uid.system”,还要有系统签名。
设置 WIFI 静态 IP 和之前以太网的类似,都是要构造 StaticIpConfiguration 对象,以及 IpConfiguration.IpAssignment.STATIC 就代表设置为静态 IP,也可以设置 DHCP(自动获取),不过 WifiConfiguration 可以直接通过 WifiManager 获取到,比设置以太网的要简单一些,不用反射来获取对象。

将 IP,NETMASK,GATEWAY 和 DNS 设置进去,构造 StaticIpConfiguration 对象,下边是代码:

try {
    Inet4Address inetAddr = getIPv4Address(STATIC_IP);
    int prefixLength = NetUtils.maskStr2InetMask(STATIC_NETMASK);
    InetAddress gatewayAddr = getIPv4Address(STATIC_GATEWAY);
    InetAddress dnsAddr = getIPv4Address(STATIC_DNS1);

    Class[] cl = new Class[]{InetAddress.class, int.class};
    Constructor cons = null;

    Class<?> clazz = Class.forName("android.net.LinkAddress");

    //取得所有构造函数
    try {
        cons = clazz.getConstructor(cl);
    } catch (NoSuchMethodException e) {
        e.printStackTrace();
    }

    if (cons == null) {
        return;
    }
    //给传入参数赋初值
    Object[] x = {inetAddr, prefixLength};

    //构造StaticIpConfiguration对象
    Class<?> staticIpConfigurationCls = Class.forName("android.net.StaticIpConfiguration");
    //实例化StaticIpConfiguration
    Object staticIpConfiguration = null;

    staticIpConfiguration = staticIpConfigurationCls.newInstance();
    Field ipAddress = staticIpConfigurationCls.getField("ipAddress");
    Field gateway = staticIpConfigurationCls.getField("gateway");
    Field dnsServers = staticIpConfigurationCls.getField("dnsServers");
    //设置ipAddress
    ipAddress.set(staticIpConfiguration, (LinkAddress) cons.newInstance(x));
    //设置网关
    gateway.set(staticIpConfiguration, gatewayAddr);
    //设置dns
    ArrayList<InetAddress> dnsList = (ArrayList<InetAddress>) dnsServers.get(staticIpConfiguration);
    dnsList.add(dnsAddr);
    if (!STATIC_DNS2.isEmpty()) {
        dnsList.add(getIPv4Address(STATIC_DNS2));
    }

    WifiManager wifiManager = (WifiManager) getApplicationContext().getSystemService(WIFI_SERVICE);
    WifiConfiguration wifiConfig = null;
    WifiInfo connectionInfo = wifiManager.getConnectionInfo();  //得到连接的wifi网络

    @SuppressLint("MissingPermission")
    List<WifiConfiguration> configuredNetworks = wifiManager.getConfiguredNetworks();
    for (WifiConfiguration conf : configuredNetworks) {
        if (conf.networkId == connectionInfo.getNetworkId()) {
            wifiConfig = conf;
            break;
        }
    }

    @SuppressLint("PrivateApi") Class ipAssignmentCls = Class.forName("android.net.IpConfiguration$IpAssignment");
    Object ipAssignment = Enum.valueOf(ipAssignmentCls, "STATIC");
    Method setIpAssignmentMethod = wifiConfig.getClass().getDeclaredMethod("setIpAssignment", ipAssignmentCls);
    setIpAssignmentMethod.invoke(wifiConfig, ipAssignment);
    Method setStaticIpConfigurationMethod = wifiConfig.getClass().getDeclaredMethod("setStaticIpConfiguration", staticIpConfiguration.getClass());
    //设置静态IP,将StaticIpConfiguration设置给WifiConfiguration
    setStaticIpConfigurationMethod.invoke(wifiConfig, staticIpConfiguration);
    //WifiConfiguration重新添加到WifiManager 
    int netId = wifiManager.addNetwork(wifiConfig);
    wifiManager.disableNetwork(netId);
    boolean flag = wifiManager.enableNetwork(netId, true);
} catch (NoSuchFieldException | IllegalAccessException | InstantiationException | InvocationTargetException | ClassNotFoundException | NoSuchMethodException e) {
    e.printStackTrace();
}

通过 WifiConfiguration 的 setStaticIpConfiguration 方法将 StaticIpConfiguration 对象设置进去,通过 setIpAssignment,将 IpAssignment 设置进去,值设为 STATIC,最后根据 netId 重启这个网络,即可将静态 IP 设置成功。