前言:因为项目需要设置安卓9.0系统的以太网静态ip地址,于是网上搜索相关资料。9.0系统以太网设置静态ip有关的,只有Github上有个MTK开发人员的分享,github链接:https://github.com/Dufre/Android-Settings-Ethernet,patch是在系统设置中加上以太网设置,用过后发现设置静态IP可以成功,但是无法连外网,解决方法是将 0001-Ethernet-Add-Static-IP-Settiings.patch 中的两个注释去掉,改成如下,且在设置的时候一定要配置正确的网关和DNS。

+        mStaticIpConfiguration.gateway=gatewayAddr;
+        mStaticIpConfiguration.dnsServers.add(dnsAddr);

 打patch方式,比方说想打0001-Ethernet-Add-Static-IP-Settiings.patch,那么到/packages/apps/Settings目录,这个目录可以通过看patch文件中类似如下代码中a/b所在目录确认。

diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 4456aa0..ea33f8a 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml

// 进入到a所在目录即可。

然后执行patch -p1 < patch文件绝对路径,p后面是数字1,即可。

0001-Ethernet-IP-Add-Framework-Interface.patch这个patch到/frameworks/base目录导入。

0001-Ethernet-IP-Add-Framework-Function.patch这个patch到/frameworks/opt/net/ethernet目录导入。

接下来讲解如何通过一个方法来实现9.0以太网设置。

首先:在应用的清单文件中授权网络权限,主要应该是如下几个。同时

sharedUserId设置成"android.uid.system"。
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
<uses-permission android:name="android.permission.CONNECTIVITY_INTERNAL"/>
<uses-permission android:name="android.permission.CONNECTIVITY_USE_RESTRICTED_NETWORKS"/>

其次:导入framework.jar,因为用到的类都是在framework中的。而且我测试的时候也使用了platform签名。

