天天看點

Android6.0及以上動态申請權限詳細講解

不知不覺Android已經到了8.0,記得剛開始6.0剛出來的時候也是看了别人寫的一些文章這麼慢慢的過來了,轉眼已經快要兩年了,感歎時光過的好快,然而不知道自己到底進步了多少。也許因為自己很懶,不善于總結,導緻有時候明明之前見過某個知識點,卻又給忘了。當後來慢慢寫筆記的時候,我發現筆記對自己真的很重要,假如某個知識忘了,一下子就知道自己記過,在某個地方,如果不總結的話,就要花很多時間找資料,是以希望同學都應該整理自己的一個總結方式。好了,還是說說動态申請權限,網上有很多這方面的文章,有的也寫的很好,我想自己記錄下來就成了自己的東西,同時也給剛開始接觸這一塊的同學做做參考。

1,首先還是要先判斷android版本是不是23以及以上版本:

2,動态申請我們所需要的權限,這裡申請三個權限分别為:相機拍照、存儲,撥打電話,然後用一個數組給裝起來:

private String[] mPermission = {
            Manifest.permission.WRITE_EXTERNAL_STORAGE
            , Manifest.permission.CAMERA
            , Manifest.permission.CALL_PHONE
    };
           

3,這裡我們就可以開始調用requestPermissions()方法申請權限了,具體代碼:

if  (Build.VERSION.SDK_INT>=Build.VERSION_CODES.M){
            ActivityCompat.requestPermissions(this,mPermission,mRequesCode);
        }
           

也就這兩行就可以搞定了,其中mRequestCode事先申明的int類型變量,主要是為了處理申請權限後對傳回結果做處理,代碼:

private final  int mRequestCode = ;
           

4,接下來就是對申請權限的傳回結果做處理了,具體就是重寫onRequestPermissionsResult()方法,具體代碼如下:

@Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        //判斷是否是申請權限的請求碼
        if (requestCode == mRequestCode){
            //判斷版本是不是23及以上版本,也可以不做判斷,因為事先已經做了23以後才動态申請權限
            if (Build.VERSION.SDK_INT >=  Build.VERSION_CODES.M){
                //這裡忽略了其他兩個權限,是否申請成功,這裡主要檢驗存儲是否申請成功
                if (grantResults[] != PackageManager.PERMISSION_GRANTED){
                    //shouldShowRequestPermissionRationale判斷使用者是否點選了不再提醒。(檢測該權限是否還可以申請)
                    //如果點選了不再提醒我們提示使用者到引用權限清單手動開啟權限
                    //如果拒絕我們再次向使用者申請開啟存儲權限
                    boolean b = shouldShowRequestPermissionRationale(mPermission[]);
                    if (!b){
                        //不在提示
                        showDialogTipUserGoToAppSettting();
                    }else {
                        //拒絕
                        getPermissions(mStorage,mRequestCode);
                    }
                }
            }
        }
    }
           

其中getPermissions(mStorage,mRequestCode)這個方法是我封裝事先封裝的一個方法,便于多處調用,其實寫法就是這個方法ActivityCompat.requestPermissions(this,mPermission,mRequesCode);傳入要申請的權限以及請求碼,最開始已經寫了,就不再贅述了。

5,接下來就是提示使用者去應用權限清單動态設定權限了,也就是上面的 showDialogTipUserGoToAppSettting()方法,代碼如下:

private void showDialogTipUserGoToAppSettting() {
       AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setPositiveButton("确定", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                Intent intent = new Intent();
                intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
                Uri uri = Uri.fromParts("package", getPackageName(), null);
                intent.setData(uri);
                startActivityForResult(intent, );
            }
        });
        builder.setTitle("存儲權限不可用");
        builder.setMessage("請在應用權限設定中手動開啟存儲權限");
        builder.show();
    }
           

以上代碼應該很好了解就是通過Intent意圖打開對應應用權限清單,接下來就是重寫onActivityResult方法,用于處理是否手動開啟存儲權限成功,具體代碼如下:

@Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == ) {
            if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                // 檢查該權限是否已經擷取
                int i = ActivityCompat.checkSelfPermission(this, mPermission[]);
                // 權限是否已經 授權 GRANTED---授權  DINIED---拒絕
                if (i != PackageManager.PERMISSION_GRANTED) {
                    // 提示使用者應該去應用設定界面手動開啟權限
                    showDialogTipUserGoToAppSettting();
                }
            }
        }
    }
           

最後我們還需要在Manifest中靜态添加以上權限

<uses-permission android:name="android.permission.CALL_PHONE" />
  <uses-permission android:name="android.permission.CAMERA" />
   <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
           

以上代碼已詳細注釋,動态申請權限的主要代碼部分已經詳細貼出,不足之處還望多多諒解,謝謝。