Android8.1 MTK平台 增加以太网静态IP功能

2024-08-22 06:38

本文主要是介绍Android8.1 MTK平台 增加以太网静态IP功能,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

前言

android 源码中一般都自带DHCP上网的,静态IP上网是没有的。这就需要我们自己添加了,

因为之前搞过6.0的静态IP功能,同样是 MTK 平台的,差异还是有点大的,

对比分析修改完成了需求,特此分享一下,避免更多的人踩坑。

如果这篇文章帮到你,欢迎点赞和转发,请注明原文地址

Android8.1

先上效果图,毕竟没图你说个锤子

在这里插入图片描述
动图

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

如图所示在 settings 中增加以太网的配置项

1、vendor\mediatek\proprietary\packages\apps\MtkSettings\res\xml\network_and_internet.xml

<com.android.settingslib.RestrictedPreferenceandroid:key="ethernet_settings"android:title="@string/ethernet_settings_title"android:summary="@string/summary_placeholder"android:icon="@drawable/ic_ethernet_cell"android:fragment="com.android.settings.ethernet.EthernetSettings"android:order="-17"/>

在 mobile_network_settings 和 tether_settings 之间增加如上代码

对应的 icon 资源文件是我从 SystemUI 中拷贝过来的,稍微调整了下大小,也贴给你们吧

2、vendor\mediatek\proprietary\packages\apps\MtkSettings\res\drawable\ic_ethernet_cell.xml

<vector xmlns:android="http://schemas.android.com/apk/res/android"android:autoMirrored="true"android:width="24dp"android:height="24dp"android:viewportWidth="48"android:viewportHeight="48"android:tint="?android:attr/colorControlNormal"><pathandroid:fillColor="#fff"android:pathData="M15.54 13.52l-3.08-2.55L1.64 24l10.82 13.04 3.08-2.55L6.84 24l8.7-10.48zM14 26h4v-4h-4v4zm20-4h-4v4h4v-4zm-12 4h4v-4h-4v4zm13.54-15.04l-3.08 2.55L41.16 24l-8.7 10.48 3.08 2.55L46.36 24 35.54 10.96z"/>
</vector>

vendor\mediatek\proprietary\packages\apps\MtkSettings\res\values\strings.xml

<string name="ethernet_ip_settings_invalid_ip">"Please fill in the correct format."</string>
<string name="eth_ip_settings_please_complete_settings">"Network information is not complete, please fill in the complete"</string>
<string name="save_satic_ethernet">"Save"</string>
<string name="enthernet_static">"Use static settings"</string>
<string name="enthernet_ip_address">"IP address"</string>
<string name="enthernet_gateway">"gateway"</string>
<string name="enthernet_netmask">"Subnet mask"</string>
<string name="enthernet_dns1">"domain1"</string>
<string name="enthernet_dns2">"domain2"</string>
<string name="ethernet_quick_toggle_title">"Ethernet"</string>
<string name="open_ethernet">"Open Ethernet"</string>
<string name="ethernet_static_ip_settings_title">"Setting Ethernet"</string>
<string name="ethernet_settings">"Ethernet"</string>
<string name="ethernet_settings_title">"Ethernet"</string>

vendor\mediatek\proprietary\packages\apps\MtkSettings\res\values-zh-rCN\strings.xml

<string name="ethernet_ip_settings_invalid_ip">"请填写正确的格式"</string>
<string name="save_satic_ethernet">"保存"</string>
<string name="eth_ip_settings_please_complete_settings">"网络信息不完整,请填写完整"</string>
<string name="enthernet_static">"使用静态设置"</string>
<string name="enthernet_ip_address">"IP地址"</string>
<string name="enthernet_gateway">"网关"</string>
<string name="enthernet_netmask">"子网掩码"</string>
<string name="enthernet_dns1">"域名1"</string>
<string name="enthernet_dns2">"域名2"</string>
<string name="ethernet_quick_toggle_title">"以太网"</string>
<string name="open_ethernet">"打开以太网"</string>
<string name="ethernet_static_ip_settings_title">"配置以太网"</string>
<string name="ethernet_settings">"以太网"</string>
<string name="ethernet_settings_title">"以太网"</string> 

3、增加对应设置的两个布局xml

vendor\mediatek\proprietary\packages\apps\MtkSettings\res\xml\ethernet_settings.xml

<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"android:title="@string/ethernet_settings"><SwitchPreferenceandroid:key="ethernet"android:title="@string/ethernet_quick_toggle_title"android:summary="@string/open_ethernet"/><PreferenceScreenandroid:dependency="ethernet"android:fragment="com.android.settings.ethernet.EthernetStaticIP"android:key="ethernet_static_ip"android:title="@string/ethernet_static_ip_settings_title" /></PreferenceScreen>

vendor\mediatek\proprietary\packages\apps\MtkSettings\res\xml\ethernet_static_ip.xml

	<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"android:title="@string/ethernet_static_ip_settings_title"><SwitchPreferenceandroid:key="use_static_ip"android:title="@string/enthernet_static"android:persistent="false"/>    <EditTextPreferenceandroid:dependency="use_static_ip"android:key="ip_address"android:title="@string/enthernet_ip_address"android:persistent="false"android:singleLine="true"/>    <EditTextPreferenceandroid:dependency="use_static_ip"android:key="gateway"android:title="@string/enthernet_gateway"android:persistent="false"android:singleLine="true"/>    <EditTextPreferenceandroid:dependency="use_static_ip"android:key="netmask"android:title="@string/enthernet_netmask"android:persistent="false"android:singleLine="true" />    <EditTextPreferenceandroid:dependency="use_static_ip"android:key="dns1"android:title="@string/enthernet_dns1"android:persistent="false"android:singleLine="true"/>    <EditTextPreferenceandroid:dependency="use_static_ip"android:key="dns2"android:title="@string/enthernet_dns2"android:persistent="false"android:singleLine="true"/>    </PreferenceScreen>

