Android 有线网络静态属性配置

Android 有线网络静态属性配置

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

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

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

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

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 这个类的所有字段的含义

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这个类的一些字段的含义

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、使用反射调用系统方法设置网络属性

直接上完整调用的代码;

/**
     * 设置静态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方法,这里一并转换出来

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

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Kuye--

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值