android 6.0 动态权限

来源:互联网 发布:个人域名能备案吗 编辑:程序博客网 时间:2024/05/29 00:30

从简书上看到的,自己写了一下学习下,原链接在最后

作者:李晨玮

链接:http://www.jianshu.com/p/a37f4827079a

來源:简书

著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

权限的分组

在Android6.0(M)之后,对权限进行了分类,大致有这三种:

  • 普通权限
  • 危险权限
  • 特殊权限

普通权限

也就是正常权限,是对手机的一些正常操作,对用户的隐私没有太大影响的权限,比如手机的震动,网络访问,蓝牙等权限,这些权限会在应用被安装的时候默认授予,用户不能拒绝,也不能取消。

普通权限列表:

ACCESS_LOCATION_EXTRA_COMMANDSACCESS_NETWORK_STATEACCESS_NOTIFICATION_POLICYACCESS_WIFI_STATEBLUETOOTHBLUETOOTH_ADMINBROADCAST_STICKYCHANGE_NETWORK_STATECHANGE_WIFI_MULTICAST_STATECHANGE_WIFI_STATEDISABLE_KEYGUARDEXPAND_STATUS_BARGET_PACKAGE_SIZEINTERNETKILL_BACKGROUND_PROCESSESMODIFY_AUDIO_SETTINGSNFCREAD_SYNC_SETTINGSREAD_SYNC_STATSRECEIVE_BOOT_COMPLETEDREORDER_TASKSREQUEST_INSTALL_PACKAGESSET_TIME_ZONESET_WALLPAPERSET_WALLPAPER_HINTSTRANSMIT_IRUSE_FINGERPRINTVIBRATEWAKE_LOCKWRITE_SYNC_SETTINGSSET_ALARMINSTALL_SHORTCUTUNINSTALL_SHORTCUT

对于上面这些权限,需要和Android6.0(M)之前的系统,在AndroidManifest.xml声明即可。

危险权限

其实就是运行中需要处理的权限,也是我们最需要注意的权限,这些权限会关系到用户的隐私或影响到其他应用的运行,这些危险权限,谷歌还做了一个权限组,以分组的形式来呈现:

由于运行权限机制的出现,变得我们需要对新开发的应用去做适配,当然有人会问,那我之前开发的老应用不就完蛋了,是不是运行到6.0系统上就会发生各种崩溃?

其实不会的,谷歌做了良好的适配:
当你的应用targetSdkVersion小于23的时候,就算你运行在Android6.0系统上,它也会默认采用以前的权限管理机制,也就是一刀切。当你的targetSdkVersion大于等于23的时候且在Andorid6.0(M)系统上,它才会采用新的这套权限管理机制。

所以如果你想逃开这个“麻烦”,只要把targetSdkVersion的版本设置为低于23就可以了,不过不建议采用这种方案,该来的总是要来的,随着国产手机ROM的更新,比如小米,华为等也开始有部分机型进行了系统升级,所以这是种趋势。

说了这么多,那么来看下怎么进行Android6.0(M)的权限管理适配吧,其实很简单,只需要记住下面几个API方法就可以:(API23之后提供)

int checkSelfPermission(String permission) 用来检测应用是否已经具有权限

void requestPermissions(String[] permissions, int requestCode) 进行请求单个或多个权限

void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) 请求权限结果回调

