1. 程式人生 > >關於android6.0許可權的問題

關於android6.0許可權的問題

   android6.0使用了新的許可權管理,不再是之前的一刀切作法。對於開發者而言,23之前的許可權管理其實更簡單,但對於使用者來說,其實沒有這麼人性化。所以我猜這就是為什麼在android6.0許可權管理改變的原因。最近在弄一點關於許可權的相關的開發,結果遇到了不少坑,當然這些坑對於老鳥來說也許不是什麼問題,但到於新手來說也許有點借鑑作用。

   要弄清楚這些許可權的執行,首先了解一下android6.0的許可權分類。下面偷來一圖和說明文字。


    在圖中,我們可以看到整個許可權裡,可以分為系統許可權和特殊許可權授權。系統許可權中,又分為normal和dangerous型別。normal:這個許可權型別並不直接威脅到使用者的隱私,可以直接在manifest清單裡註冊,系統會幫我們預設授權的。dangerous:這個可以直接給app訪問使用者一些敏感的資料,不僅需要在manifest清單裡註冊,同時在使用的時候,需要向系統請求授權。值得注意一點,這裡有特殊許可權授權的區別,分別是SYSTEM_ALERT_WINDOW 和 WRITE_SETTINGS,雖然這兩個許可權也是屬於dangerous許可權型別,但是這兩個授權請求方式和其他dangerous許可權是不一樣的,需要特殊處理 。

 normal列表:

對我來說,我要處理的是危險許可權,也就是表格裡面許可權。這裡還一個概念:許可權組。正如表格看到的情況,這些許可權是分組的。有時候,你一旦獲取許可權組裡面WRITE許可權,其他READ的許可權自動獲得。或者獲取SEND許可權,READ許可權也就自動獲得。所以,在android6.0裡面應用程式管理的許可權管理,只看到如簡訊、電話之類的許可權,實際上是一組許可權。一旦獲得,整組的許可權都獲得。如下圖:


正如上圖展示的許可權管理,使用者可以隨時手動開啟或關閉這些許可權。這就是和API小於23的管理模式最大的不同之處了。但android6.0之後,使用這些許可權就要特別小心了,試圖操作沒有許可權程式碼就可能讓程式崩潰,所以使用者不得不在使用這些許可權時檢測是否有授權。

實際應用。

越來越多的裝置升級到android6.0是必然的趨勢。所以開發者們不能不在許可權這事上花些時間來研究下,把應用程式寫好。

一、版本檢測。這段程式碼可以檢查當前系統的版本是執行在android6.0以上:Build.VERSION.SDK_INT >= 23

二、許可權檢測。ContextCompat.checkSelfPermission(thisActivity,Manifest.permission.WRITE_CALENDAR) 。此方法返回int型別,-1代表沒有授權。

三、請求許可權。

// Here, thisActivity is the current activity
//判斷是否己經授權
if (ContextCompat.checkSelfPermission(thisActivity,
                Manifest.permission.READ_CONTACTS)
        != PackageManager.PERMISSION_GRANTED) {

    // 檢測是否需要提示
    if (ActivityCompat.shouldShowRequestPermissionRationale(thisActivity,
            Manifest.permission.READ_CONTACTS)) {

        // Show an expanation to the user *asynchronously* -- don't block
        // this thread waiting for the user's response! After the user
        // sees the explanation, try again to request the permission.

    } else {

        // No explanation needed, we can request the permission.
       //不需要提示,請求許可權。一次可以申請多個許可權

        ActivityCompat.requestPermissions(thisActivity,
                new String[]{Manifest.permission.READ_CONTACTS},
                MY_PERMISSIONS_REQUEST_READ_CONTACTS);

        // MY_PERMISSIONS_REQUEST_READ_CONTACTS is an
        // app-defined int constant. The callback method gets the
        // result of the request.
    }
}

         MY_PERMISSIONS_REQUEST_READ_CONTACTS,這個值是一個int 常量。

四、請求許可權響應。

@Override
public void onRequestPermissionsResult(int requestCode,
        String permissions[], int[] grantResults) {
    switch (requestCode) {
        case MY_PERMISSIONS_REQUEST_READ_CONTACTS: { //這裡是上面那個值,表示某次請求許可權影響
            if (grantResults.length > 0) { //注意這裡中處理了第一個許可權結果,實際上可以返回多個許可權結果的
                  if(grantResults[0] == PackageManager.PERMISSION_GRANTED){
                    //許可權通過
                  }else{
                    //使用者拒絕
                   }
            }
            break;
        }
    }
}

五、特殊許可權。

   Settings.canDrawOverlays() 方法進行判斷之前是否已經授權過了。
針對WRITE_SETTINGS許可權,需要向系統傳送一個ACTION_MANAGE_WRITE_SETTINGS 這樣一個動作,同時可以用Settings.System.canWrite().方法進行判斷之前是否已經授權過了。
具體程式碼:

Intent intent = new Intent(android.provider.Settings.ACTION_MANAGE_WRITE_SETTINGS);  
intent.setData(Uri.parse("package:" + getPackageName()));  
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);  
startActivity(intent);

============================================================================================================================

 以上的資料一般都能從網上查得到,下面說說本人踩過的坑,這些坑跟自己的知識有限有關。

 1、要使onRequestPermissionsResult收到回撥,requestPermissions方法必須與其放在同一個activity。

 2、所有需要用到的許可權必須配置在AndroidManifest.xml。比如你需要一個許可權,READ_SMS, 單單配置 SEND_SMS是不行的。雖然一旦請求了SEND_SMS,READ_SDS也會自動獲得。

3、如果你使用ActivityCompat.requestPermissions()請求,請在activity實現介面implements ActivityCompat.OnRequestPermissionsResultCallback

4、注意點是如果系統許可權彈窗提示框被不再提醒了,需要我們自定義提示彈窗,引導使用者去授權。