ACCESSAndroid 6.0 在运行时呼吁权限

1. Android 6.0 在运转时呼吁权限介绍

从 Android 6.0(API 级别
23)初步,用户开始在动用运行时向其授予权限,而不是在采纳设置时予以。此模式可以简化使用设置过程,因为用户在装置或更新应用时不需要予以权限。它还让用户能够对利用的效应拓展更多控制;例如,用户可以采取为相机应用提供相机访问权限,而不提供设备地方的走访权限。用户能够随时进入应用的装置页面修改权限。

1.1、为何需要周转时呼吁权限

小米上的App都是默认下载安装的,然后运行App时需要如何权限就弹窗向用户申请,这对用户来说就非凡好。因为用户不想给App权限就不给,而Android
6.0从前是这般的,我下载了一个App安装,系统就弹出这多少个App需要采纳的整个的权能,就给自己看一下,我需要这些App
的话,只好同意所有的权限都给这多少个App,要么我不设置这么些App。

1.2、 Android权限介绍

系统权限分为两类:好端端权限高危权限

健康权限不会从来给用户隐私权带来风险。假如你的使用在其manifest中列出了正规权限,系统将机关赋予该权限。

凶险权限会授予应用访问用户机密数据的权位。如若您的接纳在其manifest中列出了例行权限,系统将自动赋予该权限。如若您列出了危亡权限,则用户必须精通批准你的选取使用这一个权限,也就是说manifest文件中定义的责任险权限将不会随着安装自动赋予。

表 1.高危权限和权限组。

权限组权限

CALENDAR
: 
READ_CALENDAR

WRITE_CALENDAR

CAMERA 
: 
CAMERA

CONTACTS 
: 
READ_CONTACTS 
 
WRITE_CONTACTS 
, 
GET_ACCOUNTS

LOCATION
: 
ACCESS_FINE_LOCATION 
, 
ACCESS_COARSE_LOCATION

MICROPHONE
: 
RECORD_AUDIO

PHONE 
 
READ_PHONE_STATECALL_PHONEREAD_CALL_LOG
WRITE_CALL_LOGADD_VOICEMAILUSE_SIPPROCESS_OUTGOING_CALLS

SENSORS 
: 
BODY_SENSORS

SMS 
: 
SEND_SMSRECEIVE_SMSREAD_SMSRECEIVE_WAP_PUSHRECEIVE_MMS

STORAGE 
: 
READ_EXTERNAL_STORAGEWRITE_EXTERNAL_STORAGE

从上图中我们可以见到,Android系统把危险权限分了9大组,这样也是为了简化权限的申请机制。假设你报名了android.permission.READ_CONTACTS读取联系人的权位,这就是说6.0
系统就会把这一组中其他的权力也卷入给您
。我觉着这多少个和iOS的隐私管理机制分外相似,在iOS系统设置的“隐私->通讯录”中可以看到,假若你给一个App通讯录的权位,那么这一个App既可以读也得以写的

Android 6.0里面唯有危险权限才需要周转时得到的

1.3、android系统对权限的处理场景分析

一旦设备运行的是 Android 6.0(API 级别
23)或更高版本,并且应用的targetSdkVersion
23
或更高版本,则运用在运转时向用户请求权限。用户可每一日调用权限,因而利用在历次运行时均需检查自己是否具有所需的权位。

要是设备运转的是 Android 5.1(API 级别
22)或更低版本,并且应用的targetSdkVersion
22
或更低版本,则系统会在用户安装使用时要求用户授予权限。假如将新权力添加到革新的利用版本,系统会在用户更新应用时要求予以该权限。用户要是设置使用,他们撤消权限的唯一办法是卸载应用。

假若设备运行的是 Android 6.0(API 级别
23)或更高版本,并且拔取的targetSdkVersion
22
或更低版本,这时Android系统会把你申请的万事权力都给您用户仍旧得以进入App的装置界面把权力关闭!

比如以下图片中用户在android6.0的版本的设置中把权限关闭,此时您的权位就用持续了。那么程序需要考虑对6.0及以上版本的非常,具体参考上边的(android.support.v4.content.PermissionChecker)。

值得注意的是Android系统有一套活动权限调整的建制,我们通晓android每一趟sdk升级有可能会加盟新的权限,而你的app已经发表到用户手机上安装了,除了提拔不能修改Androidmanifest文件了,此时您可能担心自己的app可以在这些新的sdk版本的无绳电话机上运行如常吧,其实android已经考虑了那种气象,Android
将基于为targetSdkVersion特性提供的值决定运用是否需要权限。假如该值低于在其中添加权限的本子,则
Android 会为App自动添加该权限。

