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);
                            }
                        }
                    });
        }
    }
相关推荐
叽哥2 小时前
Kotlin学习第 1 课:Kotlin 入门准备:搭建学习环境与认知基础
android·java·kotlin
风往哪边走3 小时前
创建自定义语音录制View
android·前端
用户2018792831673 小时前
事件分发之“官僚主义”?或“绕圈”的艺术
android
用户2018792831673 小时前
Android事件分发为何喜欢“兜圈子”?不做个“敞亮人”!
android
Kapaseker5 小时前
你一定会喜欢的 Compose 形变动画
android
QuZhengRong5 小时前
【数据库】Navicat 导入 Excel 数据乱码问题的解决方法
android·数据库·excel
zhangphil6 小时前
Android Coil3视频封面抽取封面帧存Disk缓存,Kotlin(2)
android·kotlin
程序员码歌13 小时前
【零代码AI编程实战】AI灯塔导航-总结篇
android·前端·后端
书弋江山14 小时前
flutter 跨平台编码库 protobuf 工具使用
android·flutter
来来走走16 小时前
Flutter开发 webview_flutter的基本使用
android·flutter