Android 6.0 以后申请权限控制相关问题
java.lang.SecurityException: Permission Denial: starting Intent { act=android.media.action.IMAGE_CAPTURE flg=0x3 cmp=com.android.camera/.sdk.activity.CaptureActivity clip={text/uri-list U:content://com.dgbiz.zfxworker.fileProvider/external_storage_root/PicturesJPEG_20181024_175317_.jpg} (has extras) } from ProcessRecord{6691ac3 29310:com.dgbiz.zfxworker/u0a125} (pid=29310, uid=10125) with revoked permission android.permission.CAMERA
首先介绍一下遇到这个问题的原因:
Android开发时,到6.0系统上之后,有的权限就得申请才能用了。
Android将权限分为正常权限 和 危险权限
Android系统权限分为几个保护级别。需要了解的两个最重要保护级别是 正常权限 和 危险权限:
(1)正常权限:
涵盖应用需要访问其沙盒外部数据或资源,但对用户隐私或其他应用操作风险很小的区域。
这些权限在应用安装时授予,运行时不再询问用户。例如: 网络访问、WIFI状态、音量设置等。
(2)危险权限:
涵盖应用需要涉及用户隐私信息的数据或资源,或者可能对用户存储的数据或其他应用的操作产生影响的区域。
例如: 读取通讯录、读写存储器数据、获取用户位置等。如果应用声明需要这些危险权限,则必须在运行时明确告诉用户,让用户手动授予。
如何解决:
RxPermission:6.0以后个人建议统一使用这个来注册权限,此工具的牛逼之处在于6.0之前版本会直接permission.granted赋值true,6.0之后版本会先注册再赋值,省去了我们很多工作。话不多说上代码
注册权限(上面代码是注册多个权限,下面是注册单个的) 不足之处欢迎指点
final boolean[] isPermissionType = {false, false}; RxPermissions rxPermissions = new RxPermissions(activity); rxPermissions.requestEach(Manifest.permission.CAMERA,Manifest.permission.WRITE_EXTERNAL_STORAGE) .subscribe(new Observer<Permission>() { @Override public void onSubscribe(Disposable d) {} @Override public void onNext(Permission permission) { if (permission.name.equals(Manifest.permission.CAMERA)){ isPermissionType[0] = permission.granted; } if (permission.name.equals(Manifest.permission.WRITE_EXTERNAL_STORAGE)){ isPermissionType[1] = permission.granted; } if(isPermissionType[0] && isPermissionType[1]){ Matisse.from(activity) .choose(MimeType.allOf())//图片类型 .theme(R.style.Matisse_Dracula) .countable(false)//true:选中后显示数字;false:选中后显示对号 .maxSelectable(1)//可选的最大数 .capture(true)//选择照片时,是否显示拍照 .captureStrategy(new CaptureStrategy(true, "com.dgbiz.zfxworker.fileProvider"))//参数1 true表示拍照存储在共有目录,false表示存储在私有目录;参数2与 AndroidManifest中authorities值相同,用于适配7.0系统 必须设置 .imageEngine(new PicassoEngine())//图片加载引擎 .forResult(REQUEST_CODE_CHOOSE); }else{ ToastUtil.showText(activity,"权限请求失败",ToastUtil.TWO_SECOND); } } @Override public void onError(Throwable e) {} @Override public void onComplete() {} });
rxPermissions.request(Manifest.permission.WRITE_EXTERNAL_STORAGE) .subscribe(new Observer<Boolean>() { @Override public void onSubscribe(Disposable d) { } @Override public void onNext(Boolean aBoolean) { if (aBoolean) { Matisse.from(activity) .choose(MimeType.allOf())//图片类型 .theme(R.style.Matisse_Dracula) .countable(false)//true:选中后显示数字;false:选中后显示对号 .maxSelectable(1)//可选的最大数 .capture(true)//选择照片时,是否显示拍照 .captureStrategy(new CaptureStrategy(true, "com.dgbiz.zfxworker.fileProvider"))//参数1 true表示拍照存储在共有目录,false表示存储在私有目录;参数2与 AndroidManifest中authorities值相同,用于适配7.0系统 必须设置 .imageEngine(new PicassoEngine())//图片加载引擎 .forResult(REQUEST_CODE_CHOOSE);// } else{ ToastUtil.showText(activity,"权限请求失败",ToastUtil.TWO_SECOND); } } @Override public void onError(Throwable e) { } @Override public void onComplete() { } })