Android SecurityException:getDataNetworkTypeForSubscriberの問題が修正されました

少し前まで、Androidビデオプレーヤーの開発中getDataNetworkTypeForSubscriberに、携帯電話の4G再生を使用しているときにエラーが発生しました。詳細なエラーメッセージは次のとおりです。

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);
                            }
                        }
                    });
        }
    }

おすすめ

転載: blog.csdn.net/xiangzhihong8/article/details/123503936