1. 程式人生 > >Android 6.0 以後申請許可權控制相關問題

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() {
                    }
                })