AndroidM中,用户和开发者处理权限的方法将要发生改变,下面就来看一下它们是如何变化的以及这些变化是如何影响用户体验的,最后探讨需要做些什么来实现新的权限模式。

2015GoogleI/O大会发布新的Android版本以来,我们已经见到了全新的Android设计支持库。另外一个重要的事情就是AndroidM中新的权限机制,它也会影响到在M之前的版本中的运行方式。在ribot,我们努力跟上最新的开发方法,因此我决定分析一下Android新的权限模式,来看看到底发生了哪些改变。

当开发Android应用时,权限是一个需要考虑的重要部分。目前,用户虽然有权限意识,但并没有真正的控制权;对于开发者来说,也会遇到是否要在原有权限基础上增加新权限的问题,在应用升级过程中,这些新增权限甚至可能会引起用户讨厌,对升级数据统计产生不良影响。

在当前的权限模式下,用户必须在App使用之前,也就是在安装时对其授予各种各样的权限。这也意味着用户在使用之前需要对该App有一定程度的信任,对于很多用户来说,这可能是一个决定他们是否安装该App的关键因素。

就个人而言,在安装App时,经常遇到这种情况。最近遇到的一个案例是这样的,在参加一个音乐节时,有一个用来查看表演时间的配套App,我开始以为这是非常棒的,所以立即打开GooglePlay来下载,当点击安装之后,出现了一个让人相当惊讶的对话框,如下图:

我很不解,为什么这个App(它仅有的功能就是展示节目表演时间以及一些详情内容)需要我的联系人信息、需要访问我的位置、需要访问我的文件、访问日历以及其他一些权限,结果很显然,这个应用会丢掉一个安装用户。在我知道该应用获取那么多权限的目的或者给我一些信任它的理由之前,我是不会安装这个App的,类似这种事情还发生过很多次。

在某些情况下,用户会对上述遭遇让步,好像被迫安装一个应用似的。以Facebook应用为例,很多人知道并且喜欢Facebook,虽然它也有巨多的需求权限列表,但Facebook已经在用户中建立起了良好的信任,因此用户在安装其应用时,往往会忽略其征求的大量权限。

虽然可能只有一部分权限是Facebook主要功能真正需要的,这个权限列表里可能有一些是我们并不太想授权的。下图是Facebook权限需求列表:

AndroidM中,通过在需要时动态申请权限可以使得上述权限列表大大减少。

例如,当用户想要拍照时再申请camera权限将会显得合理。这样一来,如果用户从不使用Facebook应用的某个功能,那么也就不需要在安装时授予对应的权限。

权限分组

权限现在被分成8组:

AndroidM中,权限将会被归到一个父类分组下面,父类分组是当用户申请一个特定的权限时需要用到的。例如,如果你申请READ_CALENDAR权限,那么用户将被提示授予Calendar权限。

每一个权限分组都包含若干独立的权限,具体可分为如下几组:

你可能会发现这里不再有网络权限,不错,一件非常棒的事情就是你不再需要请求网络权限,这意味着你可以发起网络请求而不必询问用户该权限是否可用。这是因为网络权限(以及其他一些权限)现在被设计为PROTECTION_NORMAL,如果他们在manifest配置文件中声明,那么它们将自动地授权给应用。

运行时权限

在应用商店安装App的流程可能会常常觉得有一点破碎,点击安装实际上并不会安装应用,在真正的安装执行之前,需要接受一系列的权限。庆幸的是,在安装时请求权限的事情将不会再发生,因此当你在GooglePlay点击安装时,将会真正地安装应用,而不是提示你先接受一系列的权限。

在运行的时候,当执行特定功能时需要申请权限,这时候需要检查系统来确定是否你已经拥有该权限。如下图所示,系统将做一系列检查,然后响应用户并继续后续流程。

*从第1步开始,首先需要检查是否已经拥有执行操作所需的权限(可以有多个权限)。

*2步,系统将会检查是否已经拥有该权限,通过调用checkSelfPermission()可以完成该操作。

*如果已经拥有该权限,可以直接走到第6步来处理结果,反之系统将继续检查用户是否已经申请该权限(第3步)。如果用户之前没有申请过该权限的话,将会弹出一个标准的权限申请对话框(第4步)。

*否则,如果用户没有在申请权限时选择“不再询问”,那么对话框将仍会显示给用户,并有一个复选框来设置“不再询问”。

*如果选择了“不再询问”,那么结果将会在onRequestPermissionsResult()方法中返回,并在内部对结果做特定处理(第6步)。

当我们申请权限时,将会把一个对话框呈献给用户,提示他们对特定功能授权或者拒绝,如下图:

用户第一次申请权限时将会显示上述对话框,如果用户接受了请求,则应用可以获取权限来执行相关操作;如果用户拒绝了请求,如之前描述的那样,将会导致两种不同的结果。

当用户第一次拒绝了权限申请,对话框将会关闭,我们需要在视觉上以某种方式提醒用户,例如,当申请Contacts权限被拒绝时,应该在原本打算显示联系人列表的地方显示一个错误占位符,来说明这是由于拒绝权限申请的结果。

