Android13 原生以太网实现设置静态IP
一、引言
首先需要实现android13设置静态IP的功能,就要对android13以太网架构变化大致理解,谷歌把以太网相关的功能进行模块化,提取到packages/modules/Connectivity/目录,导致之前的实现需要调整,本文主要从2大块进行阐述,分别为framework与原生Settings。
本文涉及功能点主要有如下几点:
1.设置IP的方式分为DHCP和静态两种
2.IP地址的设置
3.子网掩码设置
4.DNS设置
5.网关设置
6.代理设置
二、Framework部分
2.1、涉及修改的类
packages/modules/Connectivity/framework-t/api/module-lib-current.txt packages/modules/Connectivity/framework-t/src/android/net/EthernetManager.java packages/modules/Connectivity/framework-t/src/android/net/IEthernetManager.aidl packages/modules/Connectivity/framework/api/current.txt packages/modules/Connectivity/framework/api/system-current.txt packages/modules/Connectivity/framework/src/android/net/IpConfiguration.java packages/modules/Connectivity/framework/src/android/net/ProxyInfo.java packages/modules/Connectivity/service-t/src/com/android/server/ethernet/EthernetNetworkFactory.java packages/modules/Connectivity/service-t/src/com/android/server/ethernet/EthernetServiceImpl.java packages/modules/Connectivity/service-t/src/com/android/server/ethernet/EthernetTracker.java
2.2、涉及类修改阐述
android其实不管怎么更新,都离不开client-aidl-server这样的模式,所以大体思路就是根
据以太网源码框架,在其上模仿原有的接口进行添加内容的方式,先把路打通。
2.2.1、客户端接口添加及修改
1.IEthernetManager.aidl类中添加4个接口,提供给上层使用
/* * Copyright (C) 2014 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.net; import android.net.IpConfiguration; import android.net.IEthernetServiceListener; import android.net.EthernetNetworkManagementException; import android.net.EthernetNetworkUpdateRequest; import android.net.INetworkInterfaceOutcomeReceiver; import android.net.ITetheredInterfaceCallback; import java.util.List; /** * Interface that answers queries about, and allows changing * ethernet configuration. */ /** {@hide} */ interface IEthernetManager { String[] getAvailableInterfaces(); IpConfiguration getConfiguration(String iface); void setConfiguration(String iface, in IpConfiguration config); boolean isAvailable(String iface); void addListener(in IEthernetServiceListener listener); void removeListener(in IEthernetServiceListener listener); void setIncludeTestInterfaces(boolean include); void requestTetheredInterface(in ITetheredInterfaceCallback callback); void releaseTetheredInterface(in ITetheredInterfaceCallback callback); void updateConfiguration(String iface, in EthernetNetworkUpdateRequest request, in INetworkInterfaceOutcomeReceiver listener); void connectNetwork(String iface, in INetworkInterfaceOutcomeReceiver listener); void disconnectNetwork(String iface, in INetworkInterfaceOutcomeReceiver listener); void setEthernetEnabled(boolean enabled); List getInterfaceList(); //added by cgt Adding an Ethernet Interface start String getIpAddress(String iface); String getNetmask(String iface); String getGateway(String iface); String getDns(String iface); //added by cgt Adding an Ethernet Interface end }
2.EthernetManager.java类中实现aidl中的4个接口,并修改android13 APP调用以太网API时受限制
import java.util.Objects; import java.util.concurrent.Executor; import java.util.function.IntConsumer; +//added by cgt Adding an Ethernet Interface start +import java.net.InetAddress; +import android.net.NetworkUtils; +//added by cgt Adding an Ethernet Interface end /** * A class that manages and configures Ethernet interfaces. @@ -191,8 +195,15 @@ public class EthernetManager { * @return the Ethernet Configuration, contained in {@link IpConfiguration}. * @hide */ - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) - public IpConfiguration getConfiguration(String iface) { + //added by cgt Adding an Ethernet Interface start + /*@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) + public IpConfiguration getConfiguration(String iface) {*/ + @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) + @SystemApi(client = MODULE_LIBRARIES) + @NonNull + @UnsupportedAppUsage + public IpConfiguration getConfiguration(@NonNull String iface) { + //added by cgt Adding an Ethernet Interface end try { return mService.getConfiguration(iface); } catch (RemoteException e) { @@ -204,7 +215,13 @@ public class EthernetManager { * Set Ethernet configuration. * @hide */ - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) + //added by cgt Adding an Ethernet Interface start + //@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) + @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) + @SystemApi(client = MODULE_LIBRARIES) + @NonNull + @UnsupportedAppUsage + //added by cgt Adding an Ethernet Interface end public void setConfiguration(@NonNull String iface, @NonNull IpConfiguration config) { try { mService.setConfiguration(iface, config); @@ -217,7 +234,10 @@ public class EthernetManager { * Indicates whether the system currently has one or more Ethernet interfaces. * @hide */ - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) + //added by cgt Adding an Ethernet Interface start + //@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) + @UnsupportedAppUsage + //modified by cengt,ethernet,Adding an Ethernet Interface,20230628-end public boolean isAvailable() { return getAvailableInterfaces().length > 0; } @@ -228,7 +248,10 @@ public class EthernetManager { * @param iface Ethernet interface name * @hide */ - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) + //added by cgt Adding an Ethernet Interface start + //@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) + @UnsupportedAppUsage + //added by cgt Adding an Ethernet Interface end public boolean isAvailable(String iface) { try { return mService.isAvailable(iface); @@ -318,7 +341,13 @@ public class EthernetManager { * Returns an array of available Ethernet interface names. * @hide */ - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) + //added by cgt Adding an Ethernet Interface start + //@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) + @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) + @SystemApi(client = MODULE_LIBRARIES) + @NonNull + @UnsupportedAppUsage + //added by cgt Adding an Ethernet Interface end public String[] getAvailableInterfaces() { try { return mService.getAvailableInterfaces(); @@ -696,9 +725,12 @@ public class EthernetManager { * is available or not currently. * @hide */ + //added by cgt Adding an Ethernet Interface start + //@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) @SystemApi(client = MODULE_LIBRARIES) @NonNull + //added by cgt Adding an Ethernet Interface end public List getInterfaceList() { try { return mService.getInterfaceList(); @@ -706,4 +738,78 @@ public class EthernetManager { throw e.rethrowAsRuntimeException(); } } + + //added by cgt Adding an Ethernet Interface start + /** + * @hide + */ + @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) + @SystemApi(client = MODULE_LIBRARIES) + @NonNull + @UnsupportedAppUsage + public String getIpAddress(@NonNull String iface) { + try { + return mService.getIpAddress(iface); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + /** + * @hide + */ + @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) + @SystemApi(client = MODULE_LIBRARIES) + @NonNull + @UnsupportedAppUsage + public String getNetmask(@NonNull String iface) { + try { + return mService.getNetmask(iface); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + /** + * @hide + */ + @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) + @SystemApi(client = MODULE_LIBRARIES) + @NonNull + @UnsupportedAppUsage + public String getGateway(@NonNull String iface) { + try { + return mService.getGateway(iface); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + /** + * @hide + */ + @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) + @SystemApi(client = MODULE_LIBRARIES) + @NonNull + @UnsupportedAppUsage + public String getDns(@NonNull String iface) { + try { + return mService.getDns(iface); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + /** + * @hide + */ + @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) + @SystemApi(client = MODULE_LIBRARIES) + @NonNull + @UnsupportedAppUsage + public static InetAddress iminNumericToInetAddress(@NonNull String text) { + return NetworkUtils.numericToInetAddress(text); + } + //added by cgt Adding an Ethernet Interface end + }
3.module-lib-current.txt类中实现aidl添加接口后系统编译的文件,此文件也可以自行使用make update-api编译生成,如不想编译直接自己实现
+++ b/XXX/packages/modules/Connectivity/framework-t/api/module-lib-current.txt @@ -44,9 +44,17 @@ package android.net { public class EthernetManager { method @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public void addEthernetStateListener(@NonNull java.util.concurrent.Executor, @NonNull java.util.function.IntConsumer); method @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public void addInterfaceStateListener(@NonNull java.util.concurrent.Executor, @NonNull android.net.EthernetManager.InterfaceStateListener); + method @NonNull @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public String[] getAvailableInterfaces(); + method @NonNull @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public android.net.IpConfiguration getConfiguration(@NonNull String); + method @NonNull @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public String getDns(@NonNull String); + method @NonNull @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public String getGateway(@NonNull String); method @NonNull @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public java.util.List getInterfaceList(); + method @NonNull @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public String getIpAddress(@NonNull String); + method @NonNull @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public String getNetmask(@NonNull String); + method @NonNull @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public static java.net.InetAddress iminNumericToInetAddress(@NonNull String); method @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public void removeEthernetStateListener(@NonNull java.util.function.IntConsumer); method public void removeInterfaceStateListener(@NonNull android.net.EthernetManager.InterfaceStateListener); + method @NonNull @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public void setConfiguration(@NonNull String, @No nNull android.net.IpConfiguration); method @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_STACK , android.Manifest.permission.NETWORK_SETTINGS}) public void setEthernetEnabled(boolean); method public void setIncludeTestInterfaces(boolean); field public static final int ETHERNET_STATE_DISABLED = 0; // 0x0
4.current.txt类中添加ProxyInfo两个构造函数
+++ b/XXX/packages/modules/Connectivity/framework/api/current.txt @@ -445,6 +445,8 @@ package android.net { } public class ProxyInfo implements android.os.Parcelable { + ctor public ProxyInfo(@NonNull String, int, @NonNull String); + ctor public ProxyInfo(@NonNull android.net.Uri); ctor public ProxyInfo(@Nullable android.net.ProxyInfo); method public static android.net.ProxyInfo buildDirectProxy(String, int); method public static android.net.ProxyInfo buildDirectProxy(String, int, java.util.List);
5.system-current.txt类中添加两个函数
+++ b/xxx/packages/modules/Connectivity/framework/api/system-current.txt @@ -126,6 +126,7 @@ package android.net { public final class IpConfiguration implements android.os.Parcelable { ctor public IpConfiguration(); + ctor public IpConfiguration(@NonNull android.net.IpConfiguration.IpAssignment, @NonNull android.net.IpConfiguration.ProxySettings, @NonNull android.net.StaticIpConfiguration, @NonNull android.net.ProxyInfo); ctor public IpConfiguration(@NonNull android.net.IpConfiguration); method @NonNull public android.net.IpConfiguration.IpAssignment getIpAssignment(); method @NonNull public android.net.IpConfiguration.ProxySettings getProxySettings();
6.IpConfiguration.java类中修改android13 APP调用以太网API时受限制
+++ b/xxx/packages/modules/Connectivity/framework/src/android/net/IpConfiguration.java @@ -103,11 +103,14 @@ public final class IpConfiguration implements Parcelable { } /** @hide */ - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) - public IpConfiguration(IpAssignment ipAssignment, - ProxySettings proxySettings, - StaticIpConfiguration staticIpConfiguration, - ProxyInfo httpProxy) { + //added by cgt Adding an Ethernet Interface start + //@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) + @SystemApi + //added by cgt Adding an Ethernet Interface end + public IpConfiguration(@NonNull IpAssignment ipAssignment, + @NonNull ProxySettings proxySettings, + @NonNull StaticIpConfiguration staticIpConfiguration, + @NonNull ProxyInfo httpProxy) { init(ipAssignment, proxySettings, staticIpConfiguration, httpProxy); }
7.ProxyInfo.java类中修改android13 APP调用以太网API时受限制
+++ b/xxx/packages/modules/Connectivity/framework/src/android/net/ProxyInfo.java @@ -103,10 +103,11 @@ public class ProxyInfo implements Parcelable { /** * Create a ProxyProperties that points at a HTTP Proxy. - * @hide */ - @UnsupportedAppUsage - public ProxyInfo(String host, int port, String exclList) { + //added by cgt Adding an Ethernet Interface start + //@UnsupportedAppUsage + //added by cgt Adding an Ethernet Interface end + public ProxyInfo(@NonNull String host, int port, @NonNull String exclList) { mHost = host; mPort = port; mExclusionList = exclList; @@ -116,7 +117,6 @@ public class ProxyInfo implements Parcelable { /** * Create a ProxyProperties that points at a PAC URL. - * @hide */ public ProxyInfo(@NonNull Uri pacFileUrl) { mHost = LOCAL_HOST;
2.2.2、客户端接口添加及修改
1.EthernetNetworkFactory.java类中实现4个接口
+++ b/xxx/packages/modules/Connectivity/service-t/src/com/android/server/ethernet/EthernetNetworkFactory.java @@ -58,6 +58,17 @@ import java.io.FileDescriptor; import java.util.Objects; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; +//added by cgt Adding an Ethernet Interface start +import android.net.EthernetManager; +import android.net.LinkAddress; +import android.net.NetworkUtils; +import android.net.RouteInfo; +import java.net.Inet4Address; +import java.net.InetAddress; +import android.net.LinkAddress; +import android.net.NetworkUtils; +import android.net.RouteInfo; +//added by cgt Adding an Ethernet Interface end /** * {@link NetworkProvider} that manages NetworkOffers for Ethernet networks. @@ -118,7 +129,114 @@ public class EthernetNetworkFactory { mContext = context; mProvider = provider; mDeps = deps; + //added by cgt Adding an Ethernet Interface start + mEthernetManager = (EthernetManager) context.getSystemService(Context.ETHERNET_SERVICE); + //added by cgt Adding an Ethernet Interface end + } + + //added by cgt Adding an Ethernet Interface start + private EthernetManager mEthernetManager; + String getIpAddress(String iface) { + if(mEthernetManager == null){ + mEthernetManager = (EthernetManager) mContext.getSystemService(Context.ETHERNET_SERVICE); + } + IpConfiguration config = mEthernetManager.getConfiguration(iface); + if (config.getIpAssignment() == IpAssignment.STATIC) { + return config.getStaticIpConfiguration().ipAddress.getAddress().getHostAddress(); + } else { + NetworkInterfaceState netState = mTrackingInterfaces.get(iface); + if (null != netState) { + for (LinkAddress l : netState.mLinkProperties.getLinkAddresses()) { + InetAddress source = l.getAddress(); + //Log.d(TAG, "getIpAddress: " + source.getHostAddress()); + if (source instanceof Inet4Address) { + return source.getHostAddress(); + } + } + } + } + return ""; + } + + private String prefix2netmask(int prefix) { + // convert prefix to netmask + if (true) { + int mask = 0xFFFFFFFF >>24) & 0xff) + "." + ((mask>>>16) & 0xff) + "." + ((mask>>>8) & 0xff) + "." + ((mask) & 0xff); + } else { + return NetworkUtils.intToInetAddress(NetworkUtils.prefixLengthToNetmaskInt(prefix)).getHostName(); + } + } + + String getNetmask(String iface) { + if(mEthernetManager == null){ + mEthernetManager = (EthernetManager) mContext.getSystemService(Context.ETHERNET_SERVICE); + } + IpConfiguration config = mEthernetManager.getConfiguration(iface); + if (config.getIpAssignment() == IpAssignment.STATIC) { + return prefix2netmask(config.getStaticIpConfiguration().ipAddress.getPrefixLength()); + } else { + NetworkInterfaceState netState = mTrackingInterfaces.get(iface); + if (null != netState) { + for (LinkAddress l : netState.mLinkProperties.getLinkAddresses()) { + InetAddress source = l.getAddress(); + if (source instanceof Inet4Address) { + return prefix2netmask(l.getPrefixLength()); + } + } + } + } + return ""; + } + + String getGateway(String iface) { + if(mEthernetManager == null){ + mEthernetManager = (EthernetManager) mContext.getSystemService(Context.ETHERNET_SERVICE); + } + IpConfiguration config = mEthernetManager.getConfiguration(iface); + if (config.getIpAssignment() == IpAssignment.STATIC) { + return config.getStaticIpConfiguration().gateway.getHostAddress(); + } else { + NetworkInterfaceState netState = mTrackingInterfaces.get(iface); + if (null != netState) { + for (RouteInfo route : netState.mLinkProperties.getRoutes()) { + if (route.hasGateway()) { + InetAddress gateway = route.getGateway(); + if (route.isIPv4Default()) { + return gateway.getHostAddress(); + } + } + } + } + } + return ""; + } + + /* + * return dns format: "8.8.8.8,4.4.4.4" + */ + String getDns(String iface) { + if(mEthernetManager == null){ + mEthernetManager = (EthernetManager) mContext.getSystemService(Context.ETHERNET_SERVICE); + } + String dns = ""; + IpConfiguration config = mEthernetManager.getConfiguration(iface); + if (config.getIpAssignment() == IpAssignment.STATIC) { + for (InetAddress nameserver : config.getStaticIpConfiguration().dnsServers) { + dns += nameserver.getHostAddress() + ","; + } + } else { + NetworkInterfaceState netState = mTrackingInterfaces.get(iface); + if (null != netState) { + for (InetAddress nameserver : netState.mLinkProperties.getDnsServers()) { + dns += nameserver.getHostAddress() + ","; + } + } + } + return dns; } + //added by cgt Adding an Ethernet Interface end /** * Registers the network provider with the system.
2.EthernetTracker.java类中调用EthernetNetworkFactory类中的接口,修改updateInterfaceState方法的访问范围供APP使用
+++ b/xxx/packages/modules/Connectivity/service-t/src/com/android/server/ethernet/EthernetTracker.java @@ -173,6 +173,24 @@ public class EthernetTracker { mConfigStore = new EthernetConfigStore(); } + //added by cgt Adding an Ethernet Interface start + String getIpAddress(String iface) { + return mFactory.getIpAddress(iface); + } + + String getNetmask(String iface) { + return mFactory.getNetmask(iface); + } + + String getGateway(String iface) { + return mFactory.getGateway(iface); + } + + String getDns(String iface) { + return mFactory.getDns(iface); + } + //added by cgt Adding an Ethernet Interface end + void start() { mFactory.register(); mConfigStore.read(); @@ -533,7 +551,10 @@ public class EthernetTracker { } } - private void updateInterfaceState(String iface, boolean up) { + //added by cgt Adding an Ethernet Interface start + //private void updateInterfaceState(String iface, boolean up) { + public void updateInterfaceState(String iface, boolean up) { + //added by cgt Adding an Ethernet Interface end updateInterfaceState(iface, up, null /* listener */); }
3.EthernetServiceImpl.java类中调用EthernetTracker类中的接口,供给APP用
+++ b/xxx/packages/modules/Connectivity/service-t/src/com/android/server/ethernet/EthernetServiceImpl.java @@ -122,8 +122,57 @@ public class EthernetServiceImpl extends IEthernetManager.Stub { // TODO: this does not check proxy settings, gateways, etc. // Fix this by making IpConfiguration a complete representation of static configuration. mTracker.updateIpConfiguration(iface, new IpConfiguration(config)); } + //added by cgt Adding an Ethernet Interface start + @Override + public String getIpAddress(String iface) { + PermissionUtils.enforceAccessNetworkStatePermission(mContext, TAG); + if (mTracker.isRestrictedInterface(iface)) { + PermissionUtils.enforceRestrictedNetworkPermission(mContext, TAG); + } + + return mTracker.getIpAddress(iface); + } + + @Override + public String getNetmask(String iface) { + PermissionUtils.enforceAccessNetworkStatePermission(mContext, TAG); + if (mTracker.isRestrictedInterface(iface)) { + PermissionUtils.enforceRestrictedNetworkPermission(mContext, TAG); + } + + return mTracker.getNetmask(iface); + } + + @Override + public String getGateway(String iface) { + PermissionUtils.enforceAccessNetworkStatePermission(mContext, TAG); + if (mTracker.isRestrictedInterface(iface)) { + PermissionUtils.enforceRestrictedNetworkPermission(mContext, TAG); + } + + return mTracker.getGateway(iface); + } + + @Override + public String getDns(String iface) { + PermissionUtils.enforceAccessNetworkStatePermission(mContext, TAG); + if (mTracker.isRestrictedInterface(iface)) { + PermissionUtils.enforceRestrictedNetworkPermission(mContext, TAG); + } + + return mTracker.getDns(iface); + } + //added by cgt Adding an Ethernet Interface end + /** * Indicates whether given interface is available. */
三、Settings部分
3.1、涉及修改的类
Settings/AndroidManifest.xml Settings/res/layout/static_ip_dialog.xml Settings/res/xml/imin_ethernet_settings.xml Settings/res/xml/network_provider_internet.xml Settings/src/com/android/settings/core/gateway/SettingsGateway.java Settings/src/com/android/settings/ethernet/EtherentStaticIpDialog.java Settings/src/com/android/settings/ethernet/EthernetSettingsPreferenceController.java Settings/src/com/android/settings/ethernet/IminEthernetSettings.java Settings/src/com/android/settings/ethernet/getStaticIpInfo.java
3.2、涉及类修改的类
Settings中添加一个界面去设置以太网相关的内容,我们可以仿照原生在网络中添加一项
以太网设置,供用户使用,以下简略描述下实现相关。
3.2.1、资源类
1.AndroidManifest.xml类中配置添加的以太网界面
+++ b/packages/apps/Settings/AndroidManifest.xml @@ -801,9 +801,28 @@ android:value="@string/menu_key_network"/> + + + + + + + + + + + - + +
2.network_provider_internet.xml类中配置添加显示在网络选项中的以太网项
+++ b/Settings/res/xml/network_provider_internet.xml @@ -108,6 +108,16 @@ settings:userRestriction="no_config_vpn" settings:useAdminDisabledSummary="true" /> + + + + 0) { mIfaceName = ifaces[0];//"eth0"; } if (null == mIfaceName) { Log.e(TAG, "get ethernet ifaceName failed"); Toast.makeText(mContext, R.string.disabled_feature, Toast.LENGTH_SHORT).show(); finish(); } } @Override public void onResume() { super.onResume(); if (null == mIfaceName) { return; } if (mkeyEthMode == null) { mkeyEthMode = (Preference) findPreference(KEY_ETH_test); mkeyEthMode.setOnPreferenceClickListener(this); } setStringSummary(KEY_ETH_MAC, getEthernetMacAddress()); log("resume"); mContext.registerReceiver(mReceiver, mIntentFilter); } @Override public void onPause() { super.onPause(); log("onPause"); if (null == mIfaceName) { return; } //setIPSettingMode(); //setProxyInfo(); mContext.unregisterReceiver(mReceiver); if(alertDialog != null){ alertDialog.dismiss(); } } @Override public void onDestroy() { super.onDestroy(); mHandler.removeMessages(MSG_GET_ETHERNET_STATE); log("destory"); } @Override public void onStop() { super.onStop(); log("stop"); } private final BroadcastReceiver mReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); log("Action " + action); if (ConnectivityManager.CONNECTIVITY_ACTION.equals(action)) { NetworkInfo info = intent.getParcelableExtra(ConnectivityManager.EXTRA_NETWORK_INFO); Log.v(TAG, "===" + info.toString()); if (null != info && ConnectivityManager.TYPE_ETHERNET == info.getType()) { long currentTime = System.currentTimeMillis(); int delayTime = 0; if (currentTime - mChangeTime 0) { Message msg = new Message(); msg.what = MSG_GET_ETHERNET_STATE; msg.obj = EtherState; mHandler.sendMessageDelayed(msg, delayMillis); } else { handleEtherStateChange(EtherState); } } private void handleEtherStateChange(ETHERNET_STATE EtherState) { log("curEtherState" + EtherState); switch (EtherState) { case ETHER_STATE_DISCONNECTED: mEthHwAddress = nullIpInfo; mEthIpAddress = nullIpInfo; mEthNetmask = nullIpInfo; mEthGateway = nullIpInfo; mEthdns1 = nullIpInfo; mEthdns2 = nullIpInfo; break; case ETHER_STATE_CONNECTING: //modify by luoyalong for Eth and WLAN control 20220530 begin String way = Settings.System.getString(mContext.getContentResolver() , "test_ip_way"); IpAssignment mode = way != null&& way.equals("static") ? IpAssignment.STATIC : IpAssignment.DHCP; log("IES refreshtestUI way= " + way + " , mode= " + mode); log("handleEtherStateChange mode= " + mode); if (mode == IpAssignment.DHCP) { String mStatusString = this.getResources().getString(R.string.ethernet_info_getting); mEthHwAddress = mStatusString; mEthIpAddress = mStatusString; mEthNetmask = mStatusString; mEthGateway = mStatusString; mEthdns1 = mStatusString; mEthdns2 = mStatusString; }else{ getEthInfo(); } //modify by luoyalong for Eth and WLAN control 20220530 end break; case ETHER_STATE_CONNECTED: getEthInfo(); break; } if(isAdded()){ refreshtestUI(); } } private void refreshtestUI(){ ConnectivityManager mConnectivityManager = (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo mNetworkInfo = mConnectivityManager.getActiveNetworkInfo(); if(mNetworkInfo != null && mNetworkInfo.isConnected() && !(mNetworkInfo.getType() == ConnectivityManager.TYPE_WIFI)){ String connected = this.getResources().getString(R.string.network_connected); setStringSummary(KEY_ETH_test, connected); }else{ String notConnected = this.getResources().getString(R.string.test_ethernet_not_connect); setStringSummary(KEY_ETH_test, notConnected); } if(test_ip_et != null){ String way = Settings.System.getString(mContext.getContentResolver() , "test_ip_way"); IpAssignment mode = way != null&& way.equals("static") ? IpAssignment.STATIC : IpAssignment.DHCP; log("IES refreshtestUI way= " + way + " , mode= " + mode); if (mode == IpAssignment.STATIC) { isStaticMode = true; test_ip_set_static_rb.setChecked(true); test_ip_et.setEnabled(true); test_mask_et.setEnabled(true); test_dns_et.setEnabled(true); test_gateway_et.setEnabled(true); } else { isStaticMode = false; test_ip_set_dhcp_rb.setChecked(true); test_ip_et.setEnabled(false); test_mask_et.setEnabled(false); test_dns_et.setEnabled(false); test_gateway_et.setEnabled(false); } String host = Settings.System.getString(mContext.getContentResolver() , "test_proxy_host"); String port = Settings.System.getString(mContext.getContentResolver() , "test_proxy_port"); String exclList = Settings.System.getString(mContext.getContentResolver() , "test_proxy_exclList"); String uri = Settings.System.getString(mContext.getContentResolver() , "test_proxy_uri"); log("refreshtestUI host: = " + host + " , port: = " + port + " , exclList: = " + exclList + " , uri: = " + uri); String mHost = test_host_et.getText().toString(); String mPort = test_port_et.getText().toString(); String mExclList = test_proxy_et.getText().toString(); String uriString = test_pac_et.getText().toString(); if(!"".equals(mHost)){ host = mHost; } if(!"".equals(mPort)){ port = mPort; } if(!"".equals(mExclList)){ exclList = mExclList; } if(!"".equals(uriString)){ uri = uriString; } if(!"".equals(host)&& host != null){ test_host_et.setText(host); } if(!"".equals(port)&& port != null){ test_port_et.setText(port); } if(!"".equals(exclList)&& exclList != null){ test_proxy_et.setText(exclList); } if(!"".equals(uri)&& uri != null){ test_pac_et.setText(uri); } int agency = Settings.System.getInt(mContext.getContentResolver() , "test_agency_select" , 0); test_host_ll.setVisibility(View.GONE); test_port_ll.setVisibility(View.GONE); test_proxy_ll.setVisibility(View.GONE); test_pac_ll.setVisibility(View.GONE); if(agency == 1){ test_pac_ll.setVisibility(View.VISIBLE); test_agency_auto_rb.setChecked(true); }else if(agency == 2){ test_host_ll.setVisibility(View.VISIBLE); test_port_ll.setVisibility(View.VISIBLE); test_proxy_ll.setVisibility(View.VISIBLE); test_agency_manual_rb.setChecked(true); }else{ test_agency_not_rb.setChecked(true); } test_ip_et.setText(mEthIpAddress); test_mask_et.setText(mEthNetmask); test_gateway_et.setText(mEthGateway); test_dns_et.setText(mEthdns1); } log("refreshtestUI 380 mEthIpAddress= " + mEthIpAddress + " , mEthGateway= " + mEthGateway + " , mEthdns1= " + mEthdns1 + " , mEthNetmask= " + mEthNetmask); } private void settestEtherentDialog() { LayoutInflater layoutInflater = LayoutInflater.from(mContext); //modify by luoyalong for bug 5040 eth UI problem 20230308 begin View view =null; DisplayMetrics d2 = this.getResources().getDisplayMetrics(); if(d2.density > 2.0){ view =layoutInflater.inflate(R.layout.test_ethernet_dialog_2d, null); }else{ view =layoutInflater.inflate(R.layout.test_ethernet_dialog, null); } //modify by luoyalong for bug 5040 eth UI problem 20230308 end RadioGroup test_ip_set_rg = view.findViewById(R.id.test_ip_set_rg); test_ip_set_dhcp_rb = view.findViewById(R.id.test_ip_set_dhcp_rb); test_ip_set_static_rb = view.findViewById(R.id.test_ip_set_static_rb); test_ip_et = view.findViewById(R.id.test_ip_et); test_mask_et = view.findViewById(R.id.test_mask_et); test_dns_et = view.findViewById(R.id.test_dns_et); test_gateway_et = view.findViewById(R.id.test_gateway_et); RadioGroup test_agency_rg = view.findViewById(R.id.test_agency_rg); test_agency_not_rb = view.findViewById(R.id.test_agency_not_rb); test_agency_manual_rb = view.findViewById(R.id.test_agency_manual_rb); test_agency_auto_rb = view.findViewById(R.id.test_agency_auto_rb); test_host_ll = view.findViewById(R.id.test_host_ll); test_host_et = view.findViewById(R.id.test_host_et); test_port_ll = view.findViewById(R.id.test_port_ll); test_port_et = view.findViewById(R.id.test_port_et); test_proxy_ll = view.findViewById(R.id.test_proxy_ll); test_proxy_et = view.findViewById(R.id.test_proxy_et); test_pac_ll = view.findViewById(R.id.test_pac_ll); test_pac_et = view.findViewById(R.id.test_pac_et); Button test_confirm_bt = view.findViewById(R.id.test_confirm_bt); mEthIpAddress = mEthNetmask = mEthGateway = mEthdns1 = ""; getEthInfo(); refreshtestUI(); test_ip_set_rg.setOnCheckedChangeListener((group, checkedId) -> { //handleEtherStateChange(TestEthernetSettings.ETHERNET_STATE.ETHER_STATE_CONNECTING); if(checkedId == test_ip_set_dhcp_rb.getId()){ mEthTempIpAddress = test_ip_et.getText().toString(); mEthTempGateway = test_gateway_et.getText().toString(); mEthTempdns1 = test_dns_et.getText().toString(); mEthTempNetmask = test_mask_et.getText().toString(); getEthInfo(); log("setOnCheckedChangeListener dhcp mEthIpAddress= " + mEthIpAddress + " , mEthGateway= " + mEthGateway + " , mEthdns1= " + mEthdns1 + " , mEthNetmask= " + mEthNetmask + " mEthTempIpAddress= " + mEthTempIpAddress + " , mEthTempGateway= " + mEthTempGateway + " , mEthTempdns1= " + mEthTempdns1 + " , mEthTempNetmask= " + mEthTempNetmask); test_ip_et.setText(mEthIpAddress); test_mask_et.setText(mEthNetmask); test_gateway_et.setText(mEthGateway); test_dns_et.setText(mEthdns1); test_ip_et.setEnabled(false); test_mask_et.setEnabled(false); test_dns_et.setEnabled(false); test_gateway_et.setEnabled(false); mChangeTime = System.currentTimeMillis(); }else{ getEthInfo(); log("setOnCheckedChangeListener static mEthIpAddress= " + mEthIpAddress + " , mEthGateway= " + mEthGateway + " , mEthdns1= " + mEthdns1 + " , mEthNetmask= " + mEthNetmask + " mEthTempIpAddress= " + mEthTempIpAddress + " , mEthTempGateway= " + mEthTempGateway + " , mEthTempdns1= " + mEthTempdns1 + " , mEthTempNetmask= " + mEthTempNetmask); if (mEthTempIpAddress != null) { mEthIpAddress = mEthTempIpAddress; } if (mEthTempGateway != null) { mEthGateway = mEthTempGateway; } if (mEthTempdns1 != null) { mEthdns1 = mEthTempdns1; } if (mEthTempNetmask != null) { mEthNetmask = mEthTempNetmask; } test_ip_et.setText(mEthIpAddress); test_mask_et.setText(mEthNetmask); test_gateway_et.setText(mEthGateway); test_dns_et.setText(mEthdns1); test_ip_et.setEnabled(true); test_mask_et.setEnabled(true); test_dns_et.setEnabled(true); test_gateway_et.setEnabled(true); } }); test_agency_rg.setOnCheckedChangeListener((group, checkedId) -> { test_host_ll.setVisibility(View.GONE); test_port_ll.setVisibility(View.GONE); test_proxy_ll.setVisibility(View.GONE); test_pac_ll.setVisibility(View.GONE); Settings.System.putInt(mContext.getContentResolver() , "test_agency_select" , 0); if(checkedId == test_agency_auto_rb.getId()){ test_pac_ll.setVisibility(View.VISIBLE); Settings.System.putInt(mContext.getContentResolver() , "test_agency_select" , 1); }else if(checkedId == test_agency_manual_rb.getId()){ test_host_ll.setVisibility(View.VISIBLE); test_port_ll.setVisibility(View.VISIBLE); test_proxy_ll.setVisibility(View.VISIBLE); Settings.System.putInt(mContext.getContentResolver() , "test_agency_select" , 2); } }); test_confirm_bt.setOnClickListener(v -> { log("cliked confirm button" ); setEthernetSettings(); alertDialog.dismiss(); }); alertDialog = new AlertDialog.Builder(mContext).setView(view).create(); alertDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT); Window dialogWindow = alertDialog.getWindow(); WindowManager.LayoutParams lp = dialogWindow.getAttributes(); DisplayMetrics d = this.getResources().getDisplayMetrics(); alertDialog.show(); if(d.density > 1.6){ if(d.scaledDensity > 2.0){ alertDialog.getWindow().setLayout(840, 1320); }else{ alertDialog.getWindow().setLayout(840, 1160); } }else{ alertDialog.getWindow().setLayout(760, 800); } } private void setStringSummary(String preference, String value) { try { findPreference(preference).setSummary(value); } catch (RuntimeException e) { findPreference(preference).setSummary(""); log("can't find " + preference); } } private void setProxyInfo(){ IpAssignment ipAssignment = test_ip_set_static_rb.isChecked() ? IpAssignment.STATIC : IpAssignment.DHCP; log("setProxyInfo 431 ipAssignment= " + ipAssignment + " , isStaticMode : " + isStaticMode); if(test_agency_manual_rb.isChecked()){ String host = test_host_et.getText().toString(); String port = test_port_et.getText().toString(); String exclList = test_proxy_et.getText().toString(); log("setProxyInfo 440 host= " + host + " , port= " + port + " , exclList= " + exclList); if("".equals(host) || "".equals(port) || "".equals(exclList)){ Toast.makeText(mContext , R.string.test_ethernet_manual_setup_failed , Toast.LENGTH_LONG).show(); return; } Settings.System.putString(mContext.getContentResolver() , "test_proxy_host" , host); Settings.System.putString(mContext.getContentResolver() , "test_proxy_port" , port); Settings.System.putString(mContext.getContentResolver() , "test_proxy_exclList" , exclList); ProxyInfo proxyInfo = new ProxyInfo(host, Integer.parseInt(port), exclList); if(checkIPValue()){ mEthManager.setConfiguration(mIfaceName, new IpConfiguration(ipAssignment, ProxySettings.STATIC, isStaticMode ? mStaticIpConfiguration:null, proxyInfo)); } }else if(test_agency_auto_rb.isChecked()){ String uriString = test_pac_et.getText().toString(); log("setProxyInfo 449 uriString= " + uriString); if("".equals(uriString)){ Toast.makeText(mContext , R.string.test_ethernet_address_setup_failed , Toast.LENGTH_LONG).show(); return; } Settings.System.putString(mContext.getContentResolver() , "test_proxy_uri" , uriString); Uri uri = Uri.parse(uriString); ProxyInfo proxyInfo = new ProxyInfo(uri); if(checkIPValue()){ mEthManager.setConfiguration(mIfaceName, new IpConfiguration(ipAssignment, ProxySettings.PAC, isStaticMode ? mStaticIpConfiguration:null, proxyInfo)); } }else{ log("setProxyInfo null = "); if(checkIPValue()){ mEthManager.setConfiguration(mIfaceName, new IpConfiguration(ipAssignment, ProxySettings.NONE, isStaticMode ? mStaticIpConfiguration:null, null)); } } } private void setEthernetProxyInfo(){ IpAssignment ipAssignment = mCurrentModeIsStatic ? IpAssignment.STATIC : IpAssignment.DHCP; log("setEthernetProxyInfo 431 ipAssignment= " + ipAssignment + " , mCurrentModeIsStatic : " + mCurrentModeIsStatic); if(test_agency_manual_rb.isChecked()){ String host = test_host_et.getText().toString(); String port = test_port_et.getText().toString(); String exclList = test_proxy_et.getText().toString(); log("setProxyInfo 440 host= " + host + " , port= " + port + " , exclList= " + exclList); if("".equals(host) || "".equals(port) || "".equals(exclList)){ Toast.makeText(mContext , R.string.test_ethernet_manual_setup_failed , Toast.LENGTH_LONG).show(); return; } Settings.System.putString(mContext.getContentResolver() , "test_proxy_host" , host); Settings.System.putString(mContext.getContentResolver() , "test_proxy_port" , port); Settings.System.putString(mContext.getContentResolver() , "test_proxy_exclList" , exclList); ProxyInfo proxyInfo = new ProxyInfo(host, Integer.parseInt(port), exclList); mEthManager.setConfiguration(mIfaceName, new IpConfiguration(ipAssignment, ProxySettings.STATIC, mCurrentModeIsStatic ? mStaticIpConfiguration:null, proxyInfo)); }else if(test_agency_auto_rb.isChecked()){ String uriString = test_pac_et.getText().toString(); log("setProxyInfo 449 uriString= " + uriString); if("".equals(uriString)){ Toast.makeText(mContext , R.string.test_ethernet_address_setup_failed , Toast.LENGTH_LONG).show(); return; } Settings.System.putString(mContext.getContentResolver() , "test_proxy_uri" , uriString); Uri uri = Uri.parse(uriString); ProxyInfo proxyInfo = new ProxyInfo(uri); mEthManager.setConfiguration(mIfaceName, new IpConfiguration(ipAssignment, ProxySettings.PAC, mCurrentModeIsStatic ? mStaticIpConfiguration:null, proxyInfo)); }else{ log("setEthernetProxyInfo null = "); mEthManager.setConfiguration(mIfaceName, new IpConfiguration(ipAssignment, ProxySettings.NONE, mCurrentModeIsStatic ? mStaticIpConfiguration:null, null)); } } public boolean checkEthernetSettings() { boolean enable = false; mEthIpAddress = test_ip_et.getText().toString(); mEthGateway = test_gateway_et.getText().toString(); mEthdns1 = test_dns_et.getText().toString(); mEthNetmask = test_mask_et.getText().toString(); Pattern pattern = Pattern.compile("(^((\\d|[01]?\\d\\d|2[0-4]\\d|25[0-5])\\.){3}(\\d|[01]?\\d\\d|2[0-4]\\d|25[0-5])$)|^(\\d|[1-2]\\d|3[0-2])$"); /*check subnet mask*/ log(" ** checkEthernetSettings mEthIpAddress= " + mEthIpAddress + " , mEthGateway= " + mEthGateway + " , mEthdns1= " + mEthdns1 + " , mEthNetmask= " + mEthNetmask + " , isValidIpAddress mEthIpAddress= " + isValidIpAddress(mEthIpAddress) + " , isValidIpAddress mEthGateway= " + isValidIpAddress(mEthGateway) + " , isValidIpAddress mEthdns1= " + isValidIpAddress(mEthdns1) + " , matches= " + pattern.matcher(mEthNetmask).matches()); if (isValidIpAddress(mEthIpAddress) && isValidIpAddress(mEthGateway) && isValidIpAddress(mEthdns1) && (pattern.matcher(mEthNetmask).matches())) { enable = true; } else { enable = false; } if (mEthIpAddress != null && mEthGateway != null && mEthIpAddress.equals(mEthGateway)) { enable = false; } return enable; } private void setEthernetSettings() { log("setEthernetSettings = "); if(test_ip_set_static_rb.isChecked()){ if(checkEthernetSettings()){ if (setStaticIpConfiguration()) { mChangeTime = System.currentTimeMillis(); Settings.System.putString(mContext.getContentResolver() , "test_ip_way" , "static"); mCurrentModeIsStatic = true; mEthManager.setConfiguration(mIfaceName, mIpConfiguration); log("setEthernetSettings static is checked , setConfiguration static "); handleEtherStateChange(TestEthernetSettings.ETHERNET_STATE.ETHER_STATE_CONNECTING); setEthernetProxyInfo(); } else { Toast.makeText(mContext , R.string.test_ethernet_static_ip_setup_failed , Toast.LENGTH_LONG).show(); } } else{ Toast.makeText(mContext , R.string.test_ethernet_parameter_exception , Toast.LENGTH_LONG).show(); } }else if(test_ip_set_dhcp_rb.isChecked()){ log("setEthernetSettings dhcp is checked , setConfiguration DHCP "); Settings.System.putString(mContext.getContentResolver() , "test_ip_way" , "dhcp"); mCurrentModeIsStatic = false; mEthManager.setConfiguration(mIfaceName, new IpConfiguration(IpAssignment.DHCP, ProxySettings.NONE, null, null)); setEthernetProxyInfo(); } } private void setIPSettingMode(){ log("setIPSettingMode = "); if(test_ip_set_static_rb.isChecked()){ if(checkIPValue()){ if (setStaticIpConfiguration()) { mChangeTime = System.currentTimeMillis(); mEthManager.setConfiguration(mIfaceName, mIpConfiguration); handleEtherStateChange(TestEthernetSettings.ETHERNET_STATE.ETHER_STATE_CONNECTING); } else { Toast.makeText(mContext , R.string.test_ethernet_static_ip_setup_failed , Toast.LENGTH_LONG).show(); } }else{ log("setIPSettingMode setConfiguration DHCP= "); mEthManager.setConfiguration(mIfaceName, new IpConfiguration(IpAssignment.DHCP, ProxySettings.NONE, null, null)); } }else if(test_ip_set_dhcp_rb.isChecked()){ log("setIPSettingMode dhcp is checked , setConfiguration DHCP "); mEthManager.setConfiguration(mIfaceName, new IpConfiguration(IpAssignment.DHCP, ProxySettings.NONE, null, null)); } } private String getEthernetMacAddress() { BufferedReader reader = null; String ethernetMac =null; try { reader = new BufferedReader(new FileReader("sys/class/net/eth0/address")); ethernetMac = reader.readLine(); Log.v("hg", "ethernetMac: " + ethernetMac.toString()); } catch (Exception e) { Log.e("hg", "open sys/class/net/eth0/address failed : " + e); } finally { try { if (reader != null) reader.close(); } catch (IOException e) { Log.e("hg", "close sys/class/net/eth0/address failed : " + e); } } return ethernetMac.toString(); } public boolean checkIPValue() { boolean enable = false; mEthIpAddress = test_ip_et.getText().toString(); mEthGateway = test_gateway_et.getText().toString(); mEthdns1 = test_dns_et.getText().toString(); mEthNetmask = test_mask_et.getText().toString(); Pattern pattern = Pattern.compile("(^((\\d|[01]?\\d\\d|2[0-4]\\d|25[0-5])\\.){3}(\\d|[01]?\\d\\d|2[0-4]\\d|25[0-5])$)|^(\\d|[1-2]\\d|3[0-2])$"); /*check subnet mask*/ log(" ** checkIPValue mEthIpAddress= " + mEthIpAddress + " , mEthGateway= " + mEthGateway + " , mEthdns1= " + mEthdns1 + " , mEthNetmask= " + mEthNetmask + " , isValidIpAddress mEthIpAddress= " + isValidIpAddress(mEthIpAddress) + " , isValidIpAddress mEthGateway= " + isValidIpAddress(mEthGateway) + " , isValidIpAddress mEthdns1= " + isValidIpAddress(mEthdns1) + " , matches= " + pattern.matcher(mEthNetmask).matches()); if (isValidIpAddress(mEthIpAddress) && isValidIpAddress(mEthGateway) && isValidIpAddress(mEthdns1) && (pattern.matcher(mEthNetmask).matches())) { enable = true; } else { Toast.makeText(mContext , R.string.test_ethernet_parameter_exception , Toast.LENGTH_LONG).show(); enable = false; } return enable; } private Inet4Address getIPv4Address(String text) { try { return (Inet4Address) EthernetManager.testNumericToInetAddress(text); } catch (IllegalArgumentException | ClassCastException e) { return null; } } /* * 返回 指定的 String 是否是 有效的 IP 地址. */ private boolean isValidIpAddress(String value) { int start = 0; int end = value.indexOf('.'); int numBlocks = 0; if(nullIpInfo.equals(value)){ return false; } while (start 255) || (block 8 - remainder; i--) { sum = sum + (int) Math.pow(2, i - 1); } if (part == 0) { netMask = sum + ".0.0.0"; } else if (part == 1) { netMask = "255." + sum + ".0.0"; } else if (part == 2) { netMask = "255.255." + sum + ".0"; } else if (part == 3) { netMask = "255.255.255." + sum; } else if (part == 4) { netMask = "255.255.255.255"; } return netMask; } /* * convert subMask string to prefix length */ private int maskStr2InetMask(String maskStr) { StringBuffer sb; String str; int inetmask = 0; int count = 0; /* * check the subMask format */ Pattern pattern = Pattern.compile("(^((\\d|[01]?\\d\\d|2[0-4]\\d|25[0-5])\\.){3}(\\d|[01]?\\d\\d|2[0-4]\\d|25[0-5])$)|^(\\d|[1-2]\\d|3[0-2])$"); log("595 maskStr2InetMask pattern= " + pattern + " , maskStr= " + maskStr); if (pattern.matcher(maskStr).matches() == false) { Log.e(TAG, "subMask is error"); return 0; } String[] ipSegment = maskStr.split("\\."); for (int n = 0; n四、总结
至此关于android13以太网的功能介绍完毕,实际上博主认为技术分享应该是无私的,而并非作为牟利的工具,看到很多技术收费的文章,这其实对于自我的成长进步有很大的限制,微薄的利益回报并不值得,博主后续会继续更新对开发有益的文章,愿人人成为大神。