android权限的最佳运用

原文作者:Google
原文地址:http://developer.android.com/intl/zh-cn/training/permissions/best-practices.html
原文版权:Creative Commons 2.5 Attribution License
译文作者:Jianan - [email protected]
版本信息:本文基于2016-05-04版本翻译
译文版权:CC BY-NC-ND 4.0,允许复制转载,但必须保留译文作者署名及译文链接,不得演绎和用于商业用途


前言


app的权限请求很容易让用户反感。当用户觉得一个app用起来很麻烦,或者觉得这个app不知道要拿用户的信息去做什么事情时,用户可能会避免使用甚至是完全卸载掉这个app。下面的权限最佳运用方式能够帮助你避免这些糟糕的用户体验。


考虑使用Intent


在很多情况下,app执行一个任务都会有两种可供选择的方式。你可以让你的app亲自请求系统权限来执行一个操作,你也可以让你的app发送一个Intent给其它app来代替执行这个操作。

举个例子,假设你的app需要使用设备的摄像头拍一张照片。你的app可以申请CAMERA权限,这个权限允许你的app直接访问摄像头。请求这个权限之后,你的app才能使用摄像头的API来控制摄像头并拍摄一张照片。这种方式能够使你完全控制整个拍照的过程,还能够将拍照界面UI整合到你的app里面。

然而,如果你不需要像这样完全控制整个拍照流程,那么你可以使用一个ACTION_IMAGE_CAPTURE Intent来请求获取一张图片。当你发送这个Intent请求之后,系统会提示用户选择一个拍照app(如果系统还没有设定默认拍照app的情况下)。之后,用户可以使用选择的拍照app拍摄一张照片,这个拍照app会通过onActivityResult() 方法返回一张图片。

同样的,如果你需要打电话、访问用户通讯录等等,你都可以创建一个合适的Intent来完成这件事情。当然,你都可以直接申请系统权限后直接访问响应的对象进行处理。下面是这两种方式的的优缺点。

如果你申请权限:

  • 当你在执行目标操作的时候,你能够完全控制整个过程中的用户体验。但是,这样全面的控制你的任务流程势必会增加实现的复杂程度,例如你需要设计一个合适的UI。
  • (基于用户的android设备版本)不管是在app运行的过程中还是在安装app的时候,用户会被提示授权至少一次。在这之后,你的app才能直接执行相应的操作,不再需要用户的授权互动。但是,如果用户拒绝授权(或者在过后撤销了授权),那么你的app将完全无法执行对应的操作。

如果你使用Intent:

  • 你不需要为对应的操作设计UI,接收Intent请求的app会提供相应的UI。这意味着你无法控制整个过程的用户体验。用户可能会与你从来没有见过的app进行交互操作。
  • 如果用户没有设定处理该操作的默认app,系统将会提供用户选择一个app。也就是,如果用户没有指定一个默认的操作处理app,每次用户执行响应的操作都会弹出一个额外的对话框。


只申请你需要的权限


每一次你请求一个权限,你都是在强制用户做出一个决定。你应该尽量减少这些请求的次数。如果用户的android设备系统版本是6.0(API Level 23)或者更高,每次用户尝试一个需要申请权限的新功能时,app都必须中断用户的操作要求授权。如果用户的android设备系统是更早的版本,用户就需要在安装app的时候授权每一个app需要的权限。这种情况下,如果权限列表过长或者看起来不合理,用户可能就选择不安装你的app了。基于这些原因,你都应该尽量减少你的app需要申请的权限。

通常情况下,你都可以替代使用Intent来避免申请权限。如果一个功能对于你的app来说并不是非常核心的模块,你就应该考虑让其它的app来完成这个功能,详情请参考上面考虑使用Intent章节。


不要骚扰用户


如果用户的设备运行着android 6.0(API level 23)或者更高的系统版本,在运行app的过程中,用户就必须对每一个需要的权限进行授权。如果你一次向用户申请过多的权限,你就可能骚扰到用户,导致他们放弃你的app。因此,你应该只申请你需要的权限。

在一些情况下,有些权限对于你的app来说是必须的,那么在app一启动的时候就申请这些权限是比较合理的。例如,如果你写了一个拍照app,这个app需要访问设备摄像头。当用户第一次启动这个app的时候,他们就不会惊讶这个app为什么需要申请摄像头权限。但如果这个app还有一个功能是分享照片给用户的通讯录联系人,那你就不应该在第一次启动的时候申请READ_CONTACTS权限。相反的,你应该等到用户使用“分享”功能的时候再申请联系人权限。

如果你的app能提供一个教程,那么最好在教程的结尾解释app需要的必要权限。


解释为什么你需要权限


当你调用requestPermission() 方法后系统弹出的授权对话框会说明你的app需要什么权限,但是不会解释为什么需要权限。在一些情况下,用户可能会对这些权限申请感到疑惑。因此,在调用requestPermission() 方法之前向用户解释你的app为什么需要这个权限是一种很好的做法。

例如,一个拍照app可能需要使用地理位置服务来标识拍摄的照片。一般用户可能不知道一张图片里面可以包含地理位置信息,他们可能就会对拍照app需要获取地理位置信息感到疑惑。类似这样的情况,在app调用requestPermission() 方法之前向用户解释这个功能就很有意义了。

通知用户的一种途径可以是在app的教程指南中列举所有需要的权限解释。在这个教程指南中可以轮流展示app的每一个功能,在展示的过程中解释每一个功能需要的权限。例如,拍照app的教程指南可以演示它的“分享图片给联系人”功能,在演示过程中告诉用户app需要权限来查看用户的联系人。之后,app可以调用requestPermission() 方法来请求用户授权访问对应的功能。当然,不是每一个用户都会查看教程指南,所以你在app的正常操作过程中一样要时时检查权限是否已经授权。


测试所有的权限模式


从android 6.0(API level 23)开始,用户可以在运行过程中授权或者撤销权限,而不是在安装app的时候就要求这么做。这就导致了一个结果,你必须测试你的app在多种多样的权限授权组合模式下的运行情况。在android 6.0之前的版本上,你可以合理的断定你的app如果安装运行起来了,那么app的manifest文件声明的所有权限都已经授权。但在新的权限管理模式下,你不能再这么简单的下结论。

下面的小提示可以帮助你确认在API level 23或者更高版本设备上出现的权限相关的代码问题:

  • 确认你的app当前的权限,以及相关代码的位置。
  • 测试用户经权限保护的服务和数据。
  • 测试已授权或者已被撤权的各种权限组合。例如,一个拍照app可能在manifest文件中列举了CAMERA、READ_CONTACTS、ACCESS_FINE_LOCATION权限。你就必须测试每一种权限的开启或者关闭,确保app能够优雅的处理所有权限的授权或拒绝组合模式。需要注意的是,从android 6.0开始,用户能够授权或者禁止任意app的权限,不管这个app的target API level是22还是更低的版本。
  • 在终端上使用adb工具管理权限:
    • 分组列举权限和状态:

      $ adb shell pm list permissions -d -g
    • 授权或者取消一个或多个权限:

      $ adb shell pm [grant|revoke] <permission-name> ...
  • 分析你的app那些使用权限的service。

猜你喜欢

转载自blog.csdn.net/qinxiandiqi/article/details/51691203