Android SecurityException: getDataNetworkTypeForSubscriber问题修复

Posted xiangzhihong8

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android SecurityException: getDataNetworkTypeForSubscriber问题修复相关的知识,希望对你有一定的参考价值。

前不久,在开发android视频播放器的时候,使用手机的4G播放时出现了getDataNetworkTypeForSubscriber错误,详细的报错信息如下:

Process: com.avatar.buyer.client, PID: 27217
    java.lang.SecurityException: getDataNetworkTypeForSubscriber
        at android.os.Parcel.createExceptionOrNull(Parcel.java:2437)
        at android.os.Parcel.createException(Parcel.java:2421)
        at android.os.Parcel.readException(Parcel.java:2404)
        at android.os.Parcel.readException(Parcel.java:2346)
        at com.android.internal.telephony.ITelephony$Stub$Proxy.getNetworkTypeForSubscriber(ITelephony.java:9300)
        at android.telephony.TelephonyManager.getNetworkType(TelephonyManager.java:3550)
        at android.telephony.TelephonyManager.getNetworkType(TelephonyManager.java:3514)
        at com.kk.taurus.playerbase.utils.NetworkUtils.getNetworkState(NetworkUtils.java:76)
        at com.avatar.video.cover.ErrorCover.onCoverAttachedToWindow(ErrorCover.java:54)
        at com.kk.taurus.playerbase.receiver.BaseCover.onViewAttachedToWindow(BaseCover.java:118)
        at android.view.View.dispatchAttachedToWindow(View.java:21982)
        at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:4293)
        at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:4302)
        at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:4302)
        at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:4302)
        at android.view.ViewGroup.addViewInner(ViewGroup.java:6127)
        at android.view.ViewGroup.addView(ViewGroup.java:5903)
        at android.view.ViewGroup.addView(ViewGroup.java:5875)
        at com.kk.taurus.playerbase.assist.RelationAssist.attachContainer(RelationAssist.java:367)
        at com.avatar.video.base.BSPlayer.attachContainer(BSPlayer.java:194)
        at com.avatar.video.base.BSPlayer.attachContainer(BSPlayer.java:190)
        at com.avatar.module.shop.ui.GoodsDetailActivity.setVideoConfig(GoodsDetailActivity.kt:224)
        at com.avatar.module.shop.ui.GoodsDetailActivity.access$setVideoConfig(GoodsDetailActivity.kt:64)
        at com.avatar.module.shop.ui.GoodsDetailActivity$updateTopBanner$2.onPlay(GoodsDetailActivity.kt:187)
        at com.avatar.common.widget.banner.CommonBannerAdapter.onBindViewHolder$lambda-2$lambda-1(CommonBannerAdapter.kt:55)
        at com.avatar.common.widget.banner.CommonBannerAdapter.lambda$TurXnrorY1dSzOfKtnh8x0HRywc(Unknown Source:0)
        at com.avatar.common.widget.banner.-$$Lambda$CommonBannerAdapter$TurXnrorY1dSzOfKtnh8x0HRywc.onClick(Unknown Source:11)

上述错误通常出现在,用户切换改变网络的过程中。根据资料查找,出现这种错误的场景为:

  • 根据 SecurityException: getDataNetworkTypeForSubscriber 可以看到,这是一个安全性异常,所以猜测应用在 Android11 的权限有关,由于缺少该权限导致无法访问接口而异常。
  • 找到网络状态检测方法,可以看到调用了 TelephonyManager.getNetworkType()接口获取网络类型,该方法是需要 READ_PHONE_STATE 权限的,该方法上面也有 RequiresPermission 注解声明。

下面是我们检查网络状态的代码,可以看到,最后调用了telephonyManager.getNetworkType();,报错的地方就在那,如下:

    @RequiresPermission(value = "android.permission.READ_PHONE_STATE")
    public int getNetworkState(Context context) 
        if (null == mConnectivityManager)  // 为空则认为无网络
            return NETWORK_NONE;
        
        // 获取网络类型,如果为空,返回无网络
        NetworkInfo activeNetInfo = mConnectivityManager.getActiveNetworkInfo();
        if (activeNetInfo == null || !activeNetInfo.isAvailable()) 
            return NETWORK_NONE;
        
        // 判断是否为WIFI
        NetworkInfo wifiInfo = mConnectivityManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
        if (null != wifiInfo) 
            NetworkInfo.State state = wifiInfo.getState();
            if (null != state) 
                if (state == NetworkInfo.State.CONNECTED || state == NetworkInfo.State.CONNECTING) 
                    return NETWORK_WIFI;
                
            
        
        // 若不是WIFI,则去判断是2G、3G、4G网
        TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
        int networkType = telephonyManager.getNetworkType();
        ...
    

解决的方式也是很简单,就是在调用前判断网络状态权限,如果没有权限跳转授权权限。

private void requestPermission() 
        LogUtil.printE(HomeActivity.class, ">>> etrunc requestPermission SDK-VERSION= " + Build.VERSION.SDK_INT);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R)  //Android 11 授权读写权限
            XXPermissions.with(this)
                    .permission(Permission.READ_PHONE_STATE)
                    .request(new OnPermissionCallback() 

                        @Override
                        public void onGranted(List<String> permissions, boolean all) 
                            if (all) 
                                ToastUtil.showToast(getApplication(), R.string.permission_success_tip);
                            
                        

                        @Override
                        public void onDenied(List<String> permissions, boolean never) 
                            if (never) 
                                // 如果是被永久拒绝就跳转到应用权限系统设置页面
                                XXPermissions.startPermissionActivity(this, permissions);
                             else 
                                ToastUtil.showToast(getApplication(), R.string.permissions_error);
                            
                        
                    );
        
    

以上是关于Android SecurityException: getDataNetworkTypeForSubscriber问题修复的主要内容,如果未能解决你的问题,请参考以下文章

Android:java.lang.SecurityException:权限拒绝:启动意图

Android SecurityException: getDataNetworkTypeForSubscriber问题修复

Android SecurityException

SecurityException - “调用者......不是范围委托阻止卸载的代表”(Android 8 - Java)

Android 9.0 NotificationManager.notify() 抛出 java.lang.SecurityException

SecurityException:权限拒绝:读取 com.android.providers.media.MediaProvider 需要 android.permission.READ_EXTER