android 從6.0對(duì)用戶權(quán)限的獲取方式進(jìn)行了修改,不像以前那樣只在AndroidManifest.xml單單的添加權(quán)限就可以的,有些敏感的權(quán)限還需要在runtime詢問(wèn)用戶是不是賦予此APP所需要的權(quán)限,當(dāng)然如果你沒(méi)有對(duì)這些敏感的權(quán)限在runtime進(jìn)行處理的話android默認(rèn)是會(huì)禁止當(dāng)前權(quán)限。下面就說(shuō)說(shuō)那些權(quán)限是需要在runtime進(jìn)行處理的.

相信被6.0權(quán)限問(wèn)題折磨了很久的人都看到過(guò)這張圖了,他對(duì)權(quán)限進(jìn)行了分組,當(dāng)前組任何一個(gè)權(quán)限被允許了那么當(dāng)app需要當(dāng)前組任何一個(gè)權(quán)限的時(shí)候系統(tǒng)都不會(huì)在重新詢問(wèn)客戶。
接下來(lái)就說(shuō)說(shuō)怎么在runtime時(shí)處理權(quán)限問(wèn)題:
int hasReadContactsPermission
= checkSelfPermission("android.permission.READ_CONTACTS");
if (hasReadContactsPermission
!= PackageManager.PERMISSION_GRANTED) {
requestPermissions(new String[]
{Manifest.permission.READ_CONTACTS}, 123);//第一個(gè)參數(shù)是需要的權(quán)限,第二參//數(shù)是自定義的一個(gè)回調(diào)值
return;
}
我這用的是讀取聯(lián)系人的權(quán)限為例,在讀取聯(lián)系人之前調(diào)用該片方法,當(dāng)然了調(diào)用了這些代碼還是不行的,因?yàn)槟悴恢烙脩羰沁x擇了禁止還是允許(其實(shí)你要是在操作權(quán)限之前只調(diào)用上面的代碼詢問(wèn)框直接不出來(lái)就給你拒絕了)
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode) {
case 123:
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// Permission Granted
asyncQueryHandler = new MyAsyncQueryHandler(this.getContentResolver());
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_CONTACTS}, 0);
Uri uri = ContactsContract.CommonDataKinds.Phone.CONTENT_URI; // 聯(lián)系人Uri;
// 查詢的字段
String[] projection = {ContactsContract.CommonDataKinds.Phone._ID,
ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME,
ContactsContract.CommonDataKinds.Phone.DATA1, "sort_key",
ContactsContract.CommonDataKinds.Phone.CONTACT_ID,
ContactsContract.CommonDataKinds.Phone.PHOTO_ID,
ContactsContract.CommonDataKinds.Phone.LOOKUP_KEY};
// 按照sort_key升序查詢
asyncQueryHandler.startQuery(0, null, uri, projection, null, null,
"sort_key COLLATE LOCALIZED asc");
} else {
// Permission Denied
Toast.makeText(ActivityAddFriends.this, "WRITE_CONTACTS Denied", Toast.LENGTH_SHORT)
.show();
}
break;
default:
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
}
到這權(quán)限管理才算是完成,但是這樣有一點(diǎn)不好,就是當(dāng)用戶選擇了禁止的時(shí)候app就會(huì)獲取不到數(shù)據(jù),只有當(dāng)用戶給你權(quán)限了才可以,還有另外一種方法,當(dāng)需要權(quán)限的時(shí)候先彈出了一個(gè)diloa告訴用戶我要權(quán)限是為了干什么。具體代碼如下:
private void insertDummyContactWrapper() {
int hasWriteContactsPermission = checkSelfPermission(Manifest.permission.WRITE_CONTACTS);
if (hasWriteContactsPermission != PackageManager.PERMISSION_GRANTED) {
if (!shouldShowRequestPermissionRationale(Manifest.permission.WRITE_CONTACTS)) {
showMessageOKCancel(“You need to allow access to Contacts”,
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
requestPermissions(new String[] {Manifest.permission.WRITE_CONTACTS},
123);
}
});
return;
}
}
insertDummyContact();
}
private void showMessageOKCancel(String message, DialogInterface.OnClickListener okListener) {
new AlertDialog.Builder(MainActivity.this)
.setMessage(message)
.setPositiveButton(“OK”, okListener)
.setNegativeButton(“Cancel”, null)
.create()
.show();
}`
這樣的話當(dāng)用戶點(diǎn)擊cannel的時(shí)候最多這一次權(quán)限沒(méi)有得到,但是當(dāng)下一次需要這個(gè)權(quán)限的時(shí)候就會(huì)還彈出來(lái)這個(gè)對(duì)話框,來(lái)詢問(wèn)用戶。
參考的博客是一篇純英文的看著有點(diǎn)費(fèi)勁,有翻譯的但是一時(shí)找不到了。
參考文檔