Android 有线网络静态属性配置

Android 系统有线网络静态属性配置

本篇主要涉及Android 7【SDK 25】以上系统应用,设置有线网络的静态IP、子网掩码、网关等属性设置;

有线网络提供了管理类EthernetManager,获取开关状态、获取有线网络信息、设置动态IP 静态IP 子网掩码 网关Ip获取都通过它,在标准的Android接口中,EthernetManager是隐藏的,所以在Framework没有放开的情况下,只能通过Java反射的形式进行调用,下面就先了解相关的API和方法。

注意:反射EthernetManager的前提是你的应用是系统级应用,否则反射的时候会报缺少权限,即使在AndroidManifest.xml清单里面配了也无济于事

1、介绍framework层网络配置相关类

typescript 复制代码
package android.net;
​
​
@SystemService(Context.CONNECTIVITY_SERVICE)
public class ConnectivityManager {
    
    /**
     * Create a new EthernetManager instance.
     * Applications will almost always want to use
     * {@link android.content.Context#getSystemService Context.getSystemService()} to retrieve
     * the standard {@link android.content.Context#ETHERNET_SERVICE Context.ETHERNET_SERVICE}.
     */
    public EthernetManager(Context context, IEthernetManager service) {
        mContext = context;
        mService = service;
    }
    /*
     *  阅读framework源码,我们发现ConnectivityManager的构造函数,需要两个参数
     * 最重要一个是IEthernetManager,是一个系统服务,那么说明在Android SDK里面,肯定会有个service Tag可以直接可以获得EthernetManager
    */
    