比如,API 级别 4
中进入了WRITE_EXTERNAL_STORAGE权力,用以限制访问共享存储空间。尽管你的targetSdkVersion
3 或更低版本,则会向改进 Android 版本设备上的利用添加此权限。

2、怎么着申请权限

提请权限过程包括以下多少个步骤:

自我批评权限

呼吁权限

拍卖权限请求响应

表达应用为啥需要权限

2.1、检查权限

假如你的施用需要危险权限,则每一次执行需要这一权力的操作时你都不可能不检查自己是不是有所该权限。用户从来可以自由调用此权限,由此,即便使用今天利用了相机,它不可能如果自己前天仍有所该权限,因为用户可能在装置里面关闭了。

要检查你是不是拥有某项权限,请调用ContextCompat.checkSelfPermission()办法。例如,以下代码段展现了怎样检查
Activity 是否持有在日历中举办写入的权限:

// 假若thisActivity是当前屏幕最前端正在和用户交互的activity

int permissionCheck = ContextCompat.checkSelfPermission(thisActivity,

        Manifest.permission.WRITE_CALENDAR);

一旦运用拥有此权限,方法将回来PackageManager.PERMISSION_GRANTED,并且应用可以继承操作。假使利用不拥有此权限,方法将回来PERMISSION_DENIED,且使用必须领悟向用户要求权限。

也可以使用ActivityCompat,它们六个的checkSelfPermission方法是同一个,因为ActivityCompat继承自ContextCompat,而checkSelfPermission是ContextCompat中的方法。

检查权限会有一部分专门的题目亟需小心,首要有以下三个:

如果App的targetSdkVersion小于23同时运行在Android
6.0系统上,怎么去检测用户关闭了权力呢?

国内有些手机厂商自己定制了手机权限管理(例如:黑莓),普通的checkSelfPermission已经不可靠了,该咋样处理?

问题一:

android.support.v4.content.PermissionChecker可以帮我们解决这一个题材。那多少个类的文档是如此描述的:

For apps targeting API lower
thanandroid.os.Build.VERSION_CODES.Mthese permissions are always
granted as such apps do not expect permission revocations and would
crash. Therefore, when the user disables a permission for a legacy app
in the UI the platform disables the APIs guarded by this permission
making them a no-op which is doing nothing or returning an empty result
or default error.

翻译一下是:

当app的targetsdkversion小于23的时候,这么些权限默认都会活动给当下app,但要是app没有考虑在6.0装备中被用户主动废除该权限的境况,那么可能引致app的倒台。于是app在应用该权限过程中系统权限检查时一旦这一个权力被用户撤消了,那么相应请求的API会什么都不做或者返回一个空的结果,或者出错。

PermissionChecker.checkSelfPermission主意就是用以检查App自身有没有某一个权力,这些法子的归来结果只有两种:

PERMISSION_GRANTED: 已授权

PERMISSION_DENIED: 没有被授权

PERMISSION_DENIED_APP_OP: 没有被授权

PERMISSION_DENIEDPERMISSION_DENIED_APP_OP都代表一贯不被授权,可是它们的界别就在于targetSdkVersion的值,如果targetSdkVersion小于23,就返回PERMISSION_DENIED_APP_OP,否则就回来PERMISSION_DENIED

据此,假如你的App的targetSdkVersion小于23,可是运行在Android
6.0及以后的序列上,你可以用下边的代码来检测app是否有某个权限:

PermissionChecker.checkSelfPermission(context, permission) ==
PermissionChecker. PERMISSION_DENIED_APP_OP

问题二:

进口很多有线电话在google以前早已做了和谐的权位管理,例如一加,所以这时利用ContextCompat的checkSelfPermission方法就是回到PackageManager.PERMISSION_GRANTED也恐怕不标准。倘使出现这种意况我们需要做一次特别处理,此时我们需要动用android的隐藏API
AppOpsManager

AppOpsManager合法的演讲是系统里面采取,不提供给APP开发者使用。一个一加设备万分判断的代码如下:

@TargetApi(Build.VERSION_CODES.M)private static boolean
hasSelfPermissionForXiaomi(Context context, String permission) {   
AppOpsManager appOpsManager = (AppOpsManager)
context.getSystemService(Context.APP_OPS_SERVICE);    String op =
AppOpsManager.permissionToOp(permission);    if (!TextUtils.isEmpty(op))
{        int checkOp = appOpsManager.checkOp(op, Process.myUid(),
context.getPackageName());        return checkOp ==
AppOpsManager.MODE_ALLOWED &&
ActivityCompat.checkSelfPermission(context, permission) ==
PackageManager.PERMISSION_GRANTED;    }    return true;}

2.2、请求权限

只要你的施用需要采取manifest文件中列出的高危权限,那么,它必须要求用户授予该权限。Android
为你提供了多种权力请求格局。调用这个模式将显示一个业内的 Android
对话框,然则,您不可能对它们举办自定义。

