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

相关文章

sqlite3 相关知识

WAL 模式 VS 回滚模式 特性WAL 模式回滚模式(Rollback Journal)定义使用写前日志来记录变更。使用回滚日志来记录事务的所有修改。特点更高的并发性和性能;支持多读者和单写者。支持安全的事务回滚,但并发性较低。性能写入性能更好,尤其是读多写少的场景。写操作会造成较大的性能开销,尤其是在事务开始时。写入流程数据首先写入 WAL 文件,然后才从 WAL 刷新到主数据库。数据在开始

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

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

活用c4d官方开发文档查询代码

当你问AI助手比如豆包,如何用python禁止掉xpresso标签时候,它会提示到 这时候要用到两个东西。https://developers.maxon.net/论坛搜索和开发文档 比如这里我就在官方找到正确的id描述 然后我就把参数标签换过来

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

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

poj 1258 Agri-Net(最小生成树模板代码)

感觉用这题来当模板更适合。 题意就是给你邻接矩阵求最小生成树啦。~ prim代码:效率很高。172k...0ms。 #include<stdio.h>#include<algorithm>using namespace std;const int MaxN = 101;const int INF = 0x3f3f3f3f;int g[MaxN][MaxN];int n

ASIO网络调试助手之一:简介

多年前,写过几篇《Boost.Asio C++网络编程》的学习文章,一直没机会实践。最近项目中用到了Asio,于是抽空写了个网络调试助手。 开发环境: Win10 Qt5.12.6 + Asio(standalone) + spdlog 支持协议: UDP + TCP Client + TCP Server 独立的Asio(http://www.think-async.com)只包含了头文件,不依

怎么让1台电脑共享给7人同时流畅设计

在当今的创意设计与数字内容生产领域,图形工作站以其强大的计算能力、专业的图形处理能力和稳定的系统性能,成为了众多设计师、动画师、视频编辑师等创意工作者的必备工具。 设计团队面临资源有限,比如只有一台高性能电脑时,如何高效地让七人同时流畅地进行设计工作,便成为了一个亟待解决的问题。 一、硬件升级与配置 1.高性能处理器(CPU):选择多核、高线程的处理器,例如Intel的至强系列或AMD的Ry

计算机毕业设计 大学志愿填报系统 Java+SpringBoot+Vue 前后端分离 文档报告 代码讲解 安装调试

🍊作者:计算机编程-吉哥 🍊简介:专业从事JavaWeb程序开发,微信小程序开发,定制化项目、 源码、代码讲解、文档撰写、ppt制作。做自己喜欢的事,生活就是快乐的。 🍊心愿:点赞 👍 收藏 ⭐评论 📝 🍅 文末获取源码联系 👇🏻 精彩专栏推荐订阅 👇🏻 不然下次找不到哟~Java毕业设计项目~热门选题推荐《1000套》 目录 1.技术选型 2.开发工具 3.功能

代码随想录冲冲冲 Day39 动态规划Part7

198. 打家劫舍 dp数组的意义是在第i位的时候偷的最大钱数是多少 如果nums的size为0 总价值当然就是0 如果nums的size为1 总价值是nums[0] 遍历顺序就是从小到大遍历 之后是递推公式 对于dp[i]的最大价值来说有两种可能 1.偷第i个 那么最大价值就是dp[i-2]+nums[i] 2.不偷第i个 那么价值就是dp[i-1] 之后取这两个的最大值就是d

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

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