注意:当第一次权限申请被拒绝时并没有任何处罚,因此不需要做任何形式的双重提醒。

如果需要,可以使用shouldShowRequestPermissionRationale()方法来检查应用是否已经申请过指定权限并被拒绝。这将有助于在申请权限之前正确地在屏幕上显示错误状态以及在再次申请权限之前解释需要的原因。

当第一次申请权限被拒绝之后再次申请时,用户将可以设置“Neveraskagain”这个复选项。

如果用户勾选该项,那么你将不能再次申请访问该权限,除非卸载重装。我们对此无能为力,因此如果这个权限对于App的功能特别重要,就需要在第一次请求权限时清楚地说明为什么需要该权限。

让用户清楚地了解为什么App需要特定的权限来完成某个功能是非常重要的,这是另一个原因。一种常用做法是提供某种形式的引导或欢迎界面,明确列出应用的功能,这可以真正地帮助用户明白为什么它们需要权限,同时也希望用户给予这些功能更多的信任。

另外也可以在一次请求下,申请多个权限,一般情况下,并不需要这么做除非特殊需要,如启动一个App,它必须在拥有所需权限时才能继续正常操作,例如,一个短消息应用启动之后,为了实现其功能就需要访问SMSContacts的权限。

一次请求多个权限会在同一个对话框中依次展示,如下图:

这个对话框除了多出了请求权限的个数之外,其他跟请求单个权限的对话框一样漂亮。权限数量可能是影响用户授权与否的一个关键原因,如果申请很多个权限,用户看到后可能会对体验产生负面影响从而导致拒绝所申请的权限。

在检查这些权限之前,首先需要检查App运行的系统版本名称,如果版本名称为AndroidM(“MNC”),那么就可以继续调用相关的权限方法。

请求单个权限

如果要申请单个权限,可以简单地调用checkSelfPermission()方法来判断应用是否已经拥有了该权限。在下面的代码示例中,如果应用没有该权限,则需要调用requestPermissions()方法来申请,并传递一个包含所申请权限的数组作为参数。

requestPermissions()方法被调用后,会弹出一个提示用户响应权限申请的对话框,用户响应之后,onRequestPermissionsResult()方法会被回调,在这个方法里,可以检查用户对权限申请的响应并作出对应的处理。

在这个示例中,可以从grantResults数组中获取权限级别,因为我们只申请了一个权限,所以访问数组的第一个元素即可。如果权限被许可了,则应该执行需要该权限的操作来反馈给用户。如果权限被拒绝了,我们应该提示一些信息,通知用户应用在没有该权限时无法执行某些操作。

请求多个权限

请求多个权限的情况跟请求单个权限略微不同,在下面的示例中,首先检查是否已经拥有了某个权限,如果没有,则把它添加到期望权限列表中,然后将期望权限列表作为参数传入到requestPermissions()方法中。

针对AndroidM声明权限

如果想要应用运行在AndroidM的设备上时才申请权限,可以通过如下方法只为M版本声明权限:

<uses-permission-sdk-mandroid:name="android.permission.ACCESS_FINE_LOCATION"/>

这种声明权限的方式跟普通权限声明一样,但它仅当运行在AndroidM上时才会检查该声明,这意味着可以更新应用的版本而不用担心M之前的版本发生编译错误,这个权限仅对AndroidM有效。

权限设置

在手机的设置中,用户可以查看和编辑授予应用的权限,如下图所示,权限被归类到分组:

选择一个分组将会跳转到一个应用列表,列表中的应用都在manifest文件中指定了该权限,如下图:

用户还可以通过Settings>Apps>YourApp单独访问某个应用的权限,会得到如下一个应用权限及状态列表:

用户可以在任何时候访问这些设置,打开或关闭某个权限,也正因为如此,如果应用需要某个权限时可能会引起问题,所以每次在执行功能时一定要先检查是否已经拥有了对应的权限。

如果某个权限曾经被授权,后来用户关闭了该权限,那么你的应用需要能够再次检查并且提供未选中状态的“不再询问”复选框。

对于使用M之前版本编译的应用,同样可以在设置界面关闭掉权限,如果用户这么做,我们就无法在应用内部申请权限,因为这个功能仅适用于M版本。如果用户试图关闭一个pre-M版本编译的应用的权限时,需要弹出一个对话框来提示他们这么做将会产生怎样的后果。

M版本之前的应用

使用M之前SDK编译的应用会以相同的表现方式运行,但是可能会发生几个异常。

在安装时,权限的行为完全一致,会弹出一个权限列表对话框,用户可以查看并接受这些权限以便将应用安装到设备上。此时,这些权限已经被授权,所以在运行时并没有发生授权行为,这些权限已经在安装时获得。应用更新时也是这样,任何新的权限都会在用户安装应用时授权。

如前文所述,用户仍然可以进入系统设置页面禁用某些权限,虽然用户会被提示一些错误信息,但是如果用户依然决定要禁用某个权限,那么将不可能在应用运行时重新申请。一旦用户做了这样的禁用,重新申请权限将会返回空的状态数据,例如:

