android - 运行权限(permission)
良好的权限体验(permissions best practices)
- 权限请求很容易导致用户流失。
考虑是请求permission还是使用intent
两者各有优缺点
请求权限permission
当执行一个操作时,app能完全控制用户的体验,然而,如此广泛的控制会增加任务的复杂度,并且你需要提供相应的ui。
当app运行时或者安装时(依赖android版本),需要提示用户授予权限,之后,app就可以执行操作而不需要向用户请求额外的交互。然而,如果用户拒绝授予权限,app需要权限部分的功能是没法使用的。
使用意图intent
你不需要为操作设计专门的ui,意图会提供ui。这也意味着你将不能继续控制用户的体验。
如果用户没有设置默认的执行app,系统会弹出提示框供用户选择app。如果用户不指定默认处理程序,也许每次都会出现提示框。
只请求你需要的权限
不要掩埋用户
- eg:一个摄像app,当用户启动app时,请求camera权限是可以被理解的。如果该app同时有分享功能,你不应该在用户启动app时就请求
READ_CONTACTS
权限,而应该在用户执行分享动作时再请求该权限。
解释为什么app需要这个权限
- 调用
requestPermissions()
方法可以显示permissions dialog,但是不会告诉用户为什么需要该权限,有时会让用户很困惑,所以一般情况下,在调用req1uestPermissions()
方法之前想用户解释为啥需要该权限是个不错的决定。
使用adb工具管理权限
1 | // list permissions and status by group: |
声明权限
- 在manifest文件中声明权限
1 | <manifest xmlns:android="http://schemas.android.com/apk/res/android" |
在运行时请求权限(requesting permissions at run time)
Android6.0开始,用户不需要在安装/更新app时直接授予权限,可以在app运行时决定是否授予权限。这种运行时权限也给了用户更多的控制权去控制应用的功能。比如:用户选择授予camera应用访问camera权限而不允许其访问设备的位置。并且用户可以在任何时候通过系统设置收回应用程序权限。
正常权限&危险权限(normal&dangerous permission)
正常权限不会直接对用户的隐私带来风险,如果app的清单文件中声明了一系列正常权限,系统会自动授予这些权限。
危险权限允许app访问用户的机密数据。如果app请求危险权限,用户必须明确的审批是否授予app权限。
注:在android5.1(API level 22)及以前,如果清单文件中列出了危险权限,用户在安装应用的时候决定是否授权,如果不授权则不能安装应用。
在android6.0(API level 23)及以后,app需要在清单文件中列出权限,而且需要在运行时请求危险权限。用户可以授予/拒绝任何权限,甚至在用户拒绝授权之后依然可以执行不受权限限制的功能。
在andorid6.0以后,用户在任何时候都可以收回权限,即使app的目标版本是低级别的。
检查权限 & 请求权限 & 解释为什么需要权限
If your app needs a dangerous permission, you must check whether you have that permission every time you perform an operation that requires that permission. The user is always free to revoke the permission, so even if the app used the camera yesterday, it cannot assume it still has that permission today.
ContextCompat.checkSelfPermission()
If your app needs a dangerous permission that was listed in the app manifest, it must ask the user to grant the permission. Android provides servral methods you can use to request a permission. Calling these methods brings up a standard Android dialog, which you cannot customize.
requestPermission()
To help find situations where the user might need an explanation, Android provides a utility method, shouldShowRequestPermissionRationale()
. This method returns true if the app has requested this permission previously and the user denied the request.
if the user turned down the permission request in the past and chose the
Dont ask agin
option in the permission request system dialog, this method returnsfalse
. The method also returns false if a device policy prohibits the app from having that permission.
1 | // 如果app有该权限返回PackageManager.PERMISSION_GRANED,并且可以执行一些操作; |
请求需要的权限
1 | // 检查是否有用权限 |
处理权限请求响应
onRequestPermissionsResult()
1 | @override |
The dialog box shown by the system describes the permission group
your app needs access to; it does not list the specific permission. For example,
if you request the READ_CONTACTS
permission, the system dialog box just says your app needs access to the device’s contacts. The user only need to grant permission once for
each permission group. If your app requests any other permissions in that group(that are listed in your app manifest), the system automatically grants them. When you request the permission,
the system calls your onRequestPermissionsResult()
callback method and passes PERMISSION_GRANTED
, the same way it would if the user had explicitly granted your request through the system dialog box.
Note: Your still needs to explicitly request every permission it needs, even if the user has already granted another permission in the same group. In addition, the groupping of permission into groups may change
in future Android release. Your code should not rely on assumption that particular permissions are or are not in the same group.
For example, suppose you list both READ_CONATACTS
and WRITE_CONTACTS
in your app manifest. If you request READ_CONTACTS
and the user grants the permission, and you then request WRITE_CONTACTS
, the system immediately grants
you that permission without interacting with the user.
看看这个
1 | For example, suppose you list both READ_CONTACTS and WRITE_CONTACTS in your app manifest. If you request READ_CONTACTS and the user grants the permission, and you then request WRITE_CONTACTS, the system immediately grants you that permission without interacting with the user. |