public void request(View view) {    //判断当前系统是否高于或等于6.0    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {        //当前系统大于等于6.0        if(ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED){            //具有拍照权限,拍照        }else {            //没有拍照权限,需要进行动态申请            ActivityCompat.requestPermissions(MainActivity.this,new String[]{Manifest.permission.CAMERA},REQUEST_PERMISSION_CAMERA_CODE);        }    }else{        //小于6.0  直接调用拍照    }}

1.这里PERMISSION_GRANTED表示具有权限,PERMISSION_DENIED表示无权限

2.在判断应用没有相关权限的后,我们通过requestPermissions进行权限申请,这里的 String[] permissions是个字符串数组,可以对多个权限进行申请

3.REQUEST_PERMISSION_CAMERA_CODE是个标识码,类似Intent跳转的REQUEST_CODE的,然后我们就可以在onRequestPermissionsResult进行权限申请的回调处理:

上面的那张图,有的朋友应该已经留意到了有个不再提醒的勾选框,如果用户勾选了不再提醒,然后把你拒绝了,那你的应用就GG了,其实这里还有一个API方法:

@RequiresApi(api = Build.VERSION_CODES.M)@Overridepublic void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {    super.onRequestPermissionsResult(requestCode, permissions, grantResults);    if (grantResults.length >= 1) {        int cameraResult = grantResults[0];//相机权限        boolean cameraGranted = cameraResult == PackageManager.PERMISSION_GRANTED;        if (cameraGranted) {            //具有相机权限,调用相机            Log.d("MainActivity", "申请相机权限成功");        } else {            //不具有相关权限,给予用户提醒,比如Toast或者对话框,让用户去系统设置-应用管理里把相关权限开启            Log.d("MainActivity", "没有相关权限");            if (!shouldShowRequestPermissionRationale(Manifest.permission.CAMERA)) {                //如果用户勾选了不再提醒,则返回false                //给予用户提醒,比如Toast或者对话框,让用户去系统设置-应用管理里把相关权限打开                Log.d("MainActivity", "选择不再提醒");            }        }    }}

当用户勾选了不再提醒的框并把你拒之门外了,这个方法的返回值是true,它可以帮助你再一次的提醒用户,你需要这个权限,也是你最后翻身的方法了,哈哈,要坦诚噢~
但是在实际开发中,不得不说的一个坑,由于国内第三方ROM对系统改造的太严重,比如小米,亲测有些机型的这个方法是不起作用的,永远的是返回false,这个时候该怎么办,就要另外想解决方案了。

还有需要注意的一点是上面的权限分组,比如读写文件权限:

WRITE_EXTERNAL_STORAGEREAD_EXTERNAL_STORAGE

它们是属于同一个权限组的,你如果拿到了他们其中的一个权限,那么也同时会有另一个权限,同理,如果你拿到读取通讯录的权限,那么你同时也会拥有写入通讯录的权限,这样就避免了我们在申请相关权限的时候需要些老长老长的权限代码了。

特殊权限

特殊权限,比如:
系统级别对话框:SYSTEM_ALERT_WINDOW
修改系统设置:WRITE_SETTINGS
这2个特殊权限,我们需要在startActivityForResult里调用即可,这2个权限一般是不会用到,会用到的地方要么是黑科技或者是反用户体验的场景,这里就不再做过多描述,有兴趣的朋友自己探索吧。

这里需要另外提到的一个权限:READ_PHONE_STATE
我们可以通过这个权限来获取机器的唯一标识码,很多第三方统计是基于这个标识码来完成统计的,但是在我们应用一开始运行的时候,这个运行权限我们是没有的,在Application里我们也不能对权限进行获取,所以这点也需要我们去注意。

最后

对于一些比较特别的权限,比如文件的读写权限,一般在我们第一次开启APP的时候就要去获取了,假设我们一开始没有获取到这个权限,那么如果我的首页有轮播广告图,这个广告图是网络获取的,做了三级缓存,这样就会到导致磁盘缓存无法写入。这边提供一个解决方法,就是在你引导APP启动的时候,就引导用户去获取权限,当用户拒绝的时候,应该给出弹出框并跳转对应的应用权限管理界面(需要对不同机型进行设置)。

可以参考微信的做法:

启动app,在闪屏页的时候向用户提出权限的申请 存储空间权限,关闭微信电话权限,关闭微信位置权限,关闭微信进入app:发照片时,申请照片权限发语音时,申请麦克风权限用户每次点击拒绝,都弹出自定义对话框,提示用户设置权限
原创粉丝点击