Android9.0 网络框架之--Tethering 热点
Posted Mrsongs的心情杂货铺
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android9.0 网络框架之--Tethering 热点相关的知识,希望对你有一定的参考价值。
一、概述:最近android P 平台遇到一个打开车机热点,手机连接后不能上网的 问题,下面是正常的log和异常的log
热点正常能上网的log:
热点异常不能上网的log:
通过log发现Tethering: Found upstream interface(s): null 所以出现不能上网的情况,这里也分析一下打开热点,连接上网的过程。
参考博客:
https://blog.csdn.net/weixin_42093428/article/details/84062557
二、打开热点的流程
调用ConnectivityManager 的 startTethering方法
public void startTethering(int type, boolean showProvisioningUi,
final OnStartTetheringCallback callback, Handler handler)
Preconditions.checkNotNull(callback, “OnStartTetheringCallback cannot be null.”);
ResultReceiver wrappedCallback = new ResultReceiver(handler)
@Override
protected void onReceiveResult(int resultCode, Bundle resultData)
if (resultCode == TETHER_ERROR_NO_ERROR)
callback.onTetheringStarted();
else
callback.onTetheringFailed();
;
try
String pkgName = mContext.getOpPackageName();
Log.i(TAG, "startTethering caller:" + pkgName);
mService.startTethering(type, wrappedCallback, showProvisioningUi, pkgName);
catch (RemoteException e)
Log.e(TAG, "Exception trying to start tethering.", e);
wrappedCallback.send(TETHER_ERROR_SERVICE_UNAVAIL, null);
这里 mService.startTethering,mService 实际上就是ConnectivityService ,我们看看ConnectivityService 的startTethering 方法
@Override
public void startTethering(int type, ResultReceiver receiver, boolean showProvisioningUi,
String callerPkg)
ConnectivityManager.enforceTetherChangePermission(mContext, callerPkg);
if (!isTetheringSupported())
receiver.send(ConnectivityManager.TETHER_ERROR_UNSUPPORTED, null);
return;
mTethering.startTethering(type, receiver, showProvisioningUi);
如果系统支持热点功能,就会调用Tethering 的 startTethering 方法
代码路径:frameworks/base/services/core/java/com/android/server/connectivity/Tethering.java
public void startTethering(int type, ResultReceiver receiver, boolean showProvisioningUi)
if (!isTetherProvisioningRequired())
enableTetheringInternal(type, true, receiver);
return;
if (showProvisioningUi)
runUiTetherProvisioningAndEnable(type, receiver);
else
runSilentTetherProvisioningAndEnable(type, receiver);
这里传入的showProvisioningUi 为false ,接着走 runSilentTetherProvisioningAndEnable(type, receiver);
private void runSilentTetherProvisioningAndEnable(int type, ResultReceiver receiver)
ResultReceiver proxyReceiver = getProxyReceiver(type, receiver);
sendSilentTetherProvisionIntent(type, proxyReceiver);
private void sendSilentTetherProvisionIntent(int type, ResultReceiver receiver)
Intent intent = new Intent();
intent.putExtra(EXTRA_ADD_TETHER_TYPE, type);
intent.putExtra(EXTRA_RUN_PROVISION, true);
intent.putExtra(EXTRA_PROVISION_CALLBACK, receiver);
intent.setComponent(TETHER_SERVICE);
final long ident = Binder.clearCallingIdentity();
try
mContext.startServiceAsUser(intent, UserHandle.CURRENT);
finally
Binder.restoreCallingIdentity(ident);
这里面会启动一个TETHER_SERVICE,他的包名类名是com.android.settings/.wifi.tether.TetherService ,原来走了一圈最后还是走到了Settings 的代码中了。
TetherService 中最后会发送一个广播
private void startProvisioning(int index)
if (index < mCurrentTethers.size())
Intent intent = getProvisionBroadcastIntent(index);
setEntitlementAppActive(index);
if (DEBUG) Log.d(TAG, "Sending provisioning broadcast: " + intent.getAction()
+ " type: " + mCurrentTethers.get(index));
sendBroadcast(intent);
mInProvisionCheck = true;
private Intent getProvisionBroadcastIntent(int index)
String provisionAction = getResources().getString(
com.android.internal.R.string.config_mobile_hotspot_provision_app_no_ui);
Intent intent = new Intent(provisionAction);
int type = mCurrentTethers.get(index);
intent.putExtra(TETHER_CHOICE, type);
intent.setFlags(Intent.FLAG_RECEIVER_FOREGROUND
| Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
return intent;
以上是关于Android9.0 网络框架之--Tethering 热点的主要内容,如果未能解决你的问题,请参考以下文章
Android9.0 网络评分之--NetworkMonitor
Android9.0 网络评分之--NetworkMonitor
Android 动画之Gif动画的用法(适用于Android9.0以上和以下)