最后:终极方法如下,反射方式获取EthernetManager的实例参考 https://blog.csdn.net/aaa1050070637/article/details/79769788

   private static final String TAG = "EthernetUtils";
    /**
     * @param context use Activity or Service context
     * @param ipAddress ip address: like 192.168.1.168
     * @param mode : STATIC or DHCP, set static or dhcp ip mode
     * @param netmask ip mask, like 255.255.255.0
     * @param gateway gateway, like 192.168.1.1
     * @param dns1 dns 1
     * @param dns2 dns 2, if mode=static, then can use "" or null
     *   eg. dhcp mode: setEthernetIP(ApplicationContext, "DHCP", "", "", "", "", "");
     *         static mode: setEthernetIP(ApplicationContext, "STATIC",
     *                     "192.168.1.168", "255.255.255.0",
     *                     "192.168.1.1", "114.114.114.114", "8.8.8.8");
     *  for android 9.0
     * */
    public static void setEthernetIP(Context context, String mode, String ipAddress, String netmask,
                                     String gateway, String dns1, String dns2) {
        if (context == null || (!"STATIC".equals(mode) && !"DHCP".equals(mode))) {
            Log.d(TAG, " setEthernetIP failed, param incorrect context=" + context + ", mode=" + mode);
            return;
        }

        try {
            // get EthernetManager instance by reflect @{
            Class<?> ethernetManagerClass = Class
                    .forName("android.net.EthernetManager");
            Class<?> iEthernetManagerClass = Class
                    .forName("android.net.IEthernetManager");
            // 获取ETHERNET_SERVICE参数
            String ETHERNET_SERVICE = (String) Context.class.getField(
                    "ETHERNET_SERVICE").get(null);
            // 获取ethernetManager服务对象
            Object ethernetManager = context.getSystemService(ETHERNET_SERVICE);
            // 获取在EthernetManager中的抽象类mService成员变量
            Field mService = ethernetManagerClass.getDeclaredField("mService");
            // 修改private权限
            mService.setAccessible(true);
            // 获取抽象类的实例化对象
            Object mServiceObject = mService.get(ethernetManager);
            Object ethernetManagerInstance = ethernetManagerClass
                    .getDeclaredConstructor(Context.class,
                            iEthernetManagerClass).newInstance(context,
                            mServiceObject);
            EthernetManager mEthManager = (EthernetManager) ethernetManagerInstance;
            // @}

            String[] ifaces = mEthManager.getAvailableInterfaces();
            if (ifaces.length <= 0) {
                Log.e(TAG, " setEthernetIP failed ifaces.length <= 0");
                return;
            }
            String mInterfaceName = ifaces[0];
            Log.d(TAG, " setEthernetIP mInterfaceName=" + mInterfaceName);
            if ("DHCP".equals(mode)) {
                Log.i(TAG, " setEthernetIP  set dhcp started");
                IpConfiguration dhcpConfiguration = new IpConfiguration(IpConfiguration.IpAssignment.DHCP,
                        IpConfiguration.ProxySettings.NONE, null, null);
                dhcpConfiguration.setIpAssignment(IpConfiguration.IpAssignment.DHCP);
                mEthManager.setConfiguration(mInterfaceName, dhcpConfiguration);
                return;
            }

            if (TextUtils.isEmpty(ipAddress)
                    || TextUtils.isEmpty(netmask) || TextUtils.isEmpty(gateway)
                    || TextUtils.isEmpty(dns1)) {
                Log.e(TAG, "setEthernetIP error has some param is null ipAddress=" + ipAddress
                        + ", netmask=" + netmask + ", gateway=" + gateway
                        + ", dns1=" + dns1 + ", dns2=" + dns2);
                return;
            }
            StaticIpConfiguration mStaticIpConfiguration = new StaticIpConfiguration();
            int prefixLength = maskStr2InetMask(netmask);
            InetAddress inetAddr = null;
            InetAddress gatewayAddr = getIPv4Address(gateway);
            InetAddress dnsAddr = getIPv4Address(dns1);

            if (TextUtils.isEmpty(ipAddress)) {
                inetAddr = NetUtils.getLocalIPAddress();
            } else {
                String[] ipStr = ipAddress.split("\\.");
                byte[] ipBuf = new byte[4];
                for (int i = 0; i < 4; i++) {
                    ipBuf[i] = (byte) (Integer.parseInt(ipStr[i]) & 0xff);
                }
                try {
                    inetAddr = InetAddress.getByAddress(ipBuf);
                    Log.d(TAG, "setEthernetIP  address correct inetAddr=" + inetAddr);
                } catch (UnknownHostException e) {
                    e.printStackTrace();
                }
            }

            if (inetAddr == null || inetAddr.getAddress().toString().isEmpty()
                    || prefixLength == 0 || gatewayAddr.toString().isEmpty()
                    || dnsAddr == null || dnsAddr.toString().isEmpty()) {
                Log.d(TAG, " setEthernetIP  address incorrect inetAddr=" + inetAddr);
                return;
            }

            Class<?> linkAddressClass = null;
            linkAddressClass = Class.forName("android.net.LinkAddress");
            Class[] cl = new Class[]{InetAddress.class, int.class};
            Constructor cons = null;
            //取得所有构造函数
            try {
                cons = linkAddressClass.getConstructor(cl);
            } catch (NoSuchMethodException e) {
                e.printStackTrace();
            }
            //给传入参数赋初值
            Object[] x = {inetAddr, prefixLength};
            try {
                mStaticIpConfiguration.ipAddress = (LinkAddress) cons.newInstance(x);
                Log.d(TAG, " setEthernetIP mStaticIpConfiguration.ipAddress=" + mStaticIpConfiguration.ipAddress);
            } catch (InstantiationException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                e.printStackTrace();
            }

            mStaticIpConfiguration.gateway = gatewayAddr;
            mStaticIpConfiguration.dnsServers.add(dnsAddr);
            if (!dns2.isEmpty())
                mStaticIpConfiguration.dnsServers.add(getIPv4Address(dns2));

            Log.d(TAG, " setEthernetIP mStaticIpConfiguration  ====" + mStaticIpConfiguration
                    + ", inetAddr=" + inetAddr + ", mEthManager=" + mEthManager);

            IpConfiguration ipConfiguration = new IpConfiguration(IpConfiguration.IpAssignment.STATIC,
                    IpConfiguration.ProxySettings.NONE, mStaticIpConfiguration, null);
            ipConfiguration.setIpAssignment(IpConfiguration.IpAssignment.STATIC);
            ipConfiguration.setStaticIpConfiguration(mStaticIpConfiguration);
            mEthManager.setConfiguration(mInterfaceName, ipConfiguration);
        } catch (Exception e) {
            Log.e(TAG, "setEthernetIP error e=" + e.getMessage(), e);
        }
    }

注意事项: 该方法最好在Activity或者Fragment中执行,第一个参数使用活动、碎片或服务的context,否则容易报线程不对或初始化以太网管理器的错误,且执行完后需要重启系统才能生效。

android 9.0 GO系统 framework.jar 见资源:https://download.csdn.net/download/zzhceo/11548681

2019.12.12补充github工程地址:https://github.com/zzhceo/EthernetStaticIp,欢迎大家点赞收藏。

 

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