假定下面的权限检查手续中结果是运用尚无所需的权杖,则动用必须调用一个requestPermissions()主意,以请求适用的权位。应用将传递其所需的权限,以及你指定用于识别此权限请求的整型请求代码。此措施异步运行:它会立马回到,并且在用户响应对话框之后,系统会动用结果调用应用的回调方法,将利用传递的一致请求代码传递到requestPermissions()

唤醒用户授予或拒绝权限的体系对话框如下:

以下代码可以检查采用是否享有读取用户联系人的权力,并遵照需要请求该权限:

// 这里的 thisActivity 是时下屏幕最前端正在和用户交互的activity

if (ContextCompat.checkSelfPermission(thisActivity,

                Manifest.permission.READ_CONTACTS)

        != PackageManager.PERMISSION_GRANTED) {

    // 是否需要给用户一个分解?

    if
(ActivityCompat.shouldShowRequestPermissionRationale(thisActivity,

            Manifest.permission.READ_CONTACTS)) {

        //
彰显给用户需要那个权力的说辞,这多少个需假诺异步的(不可能围堵当前线程去等待用户的响应!)
,在用户看完这么些解释后,继续品尝请求那些权限

    } else {

        // 不需要解释, 我们得以开端请求权限

        ActivityCompat.requestPermissions(thisActivity,

                new String[]{Manifest.permission.READ_CONTACTS},

                MY_PERMISSIONS_REQUEST_READ_CONTACTS);

        // MY_PERMISSIONS_REQUEST_READ_CONTACTS
这一个是app定义的整形常量,用于标识一个请求,回调方法中会获得这么些请求对应的结果

    }

}

:当您的选择调用requestPermissions()时,系统将向用户展示一个正规对话框。您的利用无法配备或改变此对话框。若是您需要为用户提供其他信息或表明,您应在调用requestPermissions()事先进行,如解释应用为啥需要权限。

2.3、处理权限请求响应

当使用请求权限时,系统将向用户体现一个对话框。当用户响应时,系统将调用应用的onRequestPermissionsResult()模式,向其传递用户响应。您的利用必须覆写该措施,以询问是否已拿到对应权限。回调会将你传递的平等请求代码传递给requestPermissions()。例如,假如运用请求READ_CONTACTS做客权限,则它或许使用以下回调方法:

@Override

public void onRequestPermissionsResult(int requestCode,

        String permissions[], int[] grantResults) {

    switch (requestCode) {

        case MY_PERMISSIONS_REQUEST_READ_CONTACTS: {

            // 要是授权撤废 这一个结果数组是空

            if (grantResults.length > 0

                && grantResults[0] ==
PackageManager.PERMISSION_GRANTED) {

                // 权限已经授权, 很棒!可以继续联系人相关的操作了

            } else {

                // 权限被驳回了,很糟糕! 禁用和该权限相关的功效

            }

            return;

        }

        // 其余的’case’ 代码去处理其他的权柄请求回调

    }

}

注意:

当系统要求用户授予权限时,用户可以采纳提示系统不再要求提供该权限(即勾选对话框里的不在指示)。这种境况下,无论采纳在什么样时候利用requestPermissions()重复要求该权限,系统都会应声拒绝此恳请。系统会调用您的onRequestPermissionsResult()回调方法,并传递PERMISSION_DENIED

2.4 解释应用为何需要权限

在某些意况下,您或许需要支援用户了然您的应用为啥需要某项权限。例如,倘诺用户启动一个录像应用,用户对运用要求拔取相机的权杖可能不会感到吃惊,但用户可能不能精通为何此选取想要访问用户的岗位或联系人。在伸手权限以前,不妨为用户提供一个表明。请牢记,您不需要通过解释来说服用户;如若您提供太多解释,用户可能发现使用令人失望并将其移除。

您可以拔取的一个方法是仅在用户已拒绝某项权限请求时提供解释。假如用户继续尝试接纳需要某项权限的效能,但持续拒绝权限请求,则可能注解用户不领会应用为什么需要此权限才能提供有关职能。对于这种场地,相比较好的做法是呈现解释。

为了帮衬查找用户可能需要解释的动静,Android
提供了一个实用程序方法,即shouldShowRequestPermissionRationale()。假设应用以前请求过此权限但用户拒绝了请求,此措施将回到true

:如若用户在过去驳回了权力请求,并在权力请求系统对话框中挑选了Don’t
ask
again
采纳,此方法将再次回到false。假设设备正式禁止行使拥有该权限,此形式也会回到false

That’s all
感谢阅读,原文地址http://www.huahuaxie.com/android-6-0-runtime-permission/

相关文章