作为提升应用质量和保护用户隐私的一部分,我们建议您最大限度地减少应用中的权限使用。这有助于用户发现和使用提供安全可靠用户环境的优质应用。
向用户请求权限会中断用户流程,并且用户可以拒绝您的请求。此外,每次您声明新权限时,都必须审查您的应用如何请求和共享用户数据。某些特别敏感的权限和 API 要求您在应用内披露数据访问、收集、使用和共享情况。
有多种替代方法可以最大限度地减少权限使用:
- 如果您的应用只需要大致位置,请声明提供粗略位置信息而非精确位置信息的权限。
- 调用允许您的应用在不声明权限的情况下执行所需功能的 API。
- 调用特定的 intent 或事件处理程序来执行功能,而不是声明权限。
- 系统提供了针对不同文件操作的内置契约,并且还支持自定义契约。
如果您必须声明权限,请务必尊重用户的决定,并提供一种优雅降级应用体验的方式。
本页面介绍了您的应用无需声明任何权限即可实现的一些用例。
显示附近地点
您的应用可能需要知道用户的近似位置。这对于显示基于位置的信息(例如附近的餐馆)很有用。
某些用例只需要粗略估算设备位置。在这些情况下,请根据您的应用需要位置信息的频率执行以下操作之一:
- 如果您的应用经常需要位置信息,请声明
ACCESS_COARSE_LOCATION
权限。该权限通过位置服务提供设备位置估算,如关于近似位置精度的文档中所述。 - 如果您的应用不常需要位置信息,或者只需要一次,请考虑改为要求用户输入地址或邮政编码。
其他用例需要更精确地估算设备位置。只有在这些情况下,才可以声明 ACCESS_FINE_LOCATION
权限。
创建和访问文件
Android 允许您创建和访问文件,而无需声明任何与存储或传感器相关的权限。
打开媒体文件
您的应用可能允许用户从其照片和视频中选择,例如用于消息附件或个人资料图片。
为支持此功能,请使用照片选择器。照片选择器无需任何运行时权限即可使用。当用户与照片选择器交互以选择要与您的应用共享的照片或视频时,系统会授予对所选媒体文件关联 URI 的临时读取权限。
如果您的应用需要在不使用照片选择器的情况下访问媒体文件,则无需声明任何存储权限:
打开文档
您的应用可能会显示用户创建的文档,无论是在您的应用中还是在另一个应用中。一个常见的例子是文本文件。
在这种情况下,仅为了与旧设备兼容,才声明 READ_EXTERNAL_STORAGE
。将 android:maxSdkVersion
设置为 28
。
根据创建文档的应用,执行以下操作之一:
拍照
用户可能使用预装的系统相机应用在您的应用中拍照。
在这种情况下,不要声明 CAMERA
权限。而是调用 ACTION_IMAGE_CAPTURE
intent 操作。
录制视频
用户可能使用预装的系统相机应用在您的应用中录制视频。
在这种情况下,不要声明 CAMERA
权限。而是调用 ACTION_VIDEO_CAPTURE
intent 操作。
识别运行您的应用实例的设备
您的应用的一个特定实例可能需要知道它正在哪个设备上运行。这对于具有设备特定偏好或消息的应用很有用,例如电视设备和可穿戴设备的不同播放列表。
在这种情况下,不要直接访问设备的 IMEI。事实上,从 Android 10 开始,您就无法这样做了。请执行以下操作之一:
- 使用 Instance ID 库获取您的应用实例的唯一设备标识符。
- 创建一个作用域为您的应用存储的自定义标识符。使用基本的系统函数,例如
randomUUID()
。
通过蓝牙与设备配对
您的应用可以通过蓝牙向另一设备传输数据来提供增强体验。
为支持此功能,不要声明 ACCESS_FINE_LOCATION
、ACCESS_COARSE_LOCATIION
或 BLUETOOTH_ADMIN
权限。而是使用伴侣设备配对。
自动输入支付卡号
Google Play 服务提供了一个库,可让您自动输入支付卡号。您可以不声明 CAMERA
权限,而是使用借记卡和信用卡识别库。
管理电话和短信
Android 和 Google Play 服务提供了库,让您无需声明任何与电话或短信相关的权限即可管理电话和短信。
自动输入一次性密码
为了简化双重身份验证工作流程,您的应用可能会自动输入发送到用户设备的一次性密码以验证其身份。
为支持 Google Play 服务驱动的设备上的此功能,不要声明 READ_SMS
权限。而是使用 SMS Retriever API。
在其他设备上,如果您的应用目标是 Android 8.0 (API level 26) 或更高版本,请使用 createAppSpecificSmsToken()
生成一个应用专用令牌。将此令牌传递给可以发送验证短信的另一个应用或服务。
自动输入用户电话号码
为了提供更高效的销售或支持,您的应用可能允许用户自动输入其设备的电话号码。
为支持 Google Play 服务驱动的设备上的此功能,不要声明 READ_PHONE_STATE
权限。而是使用 电话号码提示库。
过滤电话
为了最大限度地减少对用户不必要的干扰,您的应用可能会过滤垃圾电话。
为支持此功能,不要声明 READ_PHONE_STATE
权限。而是使用 CallScreeningService
API。
拨打电话
您的应用可能提供通过点击联系人信息拨打电话的功能。
为支持此功能,请使用 ACTION_DIAL
intent 操作,而不是 ACTION_CALL
操作。ACTION_CALL
需要安装时权限 CALL_PHONE
,这会阻止无法拨打电话的设备(例如某些平板电脑)安装您的应用。
应用被中断时暂停媒体播放
如果用户接到电话,或发生用户配置的闹钟,您的应用应暂停任何媒体播放,直到您的应用重新获得音频焦点。
为支持此功能,不要声明 READ_PHONE_STATE
权限。而是实现 onAudioFocusChange()
事件处理程序,该处理程序在系统切换音频焦点时自动运行。了解更多关于如何实现音频焦点。
扫描条形码
Android 支持由 Google Play 服务提供支持的 Google Code Scanner API,该 API 允许您在不声明任何相机权限的情况下解码条形码。此 API 有助于保护用户隐私,并降低您需要为条形码扫描用例创建自定义 UI 的可能性。
该 API 扫描条形码并仅将扫描结果返回给您的应用。图像在设备上处理,Google 不会存储任何数据或扫描结果。
如果您的应用需要支持复杂的用例或条形码格式,或者需要自定义 UI,请改用 ML Kit 条形码扫描 API。
重置未使用的权限
Android 提供了多种方式将未使用的运行时权限重置为其默认的拒绝状态。
阅读设计指南。
请求运行时权限
一旦您评估出您的应用需要声明和请求运行时权限,请遵循特定的工作流程进行操作。
阅读设计指南。
解释您的应用为何需要权限
使用 requestPermissions()
会显示一个对话框,指示您的应用要使用哪些权限,但没有解释原因,这可能会让用户感到困惑。
有关何时以及如何显示此对话框的更多详细信息和建议,请阅读设计指南。
处理权限拒绝
您的应用应帮助用户理解在拒绝权限之前和之后拒绝权限的影响。
阅读设计指南。