Android 6.0 動態(tài)權(quán)限

這里我將介紹:
*1. 動態(tài)權(quán)限的基本使用(包括個人理解)*
*2. 動態(tài)權(quán)限使用時,我們需要去注意什么*
先解釋 再上例子
    為了用戶體驗考慮,Android6.0之后,希望當APP運行到需要被授予某項權(quán)限時,才會去提示用戶開啟某項權(quán)限,而不是像以前那樣,直接在啟動頁就全部請求授予,這就要求我們,在需要時提示用戶開啟權(quán)限并對權(quán)限請求結(jié)果進行回調(diào)監(jiān)聽。
  • 需要知道的

    1. 兩個與權(quán)限有關(guān)的變量:

      PackageManager.PERMISSION_GRANTED = 0     //表示授予權(quán)限;
      PackageManager.PERMISSION_DENIED  = -1    //表示權(quán)限未開啟;
      
    2. 運行權(quán)限檢測的三種方式:

          
        方式一:
        public static int checkSelfPermission(Activity activity,String writeContacts) {
            return PermissionChecker.checkSelfPermission(activity, writeContacts);
        }
      
        方式二:
        public static int checkSelfPermission(Activity activity,String writeContacts) {
            return ContextCompat.checkSelfPermission(WelcomeActivity.this,Manifest.permission.CALL_PHONE) != PackageManager.PERMISSION_GRANTED);
        }
      
        方式三:
        public static boolean checkSelfPermission() {
            PackageManager pm = this.getPackageManager();
            for (String auth : authBaseArr) {
              //注意,這里是只要有一個權(quán)限未通過,則返回false,并不能對具體某個權(quán)限做區(qū)分
              if (pm.checkPermission(auth, this.getPackageName()) != PackageManager.PERMISSION_GRANTED) {
            return false;
              }
            }
            return true;
        }
      
      
    3. 請求開啟權(quán)限的彈窗顯示:

      ActivityCompat.requestPermissions(mactivity, new String[] { CALL_PHONE ,CAMERA },REQUEST_CODE);
      

      注意:一次請求多個權(quán)限會有bug,當該次權(quán)限彈窗中有一個未被授予權(quán)限,那么再次執(zhí)行該代碼時,只會一直提示用戶需要獲取第一項權(quán)限,但是此時即使用戶點擊允許,依然會不斷提示請求開啟第一項權(quán)限(實則是需要開啟后邊的某項權(quán)限),所以還是每次都只請求一個權(quán)限穩(wěn)妥?。?! 例如你可以這樣寫:

         private void baiduPermission() {
             boolean canInitBaidu = true;
             // 申請權(quán)限
             if (android.os.Build.VERSION.SDK_INT >= 23) {
               pm = this.getPackageManager();
               if (pm.checkPermission(authBaseArr[0], this.getPackageName())
               != PackageManager.PERMISSION_GRANTED) {
             requestPermissions(new String[] { Manifest.permission.WRITE_EXTERNAL_STORAGE },
                 authBaseRequestCode);
             canInitBaidu = false;
               }
      
               if (pm.checkPermission(authBaseArr[1], this.getPackageName())
               != PackageManager.PERMISSION_GRANTED) {
             requestPermissions(new String[] { Manifest.permission.ACCESS_FINE_LOCATION },
                 authBaseRequestCode);
             canInitBaidu = false;
               }
             }
               if (canInitBaidu) {
             initLoc();
               }
           }
      
    4. 權(quán)限請求結(jié)果監(jiān)聽:

      @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
         @NonNull int[] grantResults) {
         if (requestCode == BaiDuRequest && grantResults.length > 0 && grantResults[0]==-1){
             UtilsW.showMessageOKCancel(mactivity, "溫馨提示",
                 "        當前操作需要開啟“XXX”權(quán)限,您可到設(shè)置的權(quán)限管理中,修改該應(yīng)用的相關(guān)權(quán)限。", null);
         } 
      }
      

      注意:這里使用了grantResults.length > 0 ,這是為防止同時有兩個requestPermissions(new String[] { XXX},RequestCode);被調(diào)用,而引起的crash問題,grantResults[0]==-1(也就是grantResults[0]==PackageManager.PERMISSION_DENIED),表示用戶拒絕了該項權(quán)限,那如果要申請多個權(quán)限怎么辦?,我們可以在第一個成功后再去申請,如下:

      @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
         @NonNull int[] grantResults) {
         if (requestCode == BaiDuRequest && grantResults.length > 0 && grantResults[0]==-1){
             UtilsW.showMessageOKCancel(mactivity, "溫馨提示",
                 "        當前操作需要開啟“定位”和“存儲”權(quán)限,您可到設(shè)置的權(quán)限管理中,修改該應(yīng)用的相關(guān)權(quán)限。", null);
         } else if (ACCESS_FINE_LOCATION.equalsIgnoreCase(permissions[0]) && grantResults.length > 0 && grantResults[0]== 0) {
             ActivityCompat.requestPermissions(mactivity, new String[] {WRITE_EXTERNAL_STORAGE },BaiDuRequest);
         }
      }
      
    5. 對于非Android6.0版本的手機,我們還是可以在AndroidManifest.xml中,直接設(shè)置權(quán)限的(如:<uses-permission android:name="android.permission.READ_PHONE_STATE"/>),在啟動APP時,就會有彈窗提示用戶給予權(quán)限了,二者雖有重復(fù),但誰讓咱們大Android越來越貼心呢;

    6. shouldShowRequestPermissionRationale作用:

      1. 第一次請求權(quán)限時,用戶拒絕了,下一次:shouldShowRequestPermissionRationale() 返回 true,應(yīng)該顯示一些為什么需要這個權(quán)限的說明;
      2. 第二次請求權(quán)限時,用戶拒絕了,并選擇了“不在提醒”的選項時:shouldShowRequestPermissionRationale() 返回 false
      3. 設(shè)備的策略禁止當前應(yīng)用獲取這個權(quán)限的授權(quán):shouldShowRequestPermissionRationale() 返回 false
        注意:上面的:第二次請求權(quán)限時,才會有“不在提醒”的選項,如果用戶一直拒絕,并沒有選擇“不在提醒”的選項,下次請求權(quán)限時,會繼續(xù)有“不在提醒”的選項
    7. 應(yīng)用方面舉例:
      在獲取DeviceID時,我們有很多方法,比如這樣:

      /**
       * 獲取DeviceId (IMEI方式)
       * 其他獲取DeviceId方式: http://blog.csdn.net/u014651216/article/details/50767326 
       */
       public static String getDeviceID(Activity activity) {
         return ((TelephonyManager)activity.getSystemService(activity.TELEPHONY_SERVICE)).getDeviceId();
      }
    

    但是直接這樣調(diào)用會報錯的:

    SecurityException: getDeviceId: Neither user 10282 nor current process has android.permission.READ_PHONE_STATE.
    

    我們需要先判斷是否有讀取電話狀態(tài)的動態(tài)權(quán)限,然后去申請該權(quán)限,如下:

      //電話狀態(tài)讀取的動態(tài)權(quán)限校驗
     if (Utils.checkSelfPermission(this,READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) {
         Utils.showMessageOKCancel(this,"提示:\n\n該應(yīng)用權(quán)限已關(guān)閉。\n開啟方式:點擊確定后,您可到“權(quán)限”中,開啟該應(yīng)用的“電話”權(quán)限。",
             new DialogInterface.OnClickListener() {
                 @Override public void onClick(DialogInterface dialog, int which) {
                     Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS); //未開啟該權(quán)限,引導(dǎo)用戶到開啟該項權(quán)限的頁面
                     intent.setData(Uri.parse("package:" + getPackageName()));
                     startActivity(intent);
                 }
             });
         return ;
    

或者直接再次申請權(quán)限:

 int permissionNum = ContextCompat.checkSelfPermission(this, Manifest.permission.READ_PHONE_STATE);  //檢測某項權(quán)限是否開啟
 if (permissionNum != PackageManager.PERMISSION_GRANTED) { //若該權(quán)限未開啟
     ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_PHONE_STATE}, REQUEST_READ_PHONE_STATE);
 }  //但這種若用戶在第一次彈窗時,勾選了不再提醒,將不會再次有該項提示了

.

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容