SecurityException:不允许执行OP_READ_PHONE_STATE

时间:2016-09-26 03:18:13

标签: android security android-6.0-marshmallow

用户使用此错误跟踪报告我的应用程序崩溃

java.lang.SecurityException: com.android.phone from uid 10134 not allowed to perform OP_READ_PHONE_STATE
at android.os.Parcel.readException(Parcel.java:1620)
at android.os.Parcel.readException(Parcel.java:1573)
at com.android.internal.telephony.IPhoneSubInfo$Stub$Proxy.getVoiceMailNumberForSubscriber(IPhoneSubInfo.java:858)
at android.telephony.TelephonyManager.getVoiceMailNumber(TelephonyManager.java:2383)
at android.telephony.TelephonyManager.getVoiceMailNumber(TelephonyManager.java:2366)

到目前为止,只有一位用户报告了此问题。其他几千名用户正在运行此版本的应用程序,没有明显的问题。

当我们调用TelephonyManager.getVoiceMailNumber()时抛出异常。此操作记录为必需的READ_PHONE_STATE权限,该权限已被绝对正式授予。

我追踪了对android.apps.AppOpsManager类的OP_READ_PHONE_STATE权限,但无法确切地知道它对什么不满意。

任何人都可以解释发生了什么以及需要做些什么来解决问题。

谢谢, -Ken

1 个答案:

答案 0 :(得分:0)

在 AOSP 中寻找该方法最终会导致 cheakReadPhoneState() method

在 Android 6 中,该方法是 here

在这两种情况下,它看起来都非常相似。这是 Android 6 代码:

private boolean checkReadPhoneState(String callingPackage, String message) {
    try {
        mContext.enforceCallingOrSelfPermission(
                android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, message);

        // SKIP checking run-time OP_READ_PHONE_STATE since self or using PRIVILEGED
        return true;
    } catch (SecurityException e) {
        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.READ_PHONE_STATE,
                message);
    }

    return mAppOps.noteOp(AppOpsManager.OP_READ_PHONE_STATE, Binder.getCallingUid(),
        callingPackage) == AppOpsManager.MODE_ALLOWED;
}

首先检查 READ_PRIVILEGED_PHONE_STATE 是否被授予。如果是,则其余代码将短路并返回 true。否则,它确保授予 READ_PHONE_STATE,否则抛出 SecurityException。

最后,如果 READ_PHONE_STATE 被授予,它确保 OP_READ_PHONE_STATE 被授予。我不完全确定它为什么这样做,但这就是问题的来源。无论在哪个设备上发生此错误,运行时权限的工作方式都发生了一些变化。授予 READ_PHONE_STATE 权限后,还应授予 OP_READ_PHONE_STATE 操作,但系统会出于任何原因撤销该操作。

(也有可能是用户正在使用某个应用来管理应用操作并手动撤销了它。)

为了修复它,我真的不认为你可以。您能做的最好的事情就是捕获错误并要求用户运行 ADB 命令以手动授予操作权限:

adb shell appops set com.your.packagename READ_PHONE_STATE allow