本文主要是介绍Android14 以太网共享功能 相关代码简介,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
Android14 以太网共享功能 相关代码简介
文章目录
- Android14 以太网共享功能 相关代码简介
- 一、前言
- 二、原生设置Settings中以太网相关代码
- 1、以太网显示布局代码
- 2、Java部分代码
- 2、以太网共享开关状态
- 3、以太网共享设置接口
- 三、其他
- 1、以太网共享小结
- 2、以太网开关的具体代码流程
- (1)ConnectivityManager.startTethering
- (2) ConnectivityManager
- (3)TetheringManager
- (4)ITetheringConnector
- (5)TetheringService
- (6)Tethering
- (7)EthernetManager
- (8)EthernetServiceImpl
- (8)EthernetTracker
- (9)NetdUtils
- (10)INetd
- 3、原生Settings中热点设置相关代码
- (1)Settings应用热点设置界面代码:
- (2)具体的热点开关api接口代码:
- 4、热点设置
- 5、Android13 有线网开关研究
一、前言
Android 的以太网共享功能是啥?
其实就是 Android设备接入一个网线后,再接入电脑,电脑就可以分配到到一个ip;
这里的Android 设备就相当于一个路由器。
如果Android设备可以正常上网,那么电脑也是可以上网的;
Android 的以太网共享功能简单的说就是把Android设备的网络通过网线的形式共享给其他设备。
Android手机设备基本没有网口,可以通过usb Hab转接网口;
一些调试用的Android 设备是保存有网口的,可以直接接入网线。
Android以太网共享功能并不是所有设备都支持,
支持有线网的正常使用的设备才能使用有线网共享功能。
也就是说插入路由器的网线接收到Android设备,Android设备能够自动获取ip;
这是Android设备是否支持有线网的前提。也是Android设备是否支持以太网共享的前提。
开启以太网共享的开关是在设置中和热点分享同级的界面。
同级目录下网络共享功能有:
热点
蓝牙网络共享
usb网络共享
以太网共享
上面的功能其实就是字面意思。
通过连接蓝牙共享网络;通过usb共享网络;通过网线共享网络。
但是很多Android 设备是没有这些功能的,有些系统是显示选项但是置灰了,有些系统是直接隐藏了功能选项。
本文主要分享一下Android14 以太网相关代码的,对于那些定制化修改以太网设置或者开发以太网的功能会有些帮助。
以太网设置在很多手机上是不显示的,有的手机在使用转接口接入网线后会显示该选项。
二、原生设置Settings中以太网相关代码
1、以太网显示布局代码
布局文件:
packages\apps\Settings\res\xml\tether_prefs.xml
<?xml version="1.0" encoding="utf-8"?><PreferenceScreenxmlns:android="http://schemas.android.com/apk/res/android"xmlns:settings="http://schemas.android.com/apk/res-auto"android:title="@string/tether_settings_title_all"><com.android.settingslib.widget.TopIntroPreferenceandroid:key="tether_prefs_top_intro"settings:searchable="false"/><com.android.settingslib.PrimarySwitchPreference //(1)热点android:key="wifi_tether"android:title="@string/wifi_hotspot_checkbox_text"android:summary="@string/wifi_hotspot_off_subtext"android:fragment="com.android.settings.wifi.tether.WifiTetherSettings"settings:allowDividerAbove="true"settings:maxLines="2"/>//(2)usb网络共享<com.android.settingslib.RestrictedSwitchPreference android:key="usb_tether_settings"android:title="@string/usb_tethering_button_text"android:summary="@string/usb_tethering_subtext"settings:keywords="@string/keywords_hotspot_tethering" />//(3)蓝牙网络共享<SwitchPreferenceandroid:key="enable_bluetooth_tethering"android:title="@string/bluetooth_tether_checkbox_text"android:summary="@string/bluetooth_tethering_subtext"settings:keywords="@string/keywords_hotspot_tethering" />//(3)以太网共享<SwitchPreferenceandroid:key="enable_ethernet_tethering"android:title="@string/ethernet_tether_checkbox_text"android:summary="@string/ethernet_tethering_subtext"settings:keywords="@string/keywords_hotspot_tethering" /><com.android.settingslib.widget.FooterPreferenceandroid:key="disabled_on_data_saver"android:title="@string/tether_settings_disabled_on_data_saver"android:selectable="false"settings:searchable="false"/>
</PreferenceScreen>
2、Java部分代码
packages\apps\Settings\src\com\android\settings\network\tether\TetherSettings.java
@SearchIndexable
public class TetherSettings extends RestrictedSettingsFragmentimplements DataSaverBackend.Listener {private ConnectivityManager mCm;@Overridepublic void onCreate(Bundle icicle) { // (1) 界面 onCreatesuper.onCreate(icicle);setupTetherPreference(); //绑定界面...//网络共享选项是否显示判断onDataSaverChanged(mDataSaverBackend.isDataSaverEnabled());}@VisibleForTestingvoid setupTetherPreference() { //(2)绑定mUsbTether = (RestrictedSwitchPreference) findPreference(KEY_USB_TETHER_SETTINGS);mBluetoothTether = (SwitchPreference) findPreference(KEY_ENABLE_BLUETOOTH_TETHERING);mEthernetTether = (SwitchPreference) findPreference(KEY_ENABLE_ETHERNET_TETHERING);}@Overridepublic void onStart() {super.onStart();...registerReceiver();//(3)广播监听updateUsbState();updateBluetoothAndEthernetState();}@VisibleForTestingvoid registerReceiver() { //(4)以太网共享状态监听final Activity activity = getActivity();mTetherChangeReceiver = new TetherChangeReceiver();IntentFilter filter = new IntentFilter(TetheringManager.ACTION_TETHER_STATE_CHANGED);final Intent intent = activity.registerReceiver(mTetherChangeReceiver, filter);//其他共享监听...}//(5)开关点击后回调,热点分享是其他地方处理@Overridepublic boolean onPreferenceTreeClick(Preference preference) {if (preference == mUsbTether) { //usb网络共享if (mUsbTether.isChecked()) {startTethering(TETHERING_USB);} else {mCm.stopTethering(TETHERING_USB);}} else if (preference == mBluetoothTether) { //蓝牙网络共享if (mBluetoothTether.isChecked()) {startTethering(TETHERING_BLUETOOTH);} else {mCm.stopTethering(TETHERING_BLUETOOTH);}} else if (preference == mEthernetTether) {//(6)以太网共享开关状态设置if (mEthernetTether.isChecked()) {startTethering(TETHERING_ETHERNET);} else {mCm.stopTethering(TETHERING_ETHERNET);//关闭}}return super.onPreferenceTreeClick(preference);}//(7)以太网共享,开启private void startTethering(int choice) {if (choice == TETHERING_BLUETOOTH) {//如果是蓝牙网络共享,需要先打开蓝牙// Turn on Bluetooth first.BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();if (adapter.getState() == BluetoothAdapter.STATE_OFF) {mBluetoothEnableForTether = true;adapter.enable();mBluetoothTether.setEnabled(false);return;}}//(8)开启共享mCm.startTethering(choice, true, mStartTetheringCallback, mHandler); }//(9)各种网络共享的广播监听private class TetherChangeReceiver extends BroadcastReceiver {@Overridepublic void onReceive(Context content, Intent intent) {String action = intent.getAction();if (DEBUG) {Log.d(TAG, "onReceive() action : " + action);}// TODO(b/194961339): Stop using ACTION_TETHER_STATE_CHANGED and use// mTetheringEventCallback instead.if (action.equals(TetheringManager.ACTION_TETHER_STATE_CHANGED)) { //以太网共享状态广播// TODO - this should understand the interface typesArrayList<String> available = intent.getStringArrayListExtra(TetheringManager.EXTRA_AVAILABLE_TETHER);ArrayList<String> active = intent.getStringArrayListExtra(TetheringManager.EXTRA_ACTIVE_TETHER);updateBluetoothState();Log.d(TAG, "onReceive() available = " + available + ", active = " + active);//(7)更新以太网状态updateEthernetState(available.toArray(new String[available.size()]),active.toArray(new String[active.size()]));}}}//(10)以太网共享开关状态更新@VisibleForTestingvoid updateEthernetState(String[] available, String[] tethered) {boolean isAvailable = false;boolean isTethered = false;for (String s : available) {if (mAvailableInterfaces.contains(s)) isAvailable = true;}for (String s : tethered) {if (mAvailableInterfaces.contains(s)) isTethered = true;}if (DEBUG) {Log.d(TAG, "updateEthernetState() isAvailable : " + isAvailable+ ", isTethered : " + isTethered);}//(11)只有tethered返回数据的情况,以太网开关才会是开启if (isTethered) {mEthernetTether.setEnabled(!mDataSaverEnabled);mEthernetTether.setChecked(true);} else if (mAvailableInterfaces.size() > 0) {mEthernetTether.setEnabled(!mDataSaverEnabled);mEthernetTether.setChecked(false);} else {mEthernetTether.setEnabled(false);mEthernetTether.setChecked(false);}}
上面就是以太网开关的主要相关代码。
主要就是界面初始化+点击事件监听处理+广播监听处理+状态更新,都在上面这个类。
USB网络共享、蓝牙网络共享的控制代码也是在上面这个类。
2、以太网共享开关状态
以太网开关状态,不像热点那样有api可以查询直接查询。
并且以太网共享开关,热点开关状态都是系统重启不记忆的;
如果要实现记忆,就要自己记忆状态,设备重启后,重新打开。
以太网状态查询就是通过监听广播,通过广播返回的数据判断
主要代码:
(1)注册广播mTetherChangeReceiver = new TetherChangeReceiver();IntentFilter filter = new IntentFilter(TetheringManager.ACTION_TETHER_STATE_CHANGED);final Intent intent = activity.registerReceiver(mTetherChangeReceiver, filter);(2)监听广播private class TetherChangeReceiver extends BroadcastReceiver {@Overridepublic void onReceive(Context content, Intent intent) {String action = intent.getAction();if (DEBUG) {Log.d(TAG, "onReceive() action : " + action);}if (action.equals(TetheringManager.ACTION_TETHER_STATE_CHANGED)) { //以太网共享状态广播// TODO - this should understand the interface typesArrayList<String> available = intent.getStringArrayListExtra(TetheringManager.EXTRA_AVAILABLE_TETHER);//只有这个activity是有用的ArrayList<String> active = intent.getStringArrayListExtra(TetheringManager.EXTRA_ACTIVE_TETHER);updateBluetoothState();Log.d(TAG, "onReceive() available = " + available + ", active = " + active);//(7)更新以太网状态updateEthernetState(available.toArray(new String[available.size()]),active.toArray(new String[active.size()]));}}}(3)更新状态void updateEthernetState(String[] available, String[] tethered) {boolean isAvailable = false;boolean isTethered = false;for (String s : tethered) {if (mAvailableInterfaces.contains(s)) isTethered = true;}//只有tethered返回数据的情况,以太网开关才会是开启if (isTethered) {mEthernetTether.setEnabled(!mDataSaverEnabled);mEthernetTether.setChecked(true);} else if (mAvailableInterfaces.size() > 0) {mEthernetTether.setEnabled(!mDataSaverEnabled);mEthernetTether.setChecked(false);} else {mEthernetTether.setEnabled(false);mEthernetTether.setChecked(false);}}
上面的代码看起来有点复杂,但是整理一下只要判断一种情况就行
ArrayList<String> active = intent.getStringArrayListExtra(TetheringManager.EXTRA_ACTIVE_TETHER);
//以太网共享是否开启:
boolean isEthernetShare = activite.size() > 0;
只要广播接收到当前可用的以太网共享节点数据是大于0 ,其实就是以太网开启的情况。
也许有些人会有疑问,以太网状态的广播,监听了就会有回调吗?
答案:是有的。
比如网络变化的广播也是一样的,只要监听了马上就会有回调。
但是也不是所有广播监听了就马上又回调,大部分广播监听了不会马上又回调的,
比如wifi开关、热点开关等广播,监听后是不会马上有回调的,需要开关状态改变后才有回调。
3、以太网共享设置接口
设置以太网就是api的调用:
ConnectivityManager mCm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);//开启以太网共享:mCm.startTethering(TetheringManager.TETHERING_ETHERNET, true, mStartTetheringCallback, mHandler); //关闭以太网共享:
mCm.stopTethering(TetheringManager.TETHERING_ETHERNET);
三、其他
1、以太网共享小结
(1)以太网共享开关状态是通过监听广播更新的;
只要监听了广播,就会有回调,开关状态修改,也会有回调;
(2)以太网共享开关使用对应的api就可以;
(3)以太网共享重启是不记忆的,如果需要记忆要自己适配;
(4)以太网共享功能,需要设备有线网可以使能的前提;
(5)以太网共享的节点是和有线网共用一个节点的
打开以太网共享后,有线网的节点会重新生成一个ip,用来做以太网共享功能;
大部分设备应该使用eth0节点,ifconfig 可以看到ip变化。
USB网络共享、蓝牙网络共享相关处理是类似的。
2、以太网开关的具体代码流程
这里简单追一下Android14以太网开启从应用到系统相关的调用流程代码:
(1)ConnectivityManager.startTethering
应用端的调用
//开启以太网共享:mCm.startTethering(TetheringManager.TETHERING_ETHERNET, true, mStartTetheringCallback, mHandler);
(2) ConnectivityManager
package\modules\Connectivity\framework\src\android\net\ConnectivityManager.java
public class ConnectivityManager {private static final String TAG = "ConnectivityManager";private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);public void startTethering(int type, boolean showProvisioningUi,final OnStartTetheringCallback callback, Handler handler) {Objects.requireNonNull(callback, "OnStartTetheringCallback cannot be null.");final Executor executor = new Executor() {@Overridepublic void execute(Runnable command) {if (handler == null) {command.run();} else {handler.post(command);}}};final StartTetheringCallback tetheringCallback = new StartTetheringCallback() {@Overridepublic void onTetheringStarted() {callback.onTetheringStarted();}@Overridepublic void onTetheringFailed(final int error) {callback.onTetheringFailed();}};final TetheringRequest request = new TetheringRequest.Builder(type).setShouldShowEntitlementUi(showProvisioningUi).build();getTetheringManager().startTethering(request, executor, tetheringCallback);}private TetheringManager getTetheringManager() {synchronized (mTetheringEventCallbacks) {if (mTetheringManager == null) {mTetheringManager = mContext.getSystemService(TetheringManager.class);}return mTetheringManager;}}}
热点也是这个类的api进行开关控制的。
Wifi是用WifiManager相关api的。
(3)TetheringManager
这个类是热点和其他分享网络的重要管理类。
package\modules\Connectivity\Tethering\common\TetheringLib\src\android\net\TetheringManager.java
@SystemApi
public class TetheringManager {private static final String TAG = TetheringManager.class.getSimpleName();private static final int DEFAULT_TIMEOUT_MS = 60_000;//各种网络共享的类型public static final int TETHERING_INVALID = -1;public static final int TETHERING_WIFI = 0;public static final int TETHERING_USB = 1;public static final int TETHERING_BLUETOOTH = 2;public static final int TETHERING_WIFI_P2P = 3;public static final int TETHERING_NCM = 4;public static final int TETHERING_ETHERNET = 5;public static final int TETHERING_WIGIG = 6;public static final int MAX_TETHERING_TYPE = TETHERING_WIGIG;public void startTethering(@NonNull final TetheringRequest request,@NonNull final Executor executor, @NonNull final StartTetheringCallback callback) {final String callerPkg = mContext.getOpPackageName();Log.i(TAG, "startTethering caller:" + callerPkg);final IIntResultListener listener = new IIntResultListener.Stub() {@Overridepublic void onResult(final int resultCode) {executor.execute(() -> {if (resultCode == TETHER_ERROR_NO_ERROR) {callback.onTetheringStarted();} else {callback.onTetheringFailed(resultCode);}});}};getConnector(c -> c.startTethering(request.getParcel(), callerPkg,getAttributionTag(), listener));}private void getConnector(ConnectorConsumer consumer) {final ITetheringConnector connector;synchronized (mConnectorWaitQueue) {connector = mConnector;if (connector == null) {mConnectorWaitQueue.add(consumer);return;}}try {consumer.onConnectorAvailable(connector);} catch (RemoteException e) {throw new IllegalStateException(e);}}}
上面可以看到很多其他相关网络类别的定义。
(4)ITetheringConnector
这个是接口定义,定义相关暴露的方法,aidl绑定服务用的。
package\modules\Connectivity\Tethering\common\TetheringLib\src\android\net\ITetheringConnector.aidl
oneway interface ITetheringConnector {void tether(String iface, String callerPkg, String callingAttributionTag,IIntResultListener receiver);void untether(String iface, String callerPkg, String callingAttributionTag,IIntResultListener receiver);void setUsbTethering(boolean enable, String callerPkg,String callingAttributionTag, IIntResultListener receiver);void startTethering(in TetheringRequestParcel request, String callerPkg,String callingAttributionTag, IIntResultListener receiver);void stopTethering(int type, String callerPkg, String callingAttributionTag,IIntResultListener receiver);
...
}
(5)TetheringService
热点等网络的服务实现
package\modules\Connectivity\Tethering\src\com\android\networkstack\tethering\TetheringService.java
@Overridepublic void startTethering(TetheringRequestParcel request, String callerPkg,String callingAttributionTag, IIntResultListener listener) {if (checkAndNotifyCommonError(callerPkg,callingAttributionTag,request.exemptFromEntitlementCheck /* onlyAllowPrivileged */,listener)) {return;}mTethering.startTethering(request, callerPkg, listener);}
wifi服务不在这里。
(6)Tethering
这个相当于一个工具类吧,调用相关服务或者管理类实现具体功能。
package\modules\Connectivity\Tethering\src\com\android\networkstack\tethering\Tethering.java
/**** This class holds much of the business logic to allow Android devices* to act as IP gateways via USB, BT, and WiFi interfaces.*/
public class Tethering {private static final String TAG = Tethering.class.getSimpleName();private static final boolean DBG = false;private static final boolean VDBG = false;void startTethering(final TetheringRequestParcel request, final String callerPkg,final IIntResultListener listener) {mHandler.post(() -> {final TetheringRequestParcel unfinishedRequest = mActiveTetheringRequests.get(request.tetheringType);// If tethering is already enabled with a different request,// disable before re-enabling.if (unfinishedRequest != null&& !TetheringUtils.isTetheringRequestEquals(unfinishedRequest, request)) {enableTetheringInternal(request.tetheringType, false /* disabled */, null);mEntitlementMgr.stopProvisioningIfNeeded(request.tetheringType);}mActiveTetheringRequests.put(request.tetheringType, request);if (request.exemptFromEntitlementCheck) {mEntitlementMgr.setExemptedDownstreamType(request.tetheringType);} else {mEntitlementMgr.startProvisioningIfNeeded(request.tetheringType,request.showProvisioningUi);}enableTetheringInternal(request.tetheringType, true /* enabled */, listener);mTetheringMetrics.createBuilder(request.tetheringType, callerPkg);});}private void enableTetheringInternal(int type, boolean enable,final IIntResultListener listener) {int result = TETHER_ERROR_NO_ERROR;switch (type) {case TETHERING_WIFI:result = setWifiTethering(enable);break;case TETHERING_USB:result = setUsbTethering(enable);break;case TETHERING_BLUETOOTH:setBluetoothTethering(enable, listener);break;case TETHERING_NCM:result = setNcmTethering(enable);break;case TETHERING_ETHERNET:result = setEthernetTethering(enable);break;default:Log.w(TAG, "Invalid tether type.");result = TETHER_ERROR_UNKNOWN_TYPE;}// The result of Bluetooth tethering will be sent by #setBluetoothTethering.if (type != TETHERING_BLUETOOTH) {sendTetherResult(listener, result, type);}}private int setEthernetTethering(final boolean enable) {final EthernetManager em = (EthernetManager) mContext.getSystemService(Context.ETHERNET_SERVICE);if (enable) {if (mEthernetCallback != null) {Log.d(TAG, "Ethernet tethering already started");return TETHER_ERROR_NO_ERROR;}mEthernetCallback = new EthernetCallback();mEthernetIfaceRequest = em.requestTetheredInterface(mExecutor, mEthernetCallback);} else {stopEthernetTethering();}return TETHER_ERROR_NO_ERROR;}}
(7)EthernetManager
这个是控制有线网的管理者。
package\modules\Connectivity\framework-t\src\android\net\EthernetManager.java
public class EthernetManager {private static final String TAG = "EthernetManager";private final IEthernetManager mService;public TetheredInterfaceRequest requestTetheredInterface(@NonNull final Executor executor,@NonNull final TetheredInterfaceCallback callback) {Objects.requireNonNull(callback, "Callback must be non-null");Objects.requireNonNull(executor, "Executor must be non-null");final ITetheredInterfaceCallback cbInternal = new ITetheredInterfaceCallback.Stub() {@Overridepublic void onAvailable(String iface) {executor.execute(() -> callback.onAvailable(iface));}@Overridepublic void onUnavailable() {executor.execute(() -> callback.onUnavailable());}};try {mService.requestTetheredInterface(cbInternal);} catch (RemoteException e) {throw e.rethrowFromSystemServer();}return new TetheredInterfaceRequest(mService, cbInternal);}}
有线网开关是通过 EthernetManager 进行控制的。
所以说以太网共享开关控制,兜兜转转,实际又回到了有线网控制的地方。
(8)EthernetServiceImpl
有线网控制的实现
package\modules\Connectivity\service-t\src\com\android\server\ethernet\EthernetServiceImpl.java
public class EthernetServiceImpl extends IEthernetManager.Stub {private static final String TAG = "EthernetServiceImpl";@Overridepublic void requestTetheredInterface(ITetheredInterfaceCallback callback) {Objects.requireNonNull(callback, "callback must not be null");PermissionUtils.enforceNetworkStackPermissionOr(mContext,android.Manifest.permission.NETWORK_SETTINGS);mTracker.requestTetheredInterface(callback);}}
(8)EthernetTracker
package\modules\Connectivity\service-t\src\com\android\server\ethernet\EthernetTracker.java
public void requestTetheredInterface(ITetheredInterfaceCallback callback) {mHandler.post(() -> {if (!mTetheredInterfaceRequests.register(callback)) {// Remote process has already diedreturn;}if (mTetheringInterfaceMode == INTERFACE_MODE_SERVER) {if (mTetheredInterfaceWasAvailable) {notifyTetheredInterfaceAvailable(callback, mTetheringInterface);}return;}setTetheringInterfaceMode(INTERFACE_MODE_SERVER);});}private void setTetheringInterfaceMode(int mode) {Log.d(TAG, "Setting tethering interface mode to " + mode);mTetheringInterfaceMode = mode;if (mTetheringInterface != null) {removeInterface(mTetheringInterface);addInterface(mTetheringInterface);// when this broadcast is sent, any calls to notifyTetheredInterfaceAvailable or// notifyTetheredInterfaceUnavailable have already happenedbroadcastInterfaceStateChange(mTetheringInterface);}}private void removeInterface(String iface) {mFactory.removeInterface(iface);maybeUpdateServerModeInterfaceState(iface, false);}private void addInterface(String iface) {InterfaceConfigurationParcel config = null;// Bring up the interface so we get link status indications.try {PermissionUtils.enforceNetworkStackPermission(mContext);// Read the flags before attempting to bring up the interface. If the interface is// already running an UP event is created after adding the interface.config = NetdUtils.getInterfaceConfigParcel(mNetd, iface);if (NetdUtils.hasFlag(config, INetd.IF_STATE_DOWN)) {// As a side-effect, NetdUtils#setInterfaceUp() also clears the interface's IPv4// address and readds it which *could* lead to unexpected behavior in the future.NetdUtils.setInterfaceUp(mNetd, iface);}} catch (IllegalStateException e) {// Either the system is crashing or the interface has disappeared. Just ignore the// error; we haven't modified any state because we only do that if our calls succeed.Log.e(TAG, "Error upping interface " + iface, e);}if (config == null) {Log.e(TAG, "Null interface config parcelable for " + iface + ". Bailing out.");return;}if (getInterfaceMode(iface) == INTERFACE_MODE_SERVER) {maybeUpdateServerModeInterfaceState(iface, true);return;}...}
(9)NetdUtils
这个其实就是一个工具类,用来控制节点开启、关闭等功能
framework\libs\net\client-libs\netd\com\android\net\module\util\NetdUtils.java
public class NetdUtils {private static final String TAG = NetdUtils.class.getSimpleName();public static void setInterfaceUp(INetd netd, String iface) {final InterfaceConfigurationParcel configParcel = getInterfaceConfigParcel(netd, iface);configParcel.flags = removeAndAddFlags(configParcel.flags, IF_STATE_DOWN /* remove */,IF_STATE_UP /* add */);setInterfaceConfig(netd, configParcel);}public static void setInterfaceConfig(INetd netd, InterfaceConfigurationParcel configParcel) {try {netd.interfaceSetCfg(configParcel);} catch (RemoteException | ServiceSpecificException e) {throw new IllegalStateException(e);}}}
(10)INetd
具体实现是通过 INetd,调用到底层。
framework\libs\net\common\netd\aidl_api\netd_aidl_interface\1\android\net\INetd.aidl
这里的 INetd 是有很多版本的,具体是哪个版本,要看系统硬件选择。
这里再往下就是HIDL的代码,就是cpp代码了,不再继续往下追踪了。
Wifi最终调用也是到IWifi,再到底层。
以太网共享开启的那个节点就是有线网那个节点。只是会重新配置ip信息。
3、原生Settings中热点设置相关代码
(1)Settings应用热点设置界面代码:
packages\apps\Settings\src\com\android\settings\wifi\tether\WifiTetherPreferenceController.java
public class WifiTetherPreferenceController extends AbstractPreferenceController ...{private static final String WIFI_TETHER_SETTINGS = "wifi_tether";@Overridepublic void displayPreference(PreferenceScreen screen) { //初始化super.displayPreference(screen);mPreference = screen.findPreference(WIFI_TETHER_SETTINGS);if (mPreference == null) {// unavailablereturn;}if (mSwitch == null) {mSwitch = new GenericSwitchController(mPreference);mSwitch.setListener(this);updateSwitch();}mPreference.setEnabled(canEnabled());if (!mIsWifiTetheringAllow) {mPreference.setSummary(R.string.not_allowed_by_ent);}}@Overridepublic boolean onSwitchToggled(boolean isChecked) { //开关回调if (isChecked) {mTetheringManagerModel.startTethering(TETHERING_WIFI);} else {mTetheringManagerModel.stopTethering(TETHERING_WIFI);}return true;}
(2)具体的热点开关api接口代码:
packages\apps\Settings\src\com\android\settings\network\tether\TetheringManagerModel.java
public class TetheringManagerModel extends AndroidViewModel {protected TetheringManager mTetheringManager;public TetheringManagerModel(@NonNull Application application) {super(application);mTetheringManager = application.getSystemService(TetheringManager.class);mTetheringManager.registerTetheringEventCallback(application.getMainExecutor(), mEventCallback);}//开启热点public void startTethering(int type) {mTetheringManager.startTethering(type, getApplication().getMainExecutor(),mStartTetheringCallback);}//关闭热点public void stopTethering(int type) {mTetheringManager.stopTethering(type);}}
4、热点设置
Android11 设置默认热点名称和热点密码、密码长度
https://blog.csdn.net/wenzhi20102321/article/details/127737534
5、Android13 有线网开关研究
https://blog.csdn.net/wenzhi20102321/article/details/131871354
这篇关于Android14 以太网共享功能 相关代码简介的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!