限制与其他应用的交互

权限不仅用于请求系统功能。您还可以限制其他应用如何与您应用的组件交互。

本指南介绍了如何检查另一个应用声明的权限集。本指南还介绍了如何配置活动、服务、内容提供者和广播接收器以限制其他应用如何与您的应用交互。

检查另一个应用的权限

要查看另一个应用声明的权限集,请使用设备或模拟器完成以下步骤

  1. 打开应用的 **应用信息** 屏幕。
  2. 选择 **权限**。**应用权限** 屏幕将加载。

    此屏幕显示一组权限组。系统将应用声明的权限集组织到这些组中。

还有许多其他有用的方法可以检查权限

  • 在调用服务时,将权限字符串传递给 Context.checkCallingPermission()。此方法返回一个整数,指示当前调用进程是否已授予该权限。请注意,这只能在您执行来自另一个进程的调用时使用,通常通过从服务发布的 IDL 接口或以其他方式提供给另一个进程。
  • 要检查另一个进程是否已授予特定权限,请将进程 (PID) 传递给 Context.checkPermission().
  • 要检查另一个包是否已授予特定权限,请将包名传递给 PackageManager.checkPermission().

限制与您的应用活动的交互

在清单中,使用 android:permission 属性来限制哪些其他应用可以启动 <activity> 标签中的 Activity。权限在 Context.startActivity()Activity.startActivityForResult() 期间进行检查。如果调用者没有所需的权限,则会发生 SecurityException

限制与您的应用服务的交互

在清单中,使用 android:permission 属性来限制哪些其他应用可以启动或绑定到 <service> 标签中关联的 Service。权限在 Context.startService()Context.stopService()Context.bindService() 期间进行检查。如果调用者没有所需的权限,则会发生 SecurityException

限制与您的应用内容提供者的交互

使用 android:permission 属性来限制哪些其他应用可以访问 <provider> 标签中 ContentProvider 中的数据。(内容提供者可以使用称为 URI 权限 的重要附加安全机制,在下一节中介绍。)与其他组件不同,您可以为内容提供者设置两个独立的权限属性: android:readPermission 限制哪些其他应用可以从提供者读取数据,而 android:writePermission 限制哪些其他应用可以向其写入数据。请注意,如果提供者受读取和写入权限保护,则仅拥有写入权限并不允许应用从提供者读取数据。

首次检索提供者时以及应用对提供者执行操作时会检查权限。如果请求应用没有任一权限,则会发生 SecurityException。使用 ContentResolver.query() 需要读取权限;使用 ContentResolver.insert()ContentResolver.update()ContentResolver.delete() 需要写入权限。在所有这些情况下,如果未持有所需的权限,则会导致 SecurityException

在每个 URI 级别授予访问权限

系统为您提供对其他应用如何访问您的应用内容提供者进行更细粒度控制的附加功能。特别是,您的内容提供者可以使用读取和写入权限进行自我保护,同时仍然允许其直接客户端与其他应用共享特定的 URI。要声明您的应用对该模型的支持,请使用 android:grantUriPermissions 属性或 <grant-uri-permission> 元素。

您也可以在每个 URI 级别授予权限。在启动 Activity 或将结果返回到 Activity 时,请设置 Intent.FLAG_GRANT_READ_URI_PERMISSION 意图标志、Intent.FLAG_GRANT_WRITE_URI_PERMISSION 意图标志或两个标志。这将分别为其他应用提供读取、写入或读取/写入权限,用于意图中包含的数据 URI。其他应用会获得这些权限,用于特定 URI,而无论它们是否具有更一般地访问内容提供者中数据的权限。

例如,假设用户正在使用您的应用查看带有图像附件的电子邮件。其他应用不应该能够访问电子邮件内容,但它们可能对查看图像感兴趣。您的应用可以使用意图和 Intent.FLAG_GRANT_READ_URI_PERMISSION 意图标志来让图像查看应用查看图像。

另一个需要考虑的是 应用可见性。如果您的应用面向 Android 11(API 级别 30)或更高版本,则系统会自动将一些应用显示给您的应用,并默认情况下隐藏其他应用。如果您的应用具有内容提供者并且已向另一个应用授予 URI 权限,则您的应用会 自动显示 给该其他应用。

有关详细信息,请查看 grantUriPermission()revokeUriPermission()checkUriPermission() 方法的参考材料。

限制与您的应用广播接收者的交互

使用 android:permission 属性来限制哪些其他应用可以向 <receiver> 标签中关联的 BroadcastReceiver 发送广播。权限在 Context.sendBroadcast() 返回之后进行检查,因为系统会尝试将提交的广播传递给给定的接收者。这意味着权限失败不会导致异常抛回给调用者,它只是不会传递 Intent

同样,您可以向 Context.registerReceiver() 提供权限来控制哪些其他应用可以向以编程方式注册的接收者广播。反过来,您可以在调用 Context.sendBroadcast() 时提供权限来限制哪些广播接收者可以接收广播。

请注意,接收者和广播者都可以要求权限。在这种情况下,必须通过两个权限检查才能将意图传递给关联的目标。有关详细信息,请参阅 使用权限限制广播