现状:
1、当代码编译版本都是 5.0及其以下(API23以下),在Manifest注册了权限。
运行在6.0以下手机没有问题,用户只能在安装的时候选择同意权限,不能修改(不考虑第三方安全软件设置的因素)
运行在6.0及其以上,对于敏感权限用户可以在设置中修改(不需要第三方软件),修改时系统会提示用户“可能会导致无法正常运行”,但还可以修改成功。一旦修改了在API23以下是没有办法在程序内部通过API的方法打开权限。对于非敏感权限安装后无法修改。
2、当代码编译版本都是 6.0及其以上(API23及其以上),在Manifest注册了权限。
运行在6.0以下手机没有问题,用户只能在安装的时候选择同意权限,不能修改(不考虑第三方安全软件设置的因素)运行在6.0及其以上,对于非敏感权限安装后即可获取该权限,也无法修改。对于敏感权限安装后默认是没有权限的。程序内部可以判断、提示用户赋予这些权限。
Android6.0与权限相关的API
//检查是否已赋予某个权限,返回PackageManager.PERMISSION_GRANTED或PERMISSION_DENIED
ContextCompat.checkSelfPermission()
//向用户请求赋予某个(某些)权限
ActivityCompat.requestPermissions()
//向用户请求赋予权限的结果
OnRequestPermissionsResultCallback()
//Google提供的一个人性化的方法,表示是否向用户解释一下权限
ActivityCompat.shouldShowRequestPermissionRationale()
FragmentCompat.requestPermissions()
OnRequestPermissionsResultCallback()
FragmentCompat.shouldShowRequestPermissionRationale()
示例:
public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); readExtStorageDir(); } /** * 读取外部SD卡目录 */ private void readExtStorageDir() { int permissionResult = ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE); if (PackageManager.PERMISSION_GRANTED == permissionResult) {//已有权限 doReadExtStorageDir(); } else {//没有权限向用户索取权限 final String[] permissions = new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}; ActivityCompat.requestPermissions(MainActivity.this, permissions, 100); } } /** * 索取权限的结果 * * @param requestCode * @param permissions * @param grantResults */ @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); if (100 == requestCode) { if (null != permissions) { //是读取外部SD卡的权限&已赋予权限 if (Manifest.permission.READ_EXTERNAL_STORAGE.equals(permissions[0]) && PackageManager.PERMISSION_GRANTED == grantResults[0]) { doReadExtStorageDir(); } } } } private void doReadExtStorageDir() { File storageDir = Environment.getExternalStorageDirectory(); File[] files = storageDir.listFiles(); if (null != files && files.length > 0) { for (File f : files) { Log.e("P", "==>" + f.getName()); } } } }
个性化提示:
当用户拒绝后,但又没有点不再提示,那么这个时候是否给用户一个对权限要求的说明呢?这个时候就用到shouldShowRequestPermissionRationale方法
shouldShowRequestPermissionRationale()的理解:
如果之前请求过并被用户拒绝,那么它会返回 true,如果之前用户已经勾选了不再提示的选项,它会返回 false,同样当设备策略禁止应用拥有这条权限时也会返回 false。第一次请求这个权限也返回false。那么我们需要做的,就是在用户确切需要拒绝这个权限请求前向他解释我们为什么需要,否则当彻底拒绝后(用户在拒绝的时候勾选了不再提示也返回false,但执行requestPermissions()方法不会显示请求权限框),除非用户手动去设置中开启,我们都无法再得到权限了。
/** * 读取外部SD卡目录 */ private void readExtStorageDir() { int permissionResult = ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE); if (PackageManager.PERMISSION_GRANTED == permissionResult) { doReadExtStorageDir(); } else { final String[] permissions = new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}; boolean shouldShowRequestPermission = ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.READ_EXTERNAL_STORAGE); Log.e("P", "shouldShowRequestPermission==" + shouldShowRequestPermission); if (shouldShowRequestPermission) { showMessageOKCancel("向用户解释权限,请用户点击允许!", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialogInterface, int i) { ActivityCompat.requestPermissions(MainActivity.this, permissions, 100); } }); return; } ActivityCompat.requestPermissions(MainActivity.this, permissions, 100); } }
一次请求多个权限:
//定义请求多个权限的名称 String[] permissions = new String[]{Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.CAMERA}; //向用户请求赋予权限 ActivityCompat.requestPermissions(MainActivity.this,permissions,100);
//回调结果 @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); Log.e("P", requestCode + " " + permissions[0] + " " + grantResults[0]); if (100 == requestCode) { if (null != permissions) { for (int i = 0; i < permissions.length; i++) { Log.e("P", permissions[i] + " ===> " + grantResults[i]); if (Manifest.permission.READ_EXTERNAL_STORAGE.equals(permissions[i])) { if (PackageManager.PERMISSION_GRANTED == grantResults[i]) { doReadExtStorageDir(); } } } } } }
权限组
ActivityCompat.requestPermissions()不能传权限组名称,只能传权限名称,同一组的任何一个权限被授权了,其他权限也自动被授权。
敏感权限列表
android.permission-group.CALENDAR(日历数据) |
|
android.permission-group.CAMERA(相机) |
|
android.permission-group.CONTACTS(联系人) |
|
android.permission-group.LOCATION(位置) |
|
android.permission-group.MICROPHONE(麦克风) |
|
android.permission-group.PHONE(电话) |
|
android.permission-group.SENSORS(传感器) |
|
android.permission-group.SMS(短信) |
|
android.permission-group.STORAGE(存储) |
|
相关推荐
Android6.0新特性
Android 6.0版本(Api 23)推出了很多新的特性, 大幅提升了用户体验, 同时也为程序员带来新的负担. 动态权限管理就是这样,一方面让用户更加容易的控制自己的隐私,一方面需要重新适配应用权限.
android6.0的新权限问题说明
之前学习android新特性Material Design时别人分享给我的还不错的笔记,现在拿出来分享给有需要的人。github地址https://github.com/zhaodecang/android5.0-6.0Newfeatures
android 6.0权限申请封装
Android6.0权限DEMO ,可以配合http://blog.csdn.net/coder_giser/article/details/73505793本文体会。
android 6.0以上关于隐私权限的动态申请,需要学习的朋友赶紧下载,
Android6.0权限管理工具类,包括动态申请权限类和跳转到应用详细页面类
一个Android6.0权限处理的Demo,包括使用第三方库 RxPermissions 来实现权限的处理
AndroidAcp * Acp 为 Android check permission 缩写,此库简化Android 6.0 系统复杂的权限操作而编写。 特点 * 支持批量权限申请,不需要重写 onRequestPermissionsResult 方法,Activity 与 Fragment 中用法一致,...
android6.0动态权限处理三部曲
安卓android6.0权限管理,支持同时管理多个权限,权限被拒绝后的处理,并可在设置中进行更改权限.rar,太多无法一一验证是否可用,程序如果跑不起来需要自调,部分代码功能进行参考学习。
因为Android项目targetSdkVersion版本到6.0之后要动态申请一些权限,所以这里简单实现Android6.0动态申请权限,单个或多个。
相比原来新安装的APP系统会一次性授予所有权限和用户无法管理APP权限的不足,新的权限系统不再允许新安装的APP一次性获得所有权限,APP必须在运行时一个一个地询问用户授予权限,甚至有时候都不会主动申请用户授权,...
Android6.0以后加入了新的权限机制,对于部分危险权限,需要开发者在自己的代码中申请,对此封装了一个简单的工具类,以简化开发。
Android6.0后加入了新的权限机制,按照开源的PermissionGen思路对权限申请进行了封装
假设首页需要权限,那么在显示首页前要检测权限是否获取,所以要在onResume()中检测权限是否全部获取。检测权限是否获取为允许权限或禁止权限,当用户点击允许时,显示首页,当用户禁止权限时,进入权限获取页面。...
Android拍照,相册选择图片以及Android6.0权限管理
Android6.0运行时权限处理demo
好用的权限处理android6.0,好东西要拿出来分享,做一个好的搬运工。