        /**
     * Get Ethernet configuration.
     * @return the Ethernet Configuration, contained in {@link IpConfiguration}.
     */
    public IpConfiguration getConfiguration(String iface) {
        try {
            return mService.getConfiguration(iface);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }
    /*
     *  getConfiguration 获取iface网卡的配置
    */
    
​
    /**
     * Set Ethernet configuration.
     */
    public void setConfiguration(String iface, IpConfiguration config) {
        try {
            mService.setConfiguration(iface, config);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }
     /*
     * setConfiguration 设置iface网卡的配置
     * IpConfiguration 一个网卡配置信息的类,也是android.net这个包下面的
    */
}

首先先介绍一下android.net.IpConfiguration 这个类的所有字段的含义

java 复制代码
package android.net;
​
/**
 * A class representing a configured network.
 * @hide
 */
public class IpConfiguration implements Parcelable {
​
    public IpAssignment ipAssignment;
​
    public StaticIpConfiguration staticIpConfiguration;
​
    public ProxySettings proxySettings;
​
    public ProxyInfo httpProxy;
    
/*
ipAssignment:表示 IP 地址分配的方式,可能的取值包括:
​
IpAssignment.DHCP:通过 DHCP 自动分配 IP 地址。
IpAssignment.STATIC:使用静态 IP 地址配置。
IpAssignment.UNASSIGNED:未分配IP,可作为无效值。
​
proxySettings:表示代理服务器设置,可能的取值包括:
​
ProxySettings.NONE:不使用代理。
ProxySettings.STATIC:使用静态代理设置。
ProxySettings.PAC:根据 PAC (Proxy Auto-Config) 文件配置代理。
ProxySettings.UNASSIGNED:未分配代理设置。
​
*/    
}

IpAssignment 设置为静态时STATIC,则需要使用 StaticIpConfiguration 来进行设定 静态IP、掩码、网关和DNS;StaticIpConfiguration也是 android.net这个包下面的类

下面继续看 StaticIpConfiguration这个类的一些字段的含义

java 复制代码
package android.net;
​
import android.net.LinkAddress;
import java.net.InetAddress;
​
​
/**
 * Class that describes static IP configuration.
 *
 * This class is different from LinkProperties because it represents
 * configuration intent. The general contract is that if we can represent
 * a configuration here, then we should be able to configure it on a network.
 * The intent is that it closely match the UI we have for configuring networks.
 *
 * In contrast, LinkProperties represents current state. It is much more
 * expressive. For example, it supports multiple IP addresses, multiple routes,
 * stacked interfaces, and so on. Because LinkProperties is so expressive,
 * using it to represent configuration intent as well as current state causes
 * problems. For example, we could unknowingly save a configuration that we are
 * not in fact capable of applying, or we could save a configuration that the
 * UI cannot display, which has the potential for malicious code to hide
 * hostile or unexpected configuration from the user: see, for example,
 * http://b/12663469 and http://b/16893413 .
 *
 * @hide
 */
public class StaticIpConfiguration implements Parcelable {
    
    public LinkAddress ipAddress;
    public InetAddress gateway;
    public final ArrayList<InetAddress> dnsServers;
    public String domains;
    
    
/*
ipAddress:表示静态 IP 地址。
​
gateway:表示静态 IP 的默认网关。
​
dnsServers:表示静态 IP 配置的 DNS 服务器的 IP 地址列表。
​
domains:表示与静态 IP 配置相关的 DNS 搜索域。
​
*/    
}

2、使用反射调用系统方法设置网络属性

直接上完整调用的代码;

ini 复制代码
/**
     * 设置静态ip、子网掩码、网关
     * @param iFace 网卡名称,如:eth0
     * @param isDhcpMode 是否是DHCP模式
     * @param ip ip 地址 //当前不支持ipv6
     * @param mask 掩码
     * @param gateway 网关
     */
    public static void setStaticIpConfiguration(String iFace,boolean isDhcpMode,String ip,String mask,String gateway){
        try {
            //1| 获得EthernetManager
            Object objEthernetManager = AppGlobal.getApplicationContext().getSystemService("ethernet");
​
            //2| 构造 IpConfiguration的成员 IpAssignment ProxySettings StaticIpConfiguration ProxyInfo
            Class<?> aClass = ReflectHelper.getClass("android.net.NetworkUtils");
            Method numericToInetAddress = aClass.getDeclaredMethod("numericToInetAddress", String.class);
            numericToInetAddress.setAccessible(true);
            Class<?> classStaticIpConfiguration = ReflectHelper.getClass("android.net.StaticIpConfiguration");
            Object objStaticIpConfiguration = null;
            if (!isDhcpMode){
                InetAddress ipV4InetAddress = (InetAddress) numericToInetAddress.invoke(null, ip);
                InetAddress gatewayInetAddress = (InetAddress) numericToInetAddress.invoke(null, gateway);
                objStaticIpConfiguration = classStaticIpConfiguration.newInstance();
                ReflectHelper.setField(objStaticIpConfiguration, "ipAddress", createLinkAddress(ipV4InetAddress, CommonUtils.getNetmaskLength(mask)));
                ReflectHelper.setField(objStaticIpConfiguration, "gateway", gatewayInetAddress);
                OsduiLog.mtuiHintLog(TAG, "setStaticIpConfiguration objStaticIpConfiguration: " + objStaticIpConfiguration);
​
            }
​
            Class<?> classIpConfiguration = ReflectHelper.getClass("android.net.IpConfiguration");
            Class<?> classProxyInfo = ReflectHelper.getClass("android.net.ProxyInfo");
            Class<?> ipAssignment = ReflectHelper.getClass("android.net.IpConfiguration$IpAssignment");
            Class<?> proxySettings = ReflectHelper.getClass("android.net.IpConfiguration$ProxySettings");
​
            Object objIpAssignment = ReflectHelper.getField(ipAssignment, null, isDhcpMode? "DHCP":"STATIC");//设置DHCP模式
            Object objProxySettings = ReflectHelper.getField(proxySettings, null, "NONE");
            //3| 构造出 IpConfiguration
            Constructor<?> declaredConstructor = classIpConfiguration.getDeclaredConstructor(ipAssignment, proxySettings, classStaticIpConfiguration, classProxyInfo);
            Object objIpConfiguration = declaredConstructor.newInstance(objIpAssignment, objProxySettings, objStaticIpConfiguration, null);
            OsduiLog.mtuiHintLog(TAG, "setStaticIpConfiguration objIpConfiguration: " + objIpConfiguration);
​
            //4| 调用 EthernetManager里的setConfiguration方法
            ReflectHelper.invokeMethod(objEthernetManager,"setConfiguration",
                    new Class[]{String.class,classIpConfiguration},new Object[]{iFace,objIpConfiguration});
​
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

这里还涉及了一个 android.net.NetworkUtils,这个系统层直接提供的网络工具类,主要用于一个Int的ip转换成java.net.InetAddress 对象;如果不想用也可以自己构造出来;

这里还涉及了一个InetAddress转成LinkAddress方法,这里一并转换出来

ini 复制代码
private static LinkAddress createLinkAddress(InetAddress ipAddress, int prefixLength) {
        try {
            Class<?> clazz = Class.forName("android.net.LinkAddress");
            Class<?>[] parTypes = new Class<?>[2];
            parTypes[0] = InetAddress.class;
            parTypes[1] = int.class;
            Constructor<?> constructor = clazz.getConstructor(parTypes);
​
            Object[] pars = new Object[2];
            pars[0] = ipAddress;
            pars[1] = prefixLength;
            return (LinkAddress) constructor.newInstance(pars);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

有线网络是通过EthernetManager来设置静态网络属性,而无线网络则不需要这么复杂,但也需要用到StaticIpConfiguration,但本次不进行展开;如有需要请点赞收藏关注支持,后续会继续更新跟网络相关的内容,Android开发;

Ps:点赞关注越多,更新越快;如遇特别难题,可私信或者评论,会及时回复~不过需要您的点赞收藏

至此,以太网络的相关操作介绍完毕。

相关推荐
不爱学习的啊Biao4 分钟前
【13】MySQL如何选择合适的索引?
android·数据库·mysql
Clockwiseee32 分钟前
PHP伪协议总结
android·开发语言·php
mmsx7 小时前
android sqlite 数据库简单封装示例(java)
android·java·数据库
众拾达人10 小时前
Android自动化测试实战 Java篇 主流工具 框架 脚本
android·java·开发语言
吃着火锅x唱着歌11 小时前
PHP7内核剖析 学习笔记 第四章 内存管理(1)
android·笔记·学习
_Shirley12 小时前
鸿蒙设置app更新跳转华为市场
android·华为·kotlin·harmonyos·鸿蒙
hedalei14 小时前
RK3576 Android14编译OTA包提示java.lang.UnsupportedClassVersionError问题
android·android14·rk3576
锋风Fengfeng14 小时前
安卓多渠道apk配置不同签名
android
枫_feng14 小时前
AOSP开发环境配置
android·安卓
叶羽西15 小时前
Android Studio打开一个外部的Android app程序
android·ide·android studio