*请求联系人列表会返回“NoContacts”

*请求用户当前位置会返回“Locationnotavailable”

*试图保存联系人时将会返回“ContactSaved”,而实际上联系人并没有真正保存

因此,如果是这样的话,在pre-M版本编译的应用中,正确处理当禁用权限引起的错误状态是非常重要的。

你还需要权限吗?

需要记住,有些功能可以使用Intent完成,而不一定需要请求权限来实现。这会大大提高用户体验,因为当应用需要完成特定功能时就不会再弹出权限申请对话框提醒用户授权。

*ACTION_INSERT——只要它能满足你的需求,它可以代替一些权限。设置MIMETypeIntentExtras可以允许插入任何日历事件或联系人,这可能将不再需要任何CalendarContacts权限。

*ACTION_IMAGE_CAPTURE——如果你的应用只是需要拍一张照片(如果视频的话,请参考:ACTION_VIDEO_CAPTURE)然后返回结果,那么这个action可以满足需求。图片可以通过使用InentExtras(EXTRA_OUTPUT)返回到指定位置,甚至这个intent可以完全取代对Camera权限的需求(更多参考:INTENT_ACTION_STILL_IMAGE_CAMERA)。

*ACTION_PICK——这个action可以用来选择一个联系人或联系人中的特定数据(如邮件、电话号码、地址)。当使用这个action时,应用会获得访问用户联系人的临时权限,从而可以不再需要READ_CONTACTS权限。

*ACTION_VIEW——当和ACTION_VIEW一起使用时,这个action可以用来查看一个选中的联系人URI详情,而不需要请求Contacts权限。该action还可以通过传入一个有效的地理位置作为Intent数据来启动一个地图。

*ACTION_EDIT——同样,跟ACTION_VIEW一起使用,返回的联系人URI可以用来编辑联系人详情。

*ACTION_DIAL——此action可以使用一个电话号码打开拨号界面,虽然需要用户自己来按下拨打按钮(参考ACTION_CALL),但是它不需要任何电话相关的权限。

*ACTION_SENDTO——这个action可以用来写短消息并将其发送到一个特定的电话号码。如果这样可以满足需求,则不再需要请求SMS权限来发送短消息(更多参考:ACTION_SENDACTION_SEND_MULTIPLE)。

最佳实践

在使用新的权限模式时,让用户愉快地使用你的应用而不为各种功能引发的权限申请而困扰,这里有一系列不错的实践原则可以遵循:

*帮助用户准确地了解申请权限的原因,这可以真正地提高应用的用户体验。应用启动时是一个不错的时机,可以来展示应用的功能,这可以帮助用户明白为什么需要授权来才可以完成特定的操作。

*一定要在需要的时候才申请权限,什么时候申请权限是很重要的,最好在看起来合理的时候请求权限。例如,如果你的应用需要Camera权限来拍照,那么最好当用户想要拍照时(如按下“拍照”按钮)再申请此权限。

*如前文所述,尽量避免一次请求多个权限,因为这会产生很差的用户体验。如果这些权限确实对应用的功能很重要,则可以在应用首次启动时请求多个权限,否则,应当在需要时再申请。

*当用户授予申请的权限后,应该反馈给用户一些信息,例如,当进入地图界面,用户授予Location权限后,应该获取用户位置并将其显示在地图上。

*如果可以使用IntentAction完成某个功能,从而可以避免申请权限,那么请一定要这样做,尽可能地拥有最少的权限对于提高应用的整体用户体验是很有必要的。

后会有期

这一切就是这么简单!当使用新的权限模式时一定要创造最佳的用户体验,遵循上述最佳实践原则可以帮你做到这点。不要忘记去真正地测试这些新的权限方法,无论是手动测试还是自动化测试,记得测试androidM版本及M之前版本编译的应用。最重要的是,从中获得乐趣!

原文地址:

https://medium.com/ribot-labs/exploring-the-new-android-permissions-model-ba1d5d6c0610

更多相关文章

  1. [置顶] Android学习及如何利用android来赚钱
  2. Ubuntu下android学习——(2)Android系统构架分析和应用程序目录结
  3. Android应用程序资源管理器(Asset Manager)的创建过程分析
  4. 开发者大会传递信号:Android开发者将越来越赚钱?
  5. 万树IT:你的Android不好用的原因就是这些!
  6. Android(安卓)Design(设计)\Get Started(从这里开始)\Creative Vis
  7. 如何学习Android及如何利用android来赚钱
  8. Android应用程序四大组件
  9. Android的开源隐忧:品牌稀释 代码分裂

随机推荐

  1. 将Android(安卓)Activity设置成对话框样
  2. android 更改密码显示风格
  3. 高仿Android(安卓)点心桌面皮肤实现方式
  4. 如何解决App无法收到android开机广播
  5. 安卓巴士Android开发神贴
  6. windows下载android源代码
  7. Android(安卓)使用 TableLayout 布局拉伸
  8. Android(安卓)Gesture Detector
  9. Android(安卓)CTS 测试总结
  10. android studio 3.6.0 绑定视图新特性的