首页 > 系统 > Android > 正文

Android 6.0+ 权限申请

2019-11-08 00:22:09
字体:
来源:转载
供稿:网友

Android 6.0+ 权限申请

前言

安卓系统权限(Runtime Permissions)分为两种:普通权限高危权限。对于普通权限的申请,只在APP安装的时候询问一次,而对于高危权限,从Android M(API.23)开始,将会在APP运行时动态申请,这样就可以使用户选择是否授予APP该权限,从而保护用户安全。

运行时权限官方文档解释:https://developer.android.com/training/permissions/requesting.html

注: - 如果设备系统低于6.0,权限只会在APP安装时询问 - 如果targetSdkVersion小于23,权限只会在APP安装时询问


需要动态申请的权限包括以下几种。

注意:同一个组内一个权限被授权了,同组内其他权限也自动被授权

Permission Group Permissions
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_STATE,CALL_PHONE,READ_CALL_LOG,WRITE_CALL_LOG,ADD_VOICEMAIL,USE_Sip,PROCESS_OUTGOING_CALLS
SENSORS BODY_SENSORS
SMS SEND_SMS,RECEIVE_SMS,READ_SMS,RECEIVE_WAP_PUSH,RECEIVE_MMS
STORAGE READ_EXTERNAL_STORAGE,WRITE_EXTERNAL_STORAGE

有图有真相

权限申请

运行时的权限申请

首先判断权限是否已经被申请如果没有申请该权限,则申请权限第一次申请被拒绝(用户也未点击不再询问),如果再次申请权限,需要给用户提示,为什么需要申请该权限,并在用户点击允许后,申请该权限

1.权限判断

int checkSelfPermission = ContextCompat.checkSelfPermission(context, Manifest.permission.CAMERA); if (checkSelfPermission != PackageManager.PERMISSION_GRANTED) { // 没有权限,需要申请 } else { // 有权限了 }

2.权限申请

ActivityCompat.requestPermissions(MainActivity.this,new String[] { Manifest.permission.CAMERA }, REQUEST_STORAGE_PERMISSION);

申请权限的时候,第二个参数为数组格式,也就是说,可以同时申请多个权限,但不建议这么做。REQUEST_STORAGE_PERMISSION为自定义的请求码。

如果在Fragment中申请权限的话,需要调用Fragment的requestPermissions(...)方法,把ActivityCompat.requestPermissions改为requestPermissions。否则会回调到Activity的 onRequestPermissionsResult方法。

3.处理权限申请回调-onRequestPermissionsResult

权限申请的成功或失败之后的操作需要在此回调方法中实现。

@Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { switch (requestCode) { case REQUEST_STORAGE_PERMISSION: if (grantResults[0] == PackageManager.PERMISSION_GRANTED) { // 权限获得成功 } else { // 权限没有获得 } break; } super.onRequestPermissionsResult(requestCode, permissions, grantResults); }因为权限可以同时申请多个,所以回调结果也是以数组的方式返回。此处我们以只请求一个权限为例,如果用户授予权限,则 grantResults[0] = PackageManager.PERMISSION_GRANTED;

4.shouldShowRequestPermissionRationale(…)

1.第一次申请权限的时候,该方法返回false 2.第一次申请权限失败,用户点击拒绝授权后,如果再次申请权限,则该方法返回true 3.如果用户拒绝授权并选择[不再提醒]之后,该方法返回false 4.设备系统禁止APP使用该权限后,返回false

用户拒绝授权权限的时候,系统会提供一个方法让我们解释为什么要申请该权限。因此,我们可以显示一个Dialog向用户再次申请权限。

if (checkSelfPermission != PackageManager.PERMISSION_GRANTED) { if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.CAMERA)) { //向用户解释权限申请原因 AlertDialog.Builder builder = new AlertDialog.Builder(context); builder.setTitle("二维码扫描需要使用相机权限"); builder.setPositiveButton("OK", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialogInterface, int i) { // 权限申请 } }); builder.setNegativeButton("Cancle", null); builder.show(); } else { // 权限申请 } } else { // 有权限了 }

第三方库 EasyPermissions

EasyPermissions简化了Android运行时权限申请、判断、处理的操作步骤 官方文档 https://github.com/googlesamples/easypermissions

1.build.gradle添加依赖

dependencies { compile 'pub.devrel:easypermissions:0.3.0'

注:如果提示Error:Failed to resolve: com.android.support:appcompat-v7:25.1.0,就是需要你升级你的SDK了。

2.检查权限

String[] perms = {Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE}; if (!EasyPermissions.haspermissions(this, perms)) { // 没有权限 }

3.申请权限

@AfterPermissionGranted(REQUEST_CODE_QRCODE_PERMISSIONS) private void requestCodeQRCodePermissions() { String[] perms = {Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE}; if (!EasyPermissions.hasPermissions(this, perms)) { EasyPermissions.requestPermissions(this, "扫描二维码需要打开相机和散光灯的权限", REQUEST_CODE_QRCODE_PERMISSIONS, perms); }else { // 权限已经有了,可以进行其他操作 } }

在第一次申请失败后,如果需要再次申请,会自动弹出Dialog对话框,第二个参数即为对话框的Message,向用户解释为什么申请该权限,提高用户授权的可能性。

AfterPermissionGranted是一个可选的注解,如果有此标签,那么当request值对应的权限申请通过的话会自动调用该方法。

4.实现EasyPermissions.PermissionCallbacks接口,直接处理权限申请的成功或失败

@Override public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); // Forward results to EasyPermissions EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this); } @Override public void onPermissionsGranted(int requestCode, List<String> perms) { // 权限申请成功 } @Override public void onPermissionsDenied(int requestCode, List<String> perms) { // 权限申请失败 }

5.用户点击“不在询问”

如果用户点击了”不在询问“,就无法在通过APP获取权限了,权限只能在设置界面重新授予。这种情况下,你可以使用EasyPermissions.somePermissionPermanentlyDenied(...)方法来显示一个系统对话框,用以打开系统设置界面。

@Override public void onPermissionsDenied(int requestCode, List<String> perms) { // 权限申请失败 if (EasyPermissions.somePermissionPermanentlyDenied(this, perms)) { new AppSettingsDialog.Builder(this).build().show(); } }

当用户从设置界面返回到APP界面的时候,在onActivityResult(...)方法中就可以再次判断权限的授权情况了。

@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == AppSettingsDialog.DEFAULT_SETTINGS_REQ_CODE){ String[] perms = {Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE}; if (EasyPermissions.hasPermissions(this, perms)) { Toast.makeText(MainActivity.this,"权限被用户通过设置界面重新授予了",Toast.LENGTH_SHORT).show(); } } }

这里写图片描述

最后

附上demo地址: http://download.csdn.net/download/u014527323/9762717


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表