17

在此处发布的更改之后,getNetworkType 方法已从 Android R 及更高版本中弃用。

尝试在 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 获取网络类型(因为此权限的级别很危险,我宁愿不向用户询问)。

4

5 回答 5

2

获取 READ_PHONE_STATE 的运行时权限以忽略getDataNetworkTypeForSubscriber的崩溃

 @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);
        }
    }
于 2021-02-04T05:22:34.913 回答
1

您仍然可以使用 getDataNetworkType(); 如他的文档中所述,此方法不一定需要 READ_PHONE_STATE,但“调用应用程序具有运营商权限”就足够了。

https://developer.android.com/reference/android/telephony/TelephonyManager#getDataNetworkType()

据我所知,获得这些特权可能会很棘手/非常困难,您可以考虑获得运营商特权并使用此方法,这也是 getNetworkType() 的建议替代方法。

于 2020-07-12T07:50:20.230 回答
1

我们可以使用ConnectivityManager#getNetworkCapabilities并且NetworkCapablities#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 级别 29 中已弃用。调用者应改为使用 ConnectivityManager.NetworkCallback API 来了解连接更改,或切换到使用 ConnectivityManager#getNetworkCapabilities 或 ConnectivityManager#getLinkProperties 来同步获取信息。请记住,虽然保证按顺序调用每个事件的回调,但同步调用没有这样的限制,因此不建议在回调中使用同步方法,因为它们通常不会提供网络视图,即一致(即:它们可能返回与回调处理的事件相关的过去或未来状态)。相反,建议调用者只使用回调的参数,可能会记住他们需要从一个回调到另一个回调的特定信息位。

于 2021-07-20T16:12:35.893 回答
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 {}
于 2020-11-01T13:58:20.440 回答
0

所以我的朋友,我遇到了和你一样的麻烦,但到目前为止,我使用的是 compileSdkVersion 29 而不是 30 以及 targetSdkVersion 29 和我的 buildToolsVersion 28.0.3,并且我的应用程序加载正常。

由于我的这个问题来自第三方库,所以在修复错误之前我无法单独修复它,但我认为现在这个临时解决方案非常好。

于 2020-07-07T01:00:24.683 回答