Android14 以太网共享功能 相关代码简介

2024-08-25 21:20

本文主要是介绍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 以太网共享功能 相关代码简介的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

python实现pdf转word和excel的示例代码

《python实现pdf转word和excel的示例代码》本文主要介绍了python实现pdf转word和excel的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价... 目录一、引言二、python编程1,PDF转Word2,PDF转Excel三、前端页面效果展示总结一

在MyBatis的XML映射文件中<trim>元素所有场景下的完整使用示例代码

《在MyBatis的XML映射文件中<trim>元素所有场景下的完整使用示例代码》在MyBatis的XML映射文件中,trim元素用于动态添加SQL语句的一部分,处理前缀、后缀及多余的逗号或连接符,示... 在MyBATis的XML映射文件中,<trim>元素用于动态地添加SQL语句的一部分,例如SET或W

Go语言实现将中文转化为拼音功能

《Go语言实现将中文转化为拼音功能》这篇文章主要为大家详细介绍了Go语言中如何实现将中文转化为拼音功能,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 有这么一个需求:新用户入职 创建一系列账号比较麻烦,打算通过接口传入姓名进行初始化。想把姓名转化成拼音。因为有些账号即需要中文也需要英

关于Maven生命周期相关命令演示

《关于Maven生命周期相关命令演示》Maven的生命周期分为Clean、Default和Site三个主要阶段,每个阶段包含多个关键步骤,如清理、编译、测试、打包等,通过执行相应的Maven命令,可以... 目录1. Maven 生命周期概述1.1 Clean Lifecycle1.2 Default Li

numpy求解线性代数相关问题

《numpy求解线性代数相关问题》本文主要介绍了numpy求解线性代数相关问题,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧... 在numpy中有numpy.array类型和numpy.mat类型,前者是数组类型,后者是矩阵类型。数组

使用C#代码计算数学表达式实例

《使用C#代码计算数学表达式实例》这段文字主要讲述了如何使用C#语言来计算数学表达式,该程序通过使用Dictionary保存变量,定义了运算符优先级,并实现了EvaluateExpression方法来... 目录C#代码计算数学表达式该方法很长,因此我将分段描述下面的代码片段显示了下一步以下代码显示该方法如

基于WinForm+Halcon实现图像缩放与交互功能

《基于WinForm+Halcon实现图像缩放与交互功能》本文主要讲述在WinForm中结合Halcon实现图像缩放、平移及实时显示灰度值等交互功能,包括初始化窗口的不同方式,以及通过特定事件添加相应... 目录前言初始化窗口添加图像缩放功能添加图像平移功能添加实时显示灰度值功能示例代码总结最后前言本文将

Java中的Opencv简介与开发环境部署方法

《Java中的Opencv简介与开发环境部署方法》OpenCV是一个开源的计算机视觉和图像处理库,提供了丰富的图像处理算法和工具,它支持多种图像处理和计算机视觉算法,可以用于物体识别与跟踪、图像分割与... 目录1.Opencv简介Opencv的应用2.Java使用OpenCV进行图像操作opencv安装j

python多进程实现数据共享的示例代码

《python多进程实现数据共享的示例代码》本文介绍了Python中多进程实现数据共享的方法,包括使用multiprocessing模块和manager模块这两种方法,具有一定的参考价值,感兴趣的可以... 目录背景进程、进程创建进程间通信 进程间共享数据共享list实践背景 安卓ui自动化框架,使用的是

使用Python实现批量访问URL并解析XML响应功能

《使用Python实现批量访问URL并解析XML响应功能》在现代Web开发和数据抓取中,批量访问URL并解析响应内容是一个常见的需求,本文将详细介绍如何使用Python实现批量访问URL并解析XML响... 目录引言1. 背景与需求2. 工具方法实现2.1 单URL访问与解析代码实现代码说明2.2 示例调用