如何处理在 Android M 中删除广播接收器的权限?

How to deal with removal of a permission for a broadcast receiver in Android M?

我有一些遗留代码,我正在为 Marshmallow 设置权限安全。

有一个使用PHONE_STATE权限的广播如下:

<receiver android:name="redacted.TheBroadcastReceiver">
    <intent-filter>
        <action android:name="android.intent.action.PHONE_STATE"></action>
        <action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
    </intent-filter>
</receiver>

如果 PHONE_STATE 权限被授予,但随后用户被拒绝,那么当有 phone 调用时,就会出现与权限相关的崩溃。 但是崩溃发生在 之前 广播接收器的 onReceive() 被调用(崩溃发生在 android.app.ActivityThread.handleReceiver 中)。这意味着广播接收器甚至没有机会检查是否授予权限并处理这种情况。

所以我的问题是,如果有这样的广播接收器,代码如何处理用户禁用权限的情况,因为 AFAIK 没有 API 来监视权限的变化当它们发生时,因此代码无法即时知道权限已被撤销,因此它无法注销其广播接收器。

Android M 的最终版本还没有出来(最终的 api 已经出来,但不是平台代码),所以希望平台在调用你的接收器之前处理权限检查。

尝试在 6.0.1 上重现该问题,但没有成功。我为我使用的 test project 添加了一个 link。
场景很简单:

  1. 运行 权限打开。一切都按预期工作。 onReceive 被调用。
  2. 关闭权限。 phone 状态更改时应用程序崩溃的预期结果没有发生。

除非有人有不同的结果,否则我认为这个问题在某种程度上是 "solved"。

至于 Android Marsmallow 中的权限,您可能需要在像这样调用接收器之前检查权限:

// Here, thisActivity is the current activity
if (ContextCompat.checkSelfPermission(thisActivity,
                Manifest.permission.PHONE_STATE)
        != PackageManager.PERMISSION_GRANTED) {

    // Should we show an explanation?
    if (ActivityCompat.shouldShowRequestPermissionRationale(thisActivity,
            Manifest.permission.PHONE_STATE)) {

        // Show an expanation to the user *asynchronously* -- don't block
        // this thread waiting for the user's response! After the user
        // sees the explanation, try again to request the permission.

    } else {

        // No explanation needed, we can request the permission.

        ActivityCompat.requestPermissions(thisActivity,
                new String[]{Manifest.permission.PHONE_STATE},
                MY_PERMISSIONS_REQUEST_PHONE_STATE);

        // MY_PERMISSIONS_REQUEST_READ_CONTACTS is an
        // app-defined int constant. The callback method gets the
        // result of the request.
    }
}

这是一个迟到的答案,但我希望它能帮助别人!!!