android6.0釋出好一段時間了,但是由于android手機廠商都要對android“深度定制”。是以很多使用者都沒有第一時間收到android6.0更新推送。筆者用的是魅族手機,到筆者寫本編文章為止還沒能更新到6.0系統。在這裡吐槽一下bugme!android6.0的權限機制發生了較大的變化,特别是對于開發者來說要第一時間掌握如何對6.0的運作時權限進行适配。
1.運作時權限的變化
在android6.0之前,安裝應用的時候回列出一個權限清單,要安裝該應用就必需同意這些權限。是以應用所需要的權限隻是展示給使用者看一眼,而不能由使用者決定到底允許哪一個權限。是以,使用者安裝應用的時候就相當于在面臨兩個選擇: 1.用該軟體,接收所有的權限請求。 2.不用該軟體。
如此粗暴!當然,在6.0之前很多“深度定制”的rom内部已經內建管理權限的軟體,但是畢竟不是原生的支援。在某些方面肯定不如官方支援的運作時權限。
運作時權限可以更好保護使用者隐私,比如玩一個單機遊戲,卻想要申請讀取短信的權限,那麼在6.0系統中就必需要彈窗請求該權限,使用者這個時候就可以點選拒絕~杜絕了濫用權限讀取使用者隐私的問題了。
新的權限機制将權限分成了兩類:
第一類:Normal Permissions 這類權限一般不會涉及使用者隐私,是不需要使用者授權的。比如通路網絡之類的。
第二類:Dangerous Permissions 這類權限涉及到使用者隐私,需要使用者授權。比如讀取sd卡之類的。
而我們正是要對第二類權限進行處理,使用這些權限之前檢查一下是否已經授權了,如果沒有則請求權限。我們先看一下屬于Dangerous Permissions的權限有哪些。
使用adb指令:adb shell pm list permissions -d -g即可進行查詢
屬于Dangerous Permissions的權限就是上面所列出來的,以後再使用這些權限之前記得進行檢查申請操作。
有些讀者可能已經發現了,這些權限是一組一組的。
使用者在授權的時候如果已經對該組的某一個權限進行授權了,那麼該組的其它權限相當于已經授權了,無需再次授權。可以這麼了解,申請權限的時候是在申請該權限所在的組的權限,是以申請權限所彈出的對話框内容,也是針對該組說明的,而不是針對該權限說明的。
二.新的權限機制的申請步驟
1.添權重限:
在manifest檔案中添加所需的權限,這一點跟之前的開發一樣。
2.檢查權限:
檢查将要使用到的權限是否已經授權,這裡以申請寫sd卡的權限為例
if (ContextCompat.checkSelfPermission(mContext, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED)
checkSelfPermission傳入兩個參數,第一個是一個Activity,第二個參數是要檢查的權限。如果該權限已經被授權則傳回 PackageManager.PERMISSION_GRANTED否則傳回
PackageManager.PERMISSION_DENIED。用一個if判斷目前檢查的權限是否不等于PackageManager.PERMISSION_GRANTED,如果不等于則相當于還沒授權這時就要對該權限進行申請,否則直接可以進行該權限的相關的操作。
3.申請授權:
ActivityCompat.requestPermissions(thisActivity, new String[]{
Manifest.permission.WRITE_EXTERNAL_STORAGE
}, REQUEST_CODE);
第一個參數依然是Activity,第二個參數是一個要申請的權限字元串數組,既然是一個數組,意味着可以一次申請多個權限,系統會使用對話框對使用者進行逐一詢問。
第三個參數是Request_CODE。這個Request_Code跟startActivityForResult的Request_code差不多。
4.權限申請回調:
在申請授權之後系統會彈窗詢問使用者是否授權,授權結果會以回調的方式傳回。
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
switch (requestCode) {
case 0:
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
save();
} else {
Toast.makeText(mContext,"使用者取消授權,無法繼續測試",Toast.LENGTH_LONG).show();
}
break;
}
}
首先要對第一個參數requestCode進行判斷,定位是哪一個授權請求的傳回結果。然後第二個參數是所申請的權限的字元數組,第三個是授權結果。如果申請的權限數量為2則grantResults與permissions這兩個數組的長度則為2.如果申請的權限數量為一個的話則這兩個數組的長度為1.
如果使用者允許本次申請的第一個權限,則grantResults數組相應位置的值會為
PackageManager.PERMISSION_GRANTED
否則:
PackageManager.PERMISSION_DENIED
然後就可以根據所傳回的結果進行相應的操作了。