4、增加对应两个布局的 java 控制类

vendor\mediatek\proprietary\packages\apps\MtkSettings\src\com\android\settings\ethernet\EthernetSettings.java

package com.android.settings.ethernet;import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.BroadcastReceiver;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.os.Build;
import android.os.Bundle;
import android.os.SystemClock;
import android.os.SystemProperties;
import android.support.v7.preference.Preference;
import android.support.v7.preference.PreferenceGroup;
import android.support.v7.preference.PreferenceScreen;
import android.support.v7.preference.CheckBoxPreference;
import android.support.v14.preference.SwitchPreference;
import android.provider.Settings;
import android.provider.Settings.System;
import android.provider.Settings.Secure;
import android.util.Log;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import android.widget.Toast;import java.io.BufferedReader;
import java.io.FileReader;
import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.net.InetAddress;import android.net.EthernetManager;
import android.net.StaticIpConfiguration;
import android.net.LinkAddress;
import android.net.IpConfiguration;
import com.android.settings.SettingsPreferenceFragment;
import com.android.settings.R;public class EthernetSettings extends SettingsPreferenceFragment implements Preference.OnPreferenceChangeListener{private static final String TAG = "EthernetSettings";private static final String USE_ETHERNET_SETTINGS = "ethernet";public static final String IS_ETHERNET_OPEN = Settings.IS_ETHERNET_OPEN;	private SwitchPreference mUseEthernet;private IntentFilter mIntentFilter;private boolean isEthernetEnabled() {return Settings.System.getInt(getActivity().getContentResolver(), IS_ETHERNET_OPEN,0) == 1 ? true : false;}@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);addPreferencesFromResource(R.xml.ethernet_settings);mUseEthernet = (SwitchPreference) findPreference(USE_ETHERNET_SETTINGS);mUseEthernet.setOnPreferenceChangeListener(this);if(isEthernetEnabled()) {mUseEthernet.setChecked(true);} else {mUseEthernet.setChecked(false);}File f = new File("sys/class/net/eth0/address");if (f.exists()) {mUseEthernet.setEnabled(true);		} else {mUseEthernet.setEnabled(false);}}@Overridepublic void onResume() {super.onResume();}@Overridepublic int getMetricsCategory(){return MetricsEvent.ETHERNET;}@Overridepublic void onPause() {super.onPause();}	@Overridepublic boolean onPreferenceChange(Preference preference, Object value) {boolean result = true;final String key = preference.getKey();if (USE_ETHERNET_SETTINGS.equals(key)) {Settings.System.putInt(getActivity().getContentResolver(), IS_ETHERNET_OPEN, ((Boolean) value) ? 1 : 0);}return result;}}

