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

Android9.0无法加载图片及访问不了服务器问题

Android 动画之Gif动画的用法(适用于Android9.0以上和以下)

Android9.0 如何精准区分SDK接口和非 SDK接口

glide4.0以上在Android9.0以上加载图片不显示解决方案