尽量减少权限请求

使用集合让一切井井有条 根据您的偏好保存内容并对其进行分类。

在您的应用中声明权限之前,请考虑您是否需要这样做。如果应用声明权限,那么每当用户尝试使用需要运行时权限的应用功能时,应用便不得不中断用户的操作,请求相应权限。然后,用户必须做出决定。如果用户不能理解您的应用为何请求特定权限,可能就会拒绝授予该权限,甚至卸载您的应用。

此外,每次声明新权限时,您都必须检查您的应用如何请求和分享用户数据。某些特别敏感的权限和 API 会要求您提供应用内披露声明以说明您对数据的访问、收集、使用和分享方式。

首先考虑是否需要该权限,或者是否有替代方法可在您的应用中支持该功能。系统会为不同的文件操作提供内置协定,并且也支持自定义协定

如果您必须声明某项权限,请始终尊重用户的决定,并提供一种方式让应用体验优雅降级。

本页将介绍您的应用可在不声明任何权限的情况下实现的几个用例。

显示附近的地点

您的应用可能需要了解用户的大致位置。对于显示所在地相关信息(如附近的餐馆)而言,这非常有用。

在某些用例中,您的应用只需要粗略的设备位置估算值。在这类情况下,请根据应用需要位置感知信息的频率,执行以下某项操作:

  • 如果您的应用频繁需要位置信息,请声明 ACCESS_COARSE_LOCATION 权限。该权限提供根据位置信息服务推测的设备位置信息,如介绍大致位置信息精确度的文档中所述。
  • 如果您的应用需要获取位置信息的频率较低,或只需要获取一次,请考虑改为让用户输入地址或邮政编码。

在其他用例中,您的应用需要更确切的设备位置估算值。只有在这些情况下才可以声明 ACCESS_FINE_LOCATION 权限。

创建和访问文件

Android 允许您不必声明任何与存储或传感器相关的权限就能创建和访问文件。

拍摄照片

用户可能会在您的应用中使用预安装的系统相机应用来拍摄照片。

在这种情况下,请勿声明 CAMERA 权限,而是改为调用 ACTION_IMAGE_CAPTURE intent 操作。

录制视频

用户可能会在您的应用中使用预安装的系统相机应用来录制视频。

在这种情况下,请勿声明 CAMERA 权限,而是改为调用 ACTION_VIDEO_CAPTURE intent 操作。

打开媒体文件

您的应用可能会允许用户从照片和视频中进行选择以实现某些目的,例如用作消息附件或个人资料照片。

如需支持此功能,请使用照片选择器。照片选择器不需要任何运行时权限。当用户与照片选择器互动以选择要与您的应用共享的照片或视频时,系统会授予对与所选媒体文件关联的 URI 的临时读取权限。

如果您的应用需要在不使用照片选择器的情况下访问媒体文件,那么您无需声明任何存储权限:

  • 如果您要访问您的应用创建的媒体文件,应用已经可以访问媒体库中的这些文件。
  • 如果您要访问其他应用创建的媒体文件,请使用存储访问框架

打开文档

您的应用可能会显示用户在您的应用或其他应用中创建的文档。一个常见的示例是文本文件。

在这种情况下,请仅声明 READ_EXTERNAL_STORAGE 以便与旧设备兼容。将 android:maxSdkVersion 设为 28

根据创建文档的是哪个应用,执行下列操作之一:

识别正在运行应用的某个实例的设备

您的应用的特定实例可能需要知道它正在哪个设备上运行。对于采用设备专属偏好设置或提供消息功能(如面向电视设备和穿戴式设备提供不同的播放列表)的应用而言,这非常有用。

在这种情况下,请勿直接获取设备的 IMEI。实际上,从 Android 10 开始,您已无法这样做。请改用以下方法之一:

  • 使用实例 ID 库获取应用实例的唯一设备标识符。
  • 创建您自己的标识符,将其存储在您的应用存储空间。使用基本系统函数,例如 randomUUID()

通过蓝牙与设备配对

通过利用蓝牙将数据传输到其他设备,您的应用或许能提供更好的体验。

如需支持此功能,请勿声明 ACCESS_FINE_LOCATIONACCESS_COARSE_LOCATIIONBLUETOOTH_ADMIN 权限,而是改用配套设备配对

自动输入支付卡号码

Google Play 服务提供了一个库,让您能够实现自动输入支付卡号码。您可以使用借记卡和信用卡识别库,而不是声明 CAMERA 权限。

在应用中断运行时暂停媒体

在用户接听电话或用户配置的闹钟触发时,您的应用应暂停播放所有媒体,直到其重新获得音频焦点再恢复播放。

如需支持此功能,请勿声明 READ_PHONE_STATE 权限,而是改为实现 onAudioFocusChange() 事件处理程序,它会在系统转换其音频焦点时自动运行。 详细了解如何实现音频焦点

管理通话和短信

Android 和 Google Play 服务提供的库让您不必声明任何与通话或短信相关的权限就能管理通话和短信。

自动输入一次性密码

为了简化双重身份验证工作流,您的应用可能会自动输入向用户设备发送的一次性密码以验证用户身份。

如需在由 Google Play 服务提供支持的设备上支持此功能,请勿声明 READ_SMS 权限,而是改用 SMS Retriever API

在其他设备上,如果您的应用以 Android 8.0(API 级别 26)或更高版本为目标平台,请使用 createAppSpecificSmsToken() 生成应用专用令牌。然后,将此令牌传递给可发送验证短信的其他应用或服务。

自动输入用户的电话号码

为了提供更高效的销售或支持,您的应用可能会允许用户自动输入其设备的电话号码。

如需在由 Google Play 服务提供支持的设备上支持此功能,请勿声明 READ_PHONE_STATE 权限,而是改用电话号码提示库。

过滤来电

为了给用户最大限度地减少不必要的干扰,您的应用可能会过滤掉垃圾来电。

如需支持此功能,请勿声明 READ_PHONE_STATE 权限,而是改用 CallScreeningService API。

拨打电话

您的应用可能会提供通过点按某个联系人的信息拨打电话的功能。

如需支持此功能,请使用 ACTION_DIAL intent 操作,而不是 ACTION_CALL 操作。ACTION_CALL 需要安装时权限 CALL_PHONE,这样可以阻止无法拨打电话的设备(比如某些平板电脑)安装您的应用。