vendor\mediatek\proprietary\packages\apps\MtkSettings\src\com\android\settings\ethernet\EthernetStaticIP.java

	package com.android.settings.ethernet;import android.app.Dialog;import android.content.DialogInterface;import android.content.Intent;import android.content.ContentResolver;import android.os.Bundle;import android.support.v7.preference.Preference;import android.preference.PreferenceActivity;import android.support.v7.preference.PreferenceScreen;import android.support.v7.preference.CheckBoxPreference;import android.support.v7.preference.EditTextPreference;import android.support.v14.preference.SwitchPreference;import android.provider.Settings;import android.provider.Settings.Secure;import android.util.Log;import android.view.ContextMenu;import android.view.Menu;import android.view.MenuInflater;import android.view.MenuItem;import android.view.View;import android.view.ContextMenu.ContextMenuInfo;import android.widget.AdapterView;import android.widget.Toast;import android.widget.AdapterView.AdapterContextMenuInfo;import android.text.TextUtils;import java.util.Set;import java.util.WeakHashMap;import java.util.Formatter;import java.net.InetAddress;import android.net.EthernetManager;import android.net.StaticIpConfiguration;import android.net.LinkAddress;import android.net.IpConfiguration;import android.net.IpConfiguration.IpAssignment;import android.net.IpConfiguration.ProxySettings;import android.net.NetworkInfo.DetailedState;import android.content.BroadcastReceiver;import android.content.IntentFilter;import android.content.Context;import android.net.NetworkInfo;import android.view.KeyEvent;import android.view.Menu;import android.view.MenuItem;import android.app.AlertDialog;import com.android.settings.SettingsPreferenceFragment;import com.android.settings.R;import com.android.internal.logging.nano.MetricsProto.MetricsEvent;public class EthernetStaticIP  extends SettingsPreferenceFragment implements Preference.OnPreferenceChangeListener {private static final String TAG = "EthernetStaticIP";public static final boolean DEBUG = false;private static void LOG(String msg) {if ( DEBUG ) {Log.d(TAG, msg);}}/*-------------------------------------------------------*/private static final String KEY_USE_STATIC_IP = "use_static_ip";private static final String KEY_IP_ADDRESS = "ip_address";private static final String KEY_GATEWAY = "gateway";private static final String KEY_NETMASK = "netmask";private static final String KEY_DNS1 = "dns1";private static final String KEY_DNS2 = "dns2";public static final String ETHERNET_USE_STATIC_IP = Settings.IS_ETHERNET_STATUC_OPEN;private static final int MENU_ITEM_SAVE = Menu.FIRST;private static final int MENU_ITEM_CANCEL = Menu.FIRST + 1;private String[] mSettingNames = {Settings.ETHERNET_STATIC_IP, Settings.ETHERNET_STATIC_GATEWAY,Settings.ETHERNET_STATIC_NETMASK,Settings.ETHERNET_STATIC_DNS1, Settings.ETHERNET_STATIC_DNS2};private String[] mPreferenceKeys = {KEY_IP_ADDRESS,KEY_GATEWAY,KEY_NETMASK,KEY_DNS1,KEY_DNS2,};/*-------------------------------------------------------*/private SwitchPreference mUseStaticIpSwitch;private StaticIpConfiguration mStaticIpConfiguration;private IpConfiguration mIpConfiguration;private EthernetManager mEthernetManager;private boolean isOnPause = false;private boolean chageState = false;public EthernetStaticIP() {}@Overridepublic void onActivityCreated(Bundle savedInstanceState){super.onActivityCreated(savedInstanceState);addPreferencesFromResource(R.xml.ethernet_static_ip);mUseStaticIpSwitch = (SwitchPreference)findPreference(KEY_USE_STATIC_IP);mUseStaticIpSwitch.setOnPreferenceChangeListener(this);for ( int i = 0; i < mPreferenceKeys.length; i++ ) {Preference preference = findPreference(mPreferenceKeys[i] );preference.setOnPreferenceChangeListener(this);}setHasOptionsMenu(true);}@Overridepublic void onResume() {super.onResume();if(!isOnPause) {updateIpSettingsInfo();}isOnPause = false;}@Overridepublic int getMetricsCategory(){return MetricsEvent.ETHERNET_STATIC;}    @Overridepublic void onPause() {isOnPause = true;super.onPause();}@Overridepublic void onDestroy() {super.onDestroy();}@Overridepublic void onSaveInstanceState(Bundle outState) {super.onSaveInstanceState(outState);}@Overridepublic void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {menu.add(Menu.NONE, MENU_ITEM_SAVE, 0, R.string.save_satic_ethernet).setEnabled(true).setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);super.onCreateOptionsMenu(menu, inflater);}@Overridepublic boolean onOptionsItemSelected(MenuItem item) {switch (item.getItemId()) {case MENU_ITEM_SAVE:saveIpSettingsInfo();if(isIpDataInUiComplete())finish();return true;case MENU_ITEM_CANCEL:finish();return true;}return super.onOptionsItemSelected(item);}        private void updateIpSettingsInfo() {LOG("Static IP status updateIpSettingsInfo");ContentResolver contentResolver = getContentResolver();mUseStaticIpSwitch.setChecked(Settings.System.getInt(contentResolver, ETHERNET_USE_STATIC_IP, 0) != 0);for (int i = 0; i < mSettingNames.length; i++) {EditTextPreference preference = (EditTextPreference) findPreference(mPreferenceKeys[i]);String settingValue = Settings.System.getString(contentResolver, mSettingNames[i]);preference.setText(settingValue);preference.setSummary(settingValue);}}private void saveIpSettingsInfo() {ContentResolver contentResolver = getContentResolver();/*      if(!chageState)   return;*/      if(!isIpDataInUiComplete()) {     Toast.makeText(getActivity(), R.string.eth_ip_settings_please_complete_settings, Toast.LENGTH_LONG).show();return;}mIpConfiguration = new IpConfiguration();mStaticIpConfiguration = new StaticIpConfiguration();for (int i = 0; i < mSettingNames.length; i++) {EditTextPreference preference = (EditTextPreference) findPreference(mPreferenceKeys[i]);String text = preference.getText();try {switch (mPreferenceKeys[i]) {case KEY_IP_ADDRESS:mStaticIpConfiguration.ipAddress = new LinkAddress(InetAddress.getByName(text), 24);break;case KEY_GATEWAY:mStaticIpConfiguration.gateway = InetAddress.getByName(text);break;case KEY_NETMASK:mStaticIpConfiguration.domains = text;break;case KEY_DNS1:mStaticIpConfiguration.dnsServers.add(InetAddress.getByName(text));break;case KEY_DNS2:mStaticIpConfiguration.dnsServers.add(InetAddress.getByName(text));break;	}            } catch (Exception e) {e.printStackTrace();}if ( null == text || TextUtils.isEmpty(text) ) {Settings.System.putString(contentResolver, mSettingNames[i], null);}else {Settings.System.putString(contentResolver, mSettingNames[i], text);}}mIpConfiguration.ipAssignment = IpAssignment.STATIC;mIpConfiguration.proxySettings = ProxySettings.STATIC;mIpConfiguration.staticIpConfiguration = mStaticIpConfiguration;	mEthernetManager = (EthernetManager) getSystemService(Context.ETHERNET_SERVICE);if (mUseStaticIpSwitch.isChecked())mEthernetManager.setConfiguration(mIpConfiguration); Settings.System.putInt(contentResolver,ETHERNET_USE_STATIC_IP, mUseStaticIpSwitch.isChecked() ? 1 : 0);// disable ethernetboolean enable = Secure.getInt(getContentResolver(), "isEnthernetOn", 1) == 1;LOG("notify Secure.ETHERNET_ON changed. enable = " + enable);if(enable) {LOG("first disable");Secure.putInt(getContentResolver(), "isEnthernetOn", 0);try {Thread.sleep(500);} catch (InterruptedException e) {}   LOG("second enable");Secure.putInt(getContentResolver(), "isEnthernetOn", 1);    	}}@Overridepublic boolean onPreferenceTreeClick(Preference preference) {boolean result = true;     LOG("onPreferenceTreeClick()  chageState = " + chageState);chageState = true;return result;}@Overridepublic boolean onPreferenceChange(Preference preference, Object newValue) {boolean result = true;String key = preference.getKey();LOG("onPreferenceChange() : key = " + key);if ( null == key ) {return true;}else if (key.equals(KEY_USE_STATIC_IP)) {}else if ( key.equals(KEY_IP_ADDRESS) || key.equals(KEY_GATEWAY)|| key.equals(KEY_NETMASK)|| key.equals(KEY_DNS1)|| key.equals(KEY_DNS2) ) { String value = (String) newValue;       LOG("onPreferenceChange() : value = " + value);if ( TextUtils.isEmpty(value) ) {( (EditTextPreference)preference).setText(value);preference.setSummary(value);result = true;}else  if ( !isValidIpAddress(value) ) {LOG("onPreferenceChange() : IP address user inputed is INVALID." );Toast.makeText(getActivity(), R.string.ethernet_ip_settings_invalid_ip, Toast.LENGTH_LONG).show();return false;}else {( (EditTextPreference)preference).setText(value);preference.setSummary(value);result = true;}}return result;}    private boolean isValidIpAddress(String value) {int start = 0;int end = value.indexOf('.');int numBlocks = 0;while (start < value.length()) {if ( -1 == end ) {end = value.length();}try {int block = Integer.parseInt(value.substring(start, end));if ((block > 255) || (block < 0)) {Log.w(TAG, "isValidIpAddress() : invalid 'block', block = " + block);return false;}} catch (NumberFormatException e) {Log.w(TAG, "isValidIpAddress() : e = " + e);return false;}numBlocks++;start = end + 1;end = value.indexOf('.', start);}return numBlocks == 4;}private boolean isIpDataInUiComplete() {ContentResolver contentResolver = getContentResolver();for (int i = 0; i < (mPreferenceKeys.length - 1); i++) {EditTextPreference preference = (EditTextPreference) findPreference(mPreferenceKeys[i]);String text = preference.getText();LOG("isIpDataInUiComplete() : text = " + text);if ( null == text || TextUtils.isEmpty(text) ) {return false;}}return true;}}

到这一步 Settings 的修改就完成了,就能实现上图的效果了,你可以mm push看效果了

如果你编译报错,大概是 Settings 中没有添加对应的变量,我的本来就有的,

没有的可参考下面的加一下

frameworks\base\core\java\android\provider\Settings.java

// Intent actions for Settings
// ethernet
public static final String ETHERNET_STATIC_IP = "ethernet_static_ip";
public static final String ETHERNET_STATIC_GATEWAY = "ethernet_static_gateway";
public static final String ETHERNET_STATIC_NETMASK = "ethernet_static_netmask";
public static final String ETHERNET_STATIC_DNS1 = "ethernet_static_dns1";
public static final String ETHERNET_STATIC_DNS2 = "ethernet_static_dns2";
public static final String IS_ETHERNET_OPEN = "isEthernetOpen";
public static final String IS_ETHERNET_STATUC_OPEN = "isEthernetStaticOpen";

加完后你需要先 make update-api成功后,在重新 mm 编译应该就好了

5、修改 framework 层网卡相关的控制代码

frameworks\opt\net\ethernet\java\com\android\server\ethernet\EthernetNetworkFactory.java

将原来的 startIpManager() 直接替换为如下的方法

public void startIpManager() {if (DBG) {Log.d(TAG, String.format("starting IpManager(%s): mNetworkInfo=%s", mIface,mNetworkInfo));}LinkProperties linkProperties;IpConfiguration config = mEthernetManager.getConfiguration();if (config.getIpAssignment() == IpAssignment.STATIC) {if (!setStaticIpAddress(config.getStaticIpConfiguration())) {// We've already logged an error.return;}linkProperties = config.getStaticIpConfiguration().toLinkProperties(mIface);if (config.getProxySettings() == ProxySettings.STATIC ||config.getProxySettings() == ProxySettings.PAC) {// mIpManager.setHttpProxy(config.getHttpProxy());linkProperties.setHttpProxy(config.getHttpProxy());}String tcpBufferSizes = mContext.getResources().getString(com.android.internal.R.string.config_ethernet_tcp_buffers);     if (TextUtils.isEmpty(tcpBufferSizes) == false) {linkProperties.setTcpBufferSizes(tcpBufferSizes);}} else {mNetworkInfo.setDetailedState(DetailedState.OBTAINING_IPADDR, null, mHwAddr);}IpManager.Callback ipmCallback = new IpManager.Callback() {@Overridepublic void onProvisioningSuccess(LinkProperties newLp) {mHandler.post(() -> onIpLayerStarted(newLp));}@Overridepublic void onProvisioningFailure(LinkProperties newLp) {mHandler.post(() -> onIpLayerStopped(newLp));}@Overridepublic void onLinkPropertiesChange(LinkProperties newLp) {mHandler.post(() -> updateLinkProperties(newLp));}};stopIpManager();mIpManager = new IpManager(mContext, mIface, ipmCallback);if (config.getProxySettings() == ProxySettings.STATIC ||config.getProxySettings() == ProxySettings.PAC) {mIpManager.setHttpProxy(config.getHttpProxy());}final String tcpBufferSizes = mContext.getResources().getString(com.android.internal.R.string.config_ethernet_tcp_buffers);if (!TextUtils.isEmpty(tcpBufferSizes)) {mIpManager.setTcpBufferSizes(tcpBufferSizes);}if (config.getIpAssignment() == IpAssignment.STATIC) {mIpManager.startProvisioning(config.getStaticIpConfiguration());} else {final ProvisioningConfiguration provisioningConfiguration =mIpManager.buildProvisioningConfiguration().withProvisioningTimeoutMs(0).build();mIpManager.startProvisioning(provisioningConfiguration);}
}

frameworks\opt\net\ethernet\java\com\android\server\ethernet\EthernetServiceImpl.java

在 EthernetServiceImpl 中增加网卡开关和静态IP开关的监听处理

 	private final EthernetOpenedObserver mOpenObserver = new EthernetOpenedObserver();private final EthernetStaticObserver mStaticObserver = new EthernetStaticObserver();public EthernetServiceImpl(Context context) {.....mContext.getContentResolver().registerContentObserver(System.getUriFor(IS_ETHERNET_OPEN), false, mOpenObserver);mContext.getContentResolver().registerContentObserver(System.getUriFor(ETHERNET_USE_STATIC_IP), false, mStaticObserver);    }private void enforceChangePermission() {mContext.enforceCallingOrSelfPermission(android.Manifest.permission.CHANGE_NETWORK_STATE,"EthernetService");}@Overridepublic void setConfiguration(IpConfiguration config) {if (!mStarted.get()) {Log.w(TAG, "System isn't ready enough to change ethernet configuration");}enforceChangePermission();  enforceConnectivityInternalPermission();.....}private boolean isStatic(){return Settings.System.getInt(mContext.getContentResolver(),ETHERNET_USE_STATIC_IP,0) ==1;}	private int getState(){return Settings.System.getInt(mContext.getContentResolver(), IS_ETHERNET_OPEN,0);}private final class EthernetOpenedObserver extends ContentObserver {public EthernetOpenedObserver() {super(new Handler());}@Overridepublic void onChange(boolean selfChange, Uri uri, int userId) {super.onChange(selfChange, uri, userId);Log.i(TAG, "EthernetServiceImpl isEthernetOpen onChange....");if (getState() == 1) {if (isStatic()) {StaticIpConfiguration staticIpConfiguration = new StaticIpConfiguration();staticIpConfiguration.domains = Settings.System.getString(mContext.getContentResolver(),Settings.ETHERNET_STATIC_NETMASK);try {staticIpConfiguration.gateway = InetAddress.getByName(Settings.System.getString(mContext.getContentResolver(),Settings.ETHERNET_STATIC_GATEWAY));staticIpConfiguration.ipAddress = new LinkAddress(InetAddress.getByName(Settings.System.getString(mContext.getContentResolver(),Settings.ETHERNET_STATIC_IP)), 24);staticIpConfiguration.dnsServers.add(InetAddress.getByName(Settings.System.getString(mContext.getContentResolver(),Settings.ETHERNET_STATIC_DNS1)));staticIpConfiguration.dnsServers.add(InetAddress.getByName(Settings.System.getString(mContext.getContentResolver(),Settings.ETHERNET_STATIC_DNS2)));}catch (Exception e){e.printStackTrace();}mIpConfiguration.staticIpConfiguration = staticIpConfiguration;}mStarted.set(true);mTracker.start(mContext, mHandler);} else {	mTracker.stop(); 		}}
}private final class EthernetStaticObserver extends ContentObserver {public EthernetStaticObserver() {super(new Handler());}@Overridepublic void onChange(boolean selfChange, Uri uri, int userId) {super.onChange(selfChange, uri, userId);Log.i(TAG, "EthernetServiceImpl isEthernetStaticOpen onChange....");if (!isStatic()) {mIpConfiguration = mEthernetConfigStore.readIpAndProxyConfigurations();mTracker.stop();mStarted.set(true);mTracker.start(mContext, mHandler);           }  }}

好了,到此就搞定了动图的效果了,开关以太网和设置静态IP上网,下面我们再来瞅瞅 6.0的有啥区别

Android6.0

效果图和上面的一样,这里就省略了,Settings 的修改和上面的一样,有两个细小的

区别就是

1、导包需要注意,EthernetSettings 和 EthernetStaticIP 中的 Preference

相关的包,在8.1中都换成了 support.v7 下面的,6.0 还是用原来的 android.preference

2、6.0 中的 MetricsLogger.ETHERNET 和 MetricsLogger.ETHERNET_STATIC

在8.1中替换为 MetricsEvent.ETHERNET 和 MetricsEvent.ETHERNET_STATIC

导包 com.android.internal.logging.MetricsLogger

frameworks/base/proto/src/metrics_constants.proto

      ETHERNET = 1144;ETHERNET_STATIC = 1145;

framework 方面的差异

EthernetServiceImpl.java 文件和 8.1 的一样,主要差别在 EthernetNetworkFactory.java

相比较而言没有 8.1 的复杂,下面贴一下完整的代码

frameworks\opt\net\ethernet\java\com\android\server\ethernet\EthernetNetworkFactory.java

class EthernetNetworkFactory {private static final String NETWORK_TYPE = "Ethernet";private static final String TAG = "EthernetNetworkFactory";private static final int NETWORK_SCORE = 110;private static final boolean DBG = true;public static final String ETHERNET_USE_STATIC_IP = Settings.IS_ETHERNET_STATUC_OPEN;/** Tracks interface changes. Called from NetworkManagementService. */private InterfaceObserver mInterfaceObserver;/** For static IP configuration */private EthernetManager mEthernetManager;/** To set link state and configure IP addresses. */private INetworkManagementService mNMService;/* To communicate with ConnectivityManager */private NetworkCapabilities mNetworkCapabilities;private NetworkAgent mNetworkAgent;private LocalNetworkFactory mFactory;private Context mContext;/** Product-dependent regular expression of interface names we track. */private static String mIfaceMatch = "";/** To notify Ethernet status. */private final RemoteCallbackList<IEthernetServiceListener> mListeners;/** Data members. All accesses to these must be synchronized(this). */private static String mIface = "";private String mHwAddr;private static boolean mLinkUp;private NetworkInfo mNetworkInfo;private LinkProperties mLinkProperties;EthernetNetworkFactory(RemoteCallbackList<IEthernetServiceListener> listeners) {mNetworkInfo = new NetworkInfo(ConnectivityManager.TYPE_ETHERNET, 0, NETWORK_TYPE, "");mLinkProperties = new LinkProperties();initNetworkCapabilities();mListeners = listeners;}private class LocalNetworkFactory extends NetworkFactory {LocalNetworkFactory(String name, Context context, Looper looper) {super(looper, context, name, new NetworkCapabilities());}protected void startNetwork() {onRequestNetwork();}protected void stopNetwork() {}}/*** Updates interface state variables.* Called on link state changes or on startup.*/private void updateInterfaceState(String iface, boolean up) {if (!mIface.equals(iface)) {return;}Log.d(TAG, "updateInterface: " + iface + " link " + (up ? "up" : "down"));synchronized(this) {mLinkUp = up;mNetworkInfo.setIsAvailable(up);if (!up) {// Tell the agent we're disconnected. It will call disconnect().mNetworkInfo.setDetailedState(DetailedState.DISCONNECTED, null, mHwAddr);}updateAgent();// set our score lower than any network could go// so we get dropped.  TODO - just unregister the factory// when link goes down.mFactory.setScoreFilter(up ? NETWORK_SCORE : -1);}}private class InterfaceObserver extends BaseNetworkObserver {@Overridepublic void interfaceLinkStateChanged(String iface, boolean up) {updateInterfaceState(iface, up);}@Overridepublic void interfaceAdded(String iface) {maybeTrackInterface(iface);}@Overridepublic void interfaceRemoved(String iface) {stopTrackingInterface(iface);}}private void setInterfaceUp(String iface) {// Bring up the interface so we get link status indications.try {NetworkUtils.stopDhcp(iface);mNMService.setInterfaceUp(iface);String hwAddr = null;InterfaceConfiguration config = mNMService.getInterfaceConfig(iface);if (config == null) {Log.e(TAG, "Null iterface config for " + iface + ". Bailing out.");return;}synchronized (this) {if (!isTrackingInterface()) {setInterfaceInfoLocked(iface, config.getHardwareAddress());mNetworkInfo.setIsAvailable(true);mNetworkInfo.setExtraInfo(mHwAddr);} else {Log.e(TAG, "Interface unexpectedly changed from " + iface + " to " + mIface);mNMService.setInterfaceDown(iface);}}} catch (RemoteException e) {Log.e(TAG, "Error upping interface " + mIface + ": " + e);}}private boolean maybeTrackInterface(String iface) {// If we don't already have an interface, and if this interface matches// our regex, start tracking it.if (!iface.matches(mIfaceMatch) || isTrackingInterface())return false;Log.d(TAG, "Started tracking interface " + iface);setInterfaceUp(iface);return true;}private void stopTrackingInterface(String iface) {if (!iface.equals(mIface))return;Log.d(TAG, "Stopped tracking interface " + iface);// TODO: Unify this codepath with stop().synchronized (this) {NetworkUtils.stopDhcp(mIface);setInterfaceInfoLocked("", null);mNetworkInfo.setExtraInfo(null);mLinkUp = false;mNetworkInfo.setDetailedState(DetailedState.DISCONNECTED, null, mHwAddr);updateAgent();mNetworkAgent = null;mNetworkInfo = new NetworkInfo(ConnectivityManager.TYPE_ETHERNET, 0, NETWORK_TYPE, "");mLinkProperties = new LinkProperties();}}private boolean setStaticIpAddress(StaticIpConfiguration staticConfig) {if (staticConfig!=null && staticConfig.ipAddress != null &&staticConfig.gateway != null &&staticConfig.dnsServers.size() > 0) {try {Log.i(TAG, "Applying static IPv4 configuration to " + mIface + ": " + staticConfig);InterfaceConfiguration config = mNMService.getInterfaceConfig(mIface);config.setLinkAddress(staticConfig.ipAddress);mNMService.setInterfaceConfig(mIface, config);return true;} catch(RemoteException|IllegalStateException e) {Log.e(TAG, "Setting static IP address failed: " + e.getMessage());}} else {Log.e(TAG, "Invalid static IP configuration.");}return false;}public void updateAgent() {synchronized (EthernetNetworkFactory.this) {if (mNetworkAgent == null) return;if (DBG) {Log.i(TAG, "Updating mNetworkAgent with: " +mNetworkCapabilities + ", " +mNetworkInfo + ", " +mLinkProperties);}mNetworkAgent.sendNetworkCapabilities(mNetworkCapabilities);mNetworkAgent.sendNetworkInfo(mNetworkInfo);mNetworkAgent.sendLinkProperties(mLinkProperties);// never set the network score below 0.mNetworkAgent.sendNetworkScore(mLinkUp? NETWORK_SCORE : 0);}}/* Called by the NetworkFactory on the handler thread. */public void onRequestNetwork() {// TODO: Handle DHCP renew.Thread dhcpThread = new Thread(new Runnable() {public void run() {if (DBG) Log.i(TAG, "dhcpThread(" + mIface + "): mNetworkInfo=" + mNetworkInfo);LinkProperties linkProperties;IpConfiguration config = mEthernetManager.getConfiguration();/*  if (config.getIpAssignment() == IpAssignment.STATIC) */if (isStatic()){if (!setStaticIpAddress(config.getStaticIpConfiguration())) {// We've already logged an error.return;}linkProperties = config.getStaticIpConfiguration().toLinkProperties(mIface);} else {mNetworkInfo.setDetailedState(DetailedState.OBTAINING_IPADDR, null, mHwAddr);DhcpResults dhcpResults = new DhcpResults();// TODO: Handle DHCP renewals better.// In general runDhcp handles DHCP renewals for us, because// the dhcp client stays running, but if the renewal fails,// we will lose our IP address and connectivity without// noticing.if (!NetworkUtils.runDhcp(mIface, dhcpResults)) {Log.e(TAG, "DHCP request error:" + NetworkUtils.getDhcpError());// set our score lower than any network could go// so we get dropped.mFactory.setScoreFilter(-1);// If DHCP timed out (as opposed to failing), the DHCP client will still be// running, because in M we changed its timeout to infinite. Stop it now.NetworkUtils.stopDhcp(mIface);return;}linkProperties = dhcpResults.toLinkProperties(mIface);}if (config.getProxySettings() == ProxySettings.STATIC ||config.getProxySettings() == ProxySettings.PAC) {linkProperties.setHttpProxy(config.getHttpProxy());}String tcpBufferSizes = mContext.getResources().getString(com.android.internal.R.string.config_ethernet_tcp_buffers);if (TextUtils.isEmpty(tcpBufferSizes) == false) {linkProperties.setTcpBufferSizes(tcpBufferSizes);}synchronized(EthernetNetworkFactory.this) {if (mNetworkAgent != null) {Log.e(TAG, "Already have a NetworkAgent - aborting new request");return;}mLinkProperties = linkProperties;mNetworkInfo.setIsAvailable(true);mNetworkInfo.setDetailedState(DetailedState.CONNECTED, null, mHwAddr);// Create our NetworkAgent.mNetworkAgent = new NetworkAgent(mFactory.getLooper(), mContext,NETWORK_TYPE, mNetworkInfo, mNetworkCapabilities, mLinkProperties,NETWORK_SCORE) {public void unwanted() {synchronized(EthernetNetworkFactory.this) {if (this == mNetworkAgent) {NetworkUtils.stopDhcp(mIface);mLinkProperties.clear();mNetworkInfo.setDetailedState(DetailedState.DISCONNECTED, null,mHwAddr);updateAgent();mNetworkAgent = null;try {mNMService.clearInterfaceAddresses(mIface);} catch (Exception e) {Log.e(TAG, "Failed to clear addresses or disable ipv6" + e);}} else {Log.d(TAG, "Ignoring unwanted as we have a more modern " +"instance");}}};};}}});dhcpThread.start();}/*** Begin monitoring connectivity*/public synchronized void start(Context context, Handler target) {// The services we use.IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE);mNMService = INetworkManagementService.Stub.asInterface(b);mEthernetManager = (EthernetManager) context.getSystemService(Context.ETHERNET_SERVICE);// Interface match regex.mIfaceMatch = context.getResources().getString(com.android.internal.R.string.config_ethernet_iface_regex);// Create and register our NetworkFactory.mFactory = new LocalNetworkFactory(NETWORK_TYPE, context, target.getLooper());mFactory.setCapabilityFilter(mNetworkCapabilities);mFactory.setScoreFilter(-1); // this set high when we have an ifacemFactory.register();mContext = context;// Start tracking interface change events.mInterfaceObserver = new InterfaceObserver();try {mNMService.registerObserver(mInterfaceObserver);} catch (RemoteException e) {Log.e(TAG, "Could not register InterfaceObserver " + e);}// If an Ethernet interface is already connected, start tracking that.// Otherwise, the first Ethernet interface to appear will be tracked.try {final String[] ifaces = mNMService.listInterfaces();for (String iface : ifaces) {synchronized(this) {if (maybeTrackInterface(iface)) {// We have our interface. Track it.// Note: if the interface already has link (e.g., if we// crashed and got restarted while it was running),// we need to fake a link up notification so we start// configuring it. Since we're already holding the lock,// any real link up/down notification will only arrive// after we've done this.if (mNMService.getInterfaceConfig(iface).hasFlag("running")) {updateInterfaceState(iface, true);}break;}}}} catch (RemoteException e) {Log.e(TAG, "Could not get list of interfaces " + e);}}public synchronized void stop() {NetworkUtils.stopDhcp(mIface);// ConnectivityService will only forget our NetworkAgent if we send it a NetworkInfo object// with a state of DISCONNECTED or SUSPENDED. So we can't simply clear our NetworkInfo here:// that sets the state to IDLE, and ConnectivityService will still think we're connected.//// TODO: stop using explicit comparisons to DISCONNECTED / SUSPENDED in ConnectivityService,// and instead use isConnectedOrConnecting().mNetworkInfo.setDetailedState(DetailedState.DISCONNECTED, null, mHwAddr);mLinkUp = false;updateAgent();mLinkProperties = new LinkProperties();mNetworkAgent = null;setInterfaceInfoLocked("", null);mNetworkInfo = new NetworkInfo(ConnectivityManager.TYPE_ETHERNET, 0, NETWORK_TYPE, "");mFactory.unregister();}private void initNetworkCapabilities() {mNetworkCapabilities = new NetworkCapabilities();mNetworkCapabilities.addTransportType(NetworkCapabilities.TRANSPORT_ETHERNET);mNetworkCapabilities.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET);mNetworkCapabilities.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED);// We have no useful data on bandwidth. Say 100M up and 100M down. :-(mNetworkCapabilities.setLinkUpstreamBandwidthKbps(100 * 1000);mNetworkCapabilities.setLinkDownstreamBandwidthKbps(100 * 1000);}public synchronized boolean isTrackingInterface() {return !TextUtils.isEmpty(mIface);}/*** Set interface information and notify listeners if availability is changed.* This should be called with the lock held.*/private void setInterfaceInfoLocked(String iface, String hwAddr) {boolean oldAvailable = isTrackingInterface();mIface = iface;mHwAddr = hwAddr;boolean available = isTrackingInterface();if (oldAvailable != available) {int n = mListeners.beginBroadcast();for (int i = 0; i < n; i++) {try {mListeners.getBroadcastItem(i).onAvailabilityChanged(available);} catch (RemoteException e) {// Do nothing here.}}mListeners.finishBroadcast();}}synchronized void dump(FileDescriptor fd, IndentingPrintWriter pw, String[] args) {if (isTrackingInterface()) {pw.println("Tracking interface: " + mIface);pw.increaseIndent();pw.println("MAC address: " + mHwAddr);pw.println("Link state: " + (mLinkUp ? "up" : "down"));pw.decreaseIndent();} else {pw.println("Not tracking any interface");}pw.println();pw.println("NetworkInfo: " + mNetworkInfo);pw.println("LinkProperties: " + mLinkProperties);pw.println("NetworkAgent: " + mNetworkAgent);}/*private boolean isStatic()*/private boolean isStatic(){return Settings.System.getInt(mContext.getContentResolver(),ETHERNET_USE_STATIC_IP,0) ==1;}	
}

修改文件源码下载

android 8.1添加Ethernet功能(settings+framework).zip

这篇关于Android8.1 MTK平台 增加以太网静态IP功能的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1095526

相关文章

流媒体平台/视频监控/安防视频汇聚EasyCVR播放暂停后视频画面黑屏是什么原因?

视频智能分析/视频监控/安防监控综合管理系统EasyCVR视频汇聚融合平台,是TSINGSEE青犀视频垂直深耕音视频流媒体技术、AI智能技术领域的杰出成果。该平台以其强大的视频处理、汇聚与融合能力,在构建全栈视频监控系统中展现出了独特的优势。视频监控管理系统EasyCVR平台内置了强大的视频解码、转码、压缩等技术,能够处理多种视频流格式,并以多种格式(RTMP、RTSP、HTTP-FLV、WebS

综合安防管理平台LntonAIServer视频监控汇聚抖动检测算法优势

LntonAIServer视频质量诊断功能中的抖动检测是一个专门针对视频稳定性进行分析的功能。抖动通常是指视频帧之间的不必要运动,这种运动可能是由于摄像机的移动、传输中的错误或编解码问题导致的。抖动检测对于确保视频内容的平滑性和观看体验至关重要。 优势 1. 提高图像质量 - 清晰度提升:减少抖动,提高图像的清晰度和细节表现力,使得监控画面更加真实可信。 - 细节增强:在低光条件下,抖

C++11第三弹:lambda表达式 | 新的类功能 | 模板的可变参数

🌈个人主页: 南桥几晴秋 🌈C++专栏: 南桥谈C++ 🌈C语言专栏: C语言学习系列 🌈Linux学习专栏: 南桥谈Linux 🌈数据结构学习专栏: 数据结构杂谈 🌈数据库学习专栏: 南桥谈MySQL 🌈Qt学习专栏: 南桥谈Qt 🌈菜鸡代码练习: 练习随想记录 🌈git学习: 南桥谈Git 🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈�

JAVA智听未来一站式有声阅读平台听书系统小程序源码

智听未来,一站式有声阅读平台听书系统 🌟&nbsp;开篇:遇见未来,从“智听”开始 在这个快节奏的时代,你是否渴望在忙碌的间隙,找到一片属于自己的宁静角落?是否梦想着能随时随地,沉浸在知识的海洋,或是故事的奇幻世界里?今天,就让我带你一起探索“智听未来”——这一站式有声阅读平台听书系统,它正悄悄改变着我们的阅读方式,让未来触手可及! 📚&nbsp;第一站:海量资源,应有尽有 走进“智听

让树莓派智能语音助手实现定时提醒功能

最初的时候是想直接在rasa 的chatbot上实现,因为rasa本身是带有remindschedule模块的。不过经过一番折腾后,忽然发现,chatbot上实现的定时,语音助手不一定会有响应。因为,我目前语音助手的代码设置了长时间无应答会结束对话,这样一来,chatbot定时提醒的触发就不会被语音助手获悉。那怎么让语音助手也具有定时提醒功能呢? 我最后选择的方法是用threading.Time

如何解决线上平台抽佣高 线下门店客流少的痛点!

目前,许多传统零售店铺正遭遇客源下降的难题。尽管广告推广能带来一定的客流,但其费用昂贵。鉴于此,众多零售商纷纷选择加入像美团、饿了么和抖音这样的大型在线平台,但这些平台的高佣金率导致了利润的大幅缩水。在这样的市场环境下,商家之间的合作网络逐渐成为一种有效的解决方案,通过资源和客户基础的共享,实现共同的利益增长。 以最近在上海兴起的一个跨行业合作平台为例,该平台融合了环保消费积分系统,在短

Android平台播放RTSP流的几种方案探究(VLC VS ExoPlayer VS SmartPlayer)

技术背景 好多开发者需要遴选Android平台RTSP直播播放器的时候,不知道如何选的好,本文针对常用的方案,做个大概的说明: 1. 使用VLC for Android VLC Media Player(VLC多媒体播放器),最初命名为VideoLAN客户端,是VideoLAN品牌产品,是VideoLAN计划的多媒体播放器。它支持众多音频与视频解码器及文件格式,并支持DVD影音光盘,VCD影

【区块链 + 人才服务】区块链集成开发平台 | FISCO BCOS应用案例

随着区块链技术的快速发展,越来越多的企业开始将其应用于实际业务中。然而,区块链技术的专业性使得其集成开发成为一项挑战。针对此,广东中创智慧科技有限公司基于国产开源联盟链 FISCO BCOS 推出了区块链集成开发平台。该平台基于区块链技术,提供一套全面的区块链开发工具和开发环境,支持开发者快速开发和部署区块链应用。此外,该平台还可以提供一套全面的区块链开发教程和文档,帮助开发者快速上手区块链开发。

K8S(Kubernetes)开源的容器编排平台安装步骤详解

K8S(Kubernetes)是一个开源的容器编排平台,用于自动化部署、扩展和管理容器化应用程序。以下是K8S容器编排平台的安装步骤、使用方式及特点的概述: 安装步骤: 安装Docker:K8S需要基于Docker来运行容器化应用程序。首先要在所有节点上安装Docker引擎。 安装Kubernetes Master:在集群中选择一台主机作为Master节点,安装K8S的控制平面组件,如AP

Spring框架5 - 容器的扩展功能 (ApplicationContext)

private static ApplicationContext applicationContext;static {applicationContext = new ClassPathXmlApplicationContext("bean.xml");} BeanFactory的功能扩展类ApplicationContext进行深度的分析。ApplicationConext与 BeanF