SecurityException:权限被拒绝:通过显式意图启动Activity时

时间:2019-01-27 12:06:12

标签: android android-intent android-activity android-permissions

我正在阅读有关declaring permissions in activity的信息 。根据文档

  

您可以使用清单的标签来控制哪些应用可以启动特定活动。除非两个活动在其清单中都具有相同的权限,否则父活动无法启动子活动。如果为特定活动声明元素,则调用活动必须具有匹配的元素。

要尝试这一点,我创建了2个示例应用程序。第一个应用程序将尝试使用明确意图直接启动第二个应用程序的活动, 另外,第二个应用程序将声明我从第一个应用程序启动的特定活动的权限。

这些是我遵循的步骤

  1. 创建了2个应用(说发送方和接收方)
  2. 在发件人的<uses-permission android:name="permission.SHARE_POST"/>中添加了权限Manifest
  3. 现在,通过单击Sender App的按钮,我将调用ShareActivity的Receivers Activity如下

        Intent intent = new Intent();
        intent.setComponent(new ComponentName("basics.android.com.androidbasics","basics.android.com.androidbasics.ShareActivity"));
        startActivity(intent);
    

    注意:basics.android.com.androidbasics是接收者的包裹名称

  4. 下面是Second App(接收方)清单中的活动声明

           <activity
            android:name=".ShareActivity"
            android:exported="true"
            android:permission="permission.SHARE_POST"/>
    

现在,当我同时运行这两个应用程序并尝试从发件人处取消ShareActivity时,出现以下错误

Caused by: java.lang.SecurityException: Permission Denial: starting Intent { cmp=basics.android.com.androidbasics/.ShareActivity } from ProcessRecord{e09a1fc 26267:sender.android.com.sender/u0a925} (pid=26267, uid=10925) requires permission.SHARE_POST

似乎发件人还没有权限permission.SHARE_POST。但是我已经在发件人清单中声明了它。 这里发生了什么事?

1 个答案:

答案 0 :(得分:2)

在Android中,使用自定义权限是一项相当高级的操作。基本配方是:

  1. 确定所需的权限名称。它在设备上必须是唯一的。因此,permission.SHARE_POST并不是一个好选择-添加与您的域名或您要用作应用程序applicationId值基础的任何其他内容相关的前缀。
  2. 在使用权限进行保护的应用程序中,声明一个<permission>元素,并使用一个android:name属性保存步骤#1中的权限名称。 (可选)为其提供一个android:protectionLevel属性(例如signature,因此只有使用同一签名密钥签名的应用才能一起使用)。
  3. 在使用权限进行保护的应用程序中,在组件(例如android:permission)上添加一个<activity>属性,并使用步骤1中的权限名称值。
  4. 在要与步骤3中的应用进行通信的应用中,添加<uses-permission>属性,其中android:name属性包含步骤1中的权限名称。
  5. 在两个应用程序中,将您的minSdkVersion设置为21,因为旧版本的自定义权限存在安全问题。

如果总是在客户端之前安装防御程序(步骤2和3)(步骤4),则此方法将起作用。如果您希望这些应用程序可以按任一顺序安装,则将上面的步骤2替换为:

  1. 这两个应用中,声明一个<permission>元素,并带有一个android:name属性,该属性保存步骤1中的权限名称。 (可选)为其提供一个android:protectionLevel属性(例如signature,因此只有使用同一签名密钥签名的应用才能一起使用)。另外,请确保两个应用程序始终使用相同的签名密钥进行签名,否则它们将无法定义相同的权限。