一、许可权限
一个应用程序必须在程序清单中用
标签来声明所需的权限 。例如,需要发送 SMS 消息的应用程序需要在清单中包含以下行:
...
如果清单中列出了普通权限(即对用户的隐私或设备操作不构成风险的权限),系统会自动将这些权限授予你的应用。
如果清单中列出了危险权限(即可能影响用户隐私权或设备正常操作的权限),例如上述
SEND_SMS
权限,则用户必须明确同意授予这些权限。
1. Request prompts for dangerous permissions — 对于危险权限要求提示
只有危险的权限需要用户同意授权。Android 要求用户授予危险权限的方式取决于用户设备上运行的 Android 版本以及应用的目标 Android 版本。
1.1 Runtime requests (Android 6.0 and higher) — 运行时请求
如果设备运行的是 Android 6.0(API 级别 23)或更高版本,并且应用程序的 targetSdkVersion 是 23 或更高,则安装时用户不会收到任何有关权限的通知。应用程序必须要求用户在运行时授予危险权限。这时,用户会看到一个系统对话框,该对话框包含拒绝和允许按钮,如下左图。
如果用户拒绝权限请求,则在应用下次请求权限时,该对话框将包含一个复选框,该复选框在选中后表示用户不会再次被要求提供权限,如下右图。
即使用户授予你所请求的权限,用户还是可以选择在系统设置中逐个启用和禁用权限。所以你应该始终在运行时检查并请求权限以防止运行时错误(SecurityException)。
1.2 Install-time requests (Android 5.1.1 and below) — 安装时请求
如果设备的 Android 版本是 Android 5.1.1(API 级别 22)或更低,或者该应用的 targetSdkVersion 为 22 或更低,则系统会自动要求用户在安装时为应用授予所有危险权限,如下图。
如果用户点击接受,则授予应用请求的所有权限。如果用户拒绝权限请求,系统将取消应用程序的安装。
如果应用程序更新包含对额外权限的需求,则在更新应用程序之前会提示用户接受这些新的权限。
二、Permissions for optional hardware features — 可选硬件功能的权限
访问某些硬件功能(例如蓝牙或相机)需要应用程序许可。但是,不是所有的 Android 设备都具备这些硬件功能。因此,如果应用程序请求 CAMERA
许可权,则必须在清单中用
标签来声明是否实际需要此功能。例如:
如果你用
android:required="false"
声明了该功能,那么 Google Play 可让你的应用安装在没有此功能的设备上。你必须调用PackageManager.hasSystemFeature()
来检查当前设备是否在运行时具有该功能 ,并在不可用时禁用该功能。如果你不提供
标签,那么当 Google Play 发现应用请求相应的权限时,会假定该应用需要此功能。因此,该应用会无法安装在没有该功能的设备上,就像你在
标签中声明android:required="true"
一样 。
三、自动权限调整
Android 根据 targetSdkVersion 的值来决定是否需要添加权限。如果该值低于权限被添加的版本,则 Android 会自动添加权限。
例如,READ_EXTERNAL_STORAGE
权限从 API 级别 19 开始强制要求,以限制对共享存储空间的访问。如果 targetSdkVersion 是 18 或更低版本,则会在新版 Android 上将此权限添加到应用中。
注意:如果你的应用自动添加了权限,即使实际上不需要它们,Google Play 上的应用列表也会列出这些附加权限。为了避免这种情况并删除不需要的默认权限,请将 targetSdkVersion 设置为尽可能高。
四、权限保护级别
权限分为几个保护级别,保护级别将影响是否需要在运行时请求权限。
1. 普通权限
普通权限涵盖应用程序需要访问沙箱外的数据或资源的区域,但是对用户的隐私或其他应用程序的风险很小。例如,设置时区的权限是普通权限。
系统会在安装时自动授予普通权限许可权,不会提示用户,并且用户无法撤消这些权限。
从 Android 8.1(API 级别 27)开始,以下权限分类为 PROTECTION_NORMAL
:
2. 签名权限
系统在安装时授予应用程序这些权限,但仅当试图使用权限的应用程序与定义权限的应用程序具有相同的证书签名时。
注意:某些签名权限不适用于第三方应用程序。
从 Android 8.1(API 级别 27)开始,第三方应用程序可以使用以下分类为 PROTECTION_SIGNATURE
的权限:
3. 危险权限
危险权限涵盖应用程序需要涉及用户私人信息或资源的区域,或者可能会影响用户的存储数据或其他应用程序的操作。例如,阅读用户联系人的权限是一个危险的权限。
危险权限和权限组如下图:
4. 特殊权限
有几个不属于普通和危险级别的权限。SYSTEM_ALERT_WINDOW
和 WRITE_SETTINGS
特别敏感,所以大多数应用程序不应该使用它们。如果应用程序需要这些权限之一,则必须在清单中声明权限,并请求用户授权。系统通过向用户显示详细的管理界面来响应请求。
五、查看应用程序权限
你可以使用 “设置” 应用程序和 shell 命令 adb shell pm list permissions
查看系统中当前定义的所有权限。对于开发人员,使用 adb '-s'
选项将在一个表格中显示权限,类似用户看到的那样:
$ adb shell pm list permissions -s
All Permissions:
Network communication: view Wi-Fi state, create Bluetooth connections, full
internet access, view network state
Your location: access extra location provider commands, fine (GPS) location,
mock location sources for testing, coarse (network-based) location
Services that cost you money: send SMS messages, directly call phone numbers
...
在模拟器或测试设备上安装应用程序时,你还可以使用 adb -g
选项自动授予所有权限:
$ adb shell install -g MyApp.apk