關於android6.0許可權的問題
android6.0使用了新的許可權管理,不再是之前的一刀切作法。對於開發者而言,23之前的許可權管理其實更簡單,但對於使用者來說,其實沒有這麼人性化。所以我猜這就是為什麼在android6.0許可權管理改變的原因。最近在弄一點關於許可權的相關的開發,結果遇到了不少坑,當然這些坑對於老鳥來說也許不是什麼問題,但到於新手來說也許有點借鑑作用。
要弄清楚這些許可權的執行,首先了解一下android6.0的許可權分類。下面偷來一圖和說明文字。
在圖中,我們可以看到整個許可權裡,可以分為系統許可權和特殊許可權授權。系統許可權中,又分為normal和dangerous型別。normal:這個許可權型別並不直接威脅到使用者的隱私,可以直接在manifest清單裡註冊,系統會幫我們預設授權的。dangerous:這個可以直接給app訪問使用者一些敏感的資料,不僅需要在manifest清單裡註冊,同時在使用的時候,需要向系統請求授權。值得注意一點,這裡有特殊許可權授權的區別,分別是SYSTEM_ALERT_WINDOW 和 WRITE_SETTINGS,雖然這兩個許可權也是屬於dangerous許可權型別,但是這兩個授權請求方式和其他dangerous許可權是不一樣的,需要特殊處理 。
對我來說,我要處理的是危險許可權,也就是表格裡面許可權。這裡還一個概念:許可權組。正如表格看到的情況,這些許可權是分組的。有時候,你一旦獲取許可權組裡面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、注意點是如果系統許可權彈窗提示框被不再提醒了,需要我們自定義提示彈窗,引導使用者去授權。