Android SecurityException: getDataNetworkTypeForSubscriber问题修复

Android SecurityException: getDataNetworkTypeForSubscriber问题修复

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

php 复制代码
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();,报错的地方就在那,如下:

ini 复制代码
    @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();
        ...
    }

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

typescript 复制代码
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);
                            }
                        }
                    });
        }
    }
相关推荐
xiangpanf9 小时前
Laravel 10.x重磅升级:五大核心特性解析
android
robotx12 小时前
安卓线程相关
android
消失的旧时光-194312 小时前
Android 面试高频:JSON 文件、大数据存储与断电安全(从原理到工程实践)
android·面试·json
dalancon13 小时前
VSYNC 信号流程分析 (Android 14)
android
dalancon13 小时前
VSYNC 信号完整流程2
android
dalancon13 小时前
SurfaceFlinger 上帧后 releaseBuffer 完整流程分析
android
用户693717500138415 小时前
不卷AI速度,我卷自己的从容——北京程序员手记
android·前端·人工智能
程序员Android15 小时前
Android 刷新一帧流程trace拆解
android
墨狂之逸才16 小时前
解决 Android/Gradle 编译报错:Comparison method violates its general contract!
android
阿明的小蝴蝶16 小时前
记一次Gradle环境的编译问题与解决
android·前端·gradle