在Android 11中的GetNetworkType

17
根据这里发布的更改,从Android R版本开始,getNetworkType方法被弃用。

在尝试在R版本编译的应用程序中使用此方法时,将导致抛出以下异常:

java.lang.SecurityException: getDataNetworkTypeForSubscriber: uid 10225 does not have android.permission.READ_PHONE_STATE.
  at android.os.Parcel.createExceptionOrNull(Parcel.java:2285)
  at android.os.Parcel.createException(Parcel.java:2269)
  at android.os.Parcel.readException(Parcel.java:2252)
  at android.os.Parcel.readException(Parcel.java:2194)
  at com.android.internal.telephony.ITelephony$Stub$Proxy.getNetworkTypeForSubscriber(ITelephony.java:7565)
  at android.telephony.TelephonyManager.getNetworkType(TelephonyManager.java:2964)
  at android.telephony.TelephonyManager.getNetworkType(TelephonyManager.java:2928)
  at com.ironsource.environment.ConnectivityService.getCellularNetworkType(ConnectivityService.java:197)
  at com.ironsource.sdk.service.DeviceData.updateWithConnectionInfo(DeviceData.java:98)
  at com.ironsource.sdk.service.DeviceData.fetchMutableData(DeviceData.java:54)
  at com.ironsource.sdk.service.TokenService.collectDataFromDevice(TokenService.java:120)
  at com.ironsource.sdk.service.TokenService.getRawToken(TokenService.java:177)
  at com.ironsource.sdk.service.TokenService.getToken(TokenService.java:166)
  at com.ironsource.sdk.IronSourceNetwork.getToken(IronSourceNetwork.java:183)

根据文档,这是正常的预期行为。如果将应用程序编译到 Android R 之前的任何版本,则不会显示异常。

此异常表示我需要请求android.permission.READ_PHONE_STATE权限。

我想知道是否有任何其他API可以获取网络类型而不需要此权限(因为此权限的级别很高,我宁愿不要向用户请求它)。

5个回答

2

获取数据网络类型的订阅者需要运行时权限READ_PHONE_STATE以忽略崩溃。

 @Override
    protected void onStart() {
        super.onStart();

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {

            int res = checkSelfPermission(android.Manifest.permission.READ_PHONE_STATE);
            if (res != PackageManager.PERMISSION_GRANTED) {
                requestPermissions(new String[]{android.Manifest.permission.READ_PHONE_STATE}, 123);
            }

        }
    }

    private final static int REQUEST_CODE_ASK_PERMISSIONS = 1002;

    @Override
    public void onRequestPermissionsResult(int requestCode,
                                           @NonNull String[] permissions, @NonNull int[] grantResults) {
        switch (requestCode) {
            case REQUEST_CODE_ASK_PERMISSIONS:
                if (grantResults[0] != PackageManager.PERMISSION_GRANTED) {
                    Toast.makeText(getApplicationContext(), "READ_PHONE_STATE Denied", Toast.LENGTH_SHORT)
                            .show();
                } else {
                }
                stepAfterSplash();

                break;
            default:
                super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        }
    }

1

我显然已经阅读了这篇文章,但是让应用程序拥有运营商特权并不容易获得(正如您所说)。因此,这并没有真正帮助到我。 - tomerpacific

1
这种方法必须在您的活动中通过这种方式获取READ_PHONE_STATE,而不仅仅是在清单中。
// Check if the READ_PHONE_STATE permission is already available.


if(ActivityCompat.checkSelfPermission(this,Manifest.permission.READ_PHONE_STATE)
                != PackageManager.PERMISSION_GRANTED) {

            if (ActivityCompat.shouldShowRequestPermissionRationale(this,
                    Manifest.permission.READ_PHONE_STATE)) {

                  //here >> use getNetworkType() method
              // like this example
 
              mStationInfo.set_networkType(mTelephonyManager.getNetworkType());
            } 
           else {}

如果您阅读我的问题,您会注意到我已经声明了我是否可以在不使用此权限的情况下实现这一点... - tomerpacific
抱歉,我没有注意到。 - Mohamed El SheiKh

1
我们可以像这样使用ConnectivityManager#getNetworkCapabilitiesNetworkCapablities#hasTransport
ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkCapabilities caps = cm.getNetworkCapabilities(cm.getActivityNetwork());
boolean isMobile = caps.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR);
boolean isWifi = caps.hasTransport(NetworkCapabilities.TRANSPORT_WIFI);

参考:

android.net.NetworkInfo
这个类在API level 29中被弃用。调用者应该使用ConnectivityManager.NetworkCallback API 来了解连接状态的变化,或者切换到使用ConnectivityManager#getNetworkCapabilities或 ConnectivityManager#getLinkProperties以同步获取信息。请注意,虽然回调对于每个事件的顺序都有保证, 但是同步调用没有这样的限制,因此在回调内部使用同步方法是不可取的,因为它们通常不会提供一致的网络状态视图 (即:它们可能返回与回调处理的事件相对应的过去或将来的状态)。相反,建议调用者仅使用回调的参数, 可能从一个回调中记住他们需要保留的特定信息位,以在另一个回调中使用。


0

所以我的朋友,我和你一样遇到了同样的问题,但是到目前为止,我找到了一个临时解决方案,我使用的是compileSdkVersion 29而不是30,targetSdkVersion 29,buildToolsVersion 28.0.3,我的应用程序也可以正常加载。

由于这个问题是由第三方库引起的,所以在修复错误之前,我无法独自解决它,但我认为现在这个临时解决方案已经相当好了。


8
将你的应用编译到API 29并不能解决这个问题... - tomerpacific
相关链接:https://dev59.com/tsDqa4cB1Zd3GeqPmdVW - Sean

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接