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

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

相关推荐
大白要努力!27 分钟前
Android opencv使用Core.hconcat 进行图像拼接
android·opencv
天空中的野鸟1 小时前
Android音频采集
android·音视频
小白也想学C2 小时前
Android 功耗分析(底层篇)
android·功耗
曙曙学编程3 小时前
初级数据结构——树
android·java·数据结构
闲暇部落5 小时前
‌Kotlin中的?.和!!主要区别
android·开发语言·kotlin
诸神黄昏EX7 小时前
Android 分区相关介绍
android
大白要努力!8 小时前
android 使用SQLiteOpenHelper 如何优化数据库的性能
android·数据库·oracle
Estar.Lee8 小时前
时间操作[取当前北京时间]免费API接口教程
android·网络·后端·网络协议·tcp/ip
Winston Wood8 小时前
Perfetto学习大全
android·性能优化·perfetto
Dnelic-11 小时前
【单元测试】【Android】JUnit 4 和 JUnit 5 的差异记录
android·junit·单元测试·android studio·自学笔记