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

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

相关推荐
平凡シンプル13 分钟前
安卓 uniapp跨端开发
android·uni-app
elina801316 分钟前
安卓实现导入Excel文件
android·excel
严文文-Chris20 分钟前
【设计模式-享元】
android·java·设计模式
趋势大仙1 小时前
SQLiteDatabase insert or replace数据不生效
android·数据库
DS小龙哥1 小时前
QT For Android开发-打开PPT文件
android·qt·powerpoint
试行2 小时前
Android实现自定义下拉列表绑定数据
android·java
Dingdangr7 小时前
Android中的Intent的作用
android
技术无疆7 小时前
快速开发与维护:探索 AndroidAnnotations
android·java·android studio·android-studio·androidx·代码注入
GEEKVIP7 小时前
Android 恢复挑战和解决方案:如何从 Android 设备恢复删除的文件
android·笔记·安全·macos·智能手机·电脑·笔记本电脑
Jouzzy13 小时前
【Android安全】Ubuntu 16.04安装GDB和GEF
android·ubuntu·gdb