概述
Google在 Android 6.0 開始引入了權(quán)限申請(qǐng)機(jī)制,將所有權(quán)限分成了正常權(quán)限和危險(xiǎn)權(quán)限。應(yīng)用的相關(guān)功能每次在使用危險(xiǎn)權(quán)限時(shí)需要?jiǎng)討B(tài)的申請(qǐng)并得到用戶的授權(quán)才能使用。
權(quán)限分類
系統(tǒng)權(quán)限分為兩類:正常權(quán)限和危險(xiǎn)權(quán)限。
- 正常權(quán)限不會(huì)直接給用戶隱私權(quán)帶來風(fēng)險(xiǎn)。如果您的應(yīng)用在其清單中列出了正常權(quán)限,系統(tǒng)將自動(dòng)授予該權(quán)限。
- 危險(xiǎn)權(quán)限會(huì)授予應(yīng)用訪問用戶機(jī)密數(shù)據(jù)的權(quán)限。如果您的應(yīng)用在其清單中列出了正常權(quán)限,系統(tǒng)將自動(dòng)授予該權(quán)限。如果您列出了危險(xiǎn)權(quán)限,則用戶必須明確批準(zhǔn)您的應(yīng)用使用這些權(quán)限。

重要方法
ContextCompat.checkSelfPermission
檢查應(yīng)用是否具有某個(gè)危險(xiǎn)權(quán)限。如果應(yīng)用具有此權(quán)限,方法將返回 PackageManager.PERMISSION_GRANTED,并且應(yīng)用可以繼續(xù)操作。如果應(yīng)用不具有此權(quán)限,方法將返回 PackageManager.PERMISSION_DENIED,且應(yīng)用必須明確向用戶要求權(quán)限。ActivityCompat.requestPermissions
應(yīng)用可以通過這個(gè)方法動(dòng)態(tài)申請(qǐng)權(quán)限,調(diào)用后會(huì)彈出一個(gè)對(duì)話框提示用戶授權(quán)所申請(qǐng)的權(quán)限。ActivityCompat.shouldShowRequestPermissionRationale
如果應(yīng)用之前請(qǐng)求過此權(quán)限但用戶拒絕了請(qǐng)求,此方法將返回 true。如果用戶在過去拒絕了權(quán)限請(qǐng)求,并在權(quán)限請(qǐng)求系統(tǒng)對(duì)話框中選擇了 Don't ask again 選項(xiàng),此方法將返回 false。如果設(shè)備規(guī)范禁止應(yīng)用具有該權(quán)限,此方法也會(huì)返回 false。onRequestPermissionsResult
當(dāng)應(yīng)用請(qǐng)求權(quán)限時(shí),系統(tǒng)將向用戶顯示一個(gè)對(duì)話框。當(dāng)用戶響應(yīng)時(shí),系統(tǒng)將調(diào)用應(yīng)用的 onRequestPermissionsResult() 方法,向其傳遞用戶響應(yīng),處理對(duì)應(yīng)的場(chǎng)景。
示例
本示例在Google示例的基礎(chǔ)上做了少許修改,步驟如下:
1、在AndroidManifest.xml中添加所需權(quán)限。
<uses-permission android:name="android.permission.READ_CONTACTS" />
2、封裝了一個(gè)requestPermission方法來動(dòng)態(tài)檢查和申請(qǐng)權(quán)限
private void requestPermission() {
Log.i(TAG,"requestPermission");
// Here, thisActivity is the current activity
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.READ_CONTACTS)
!= PackageManager.PERMISSION_GRANTED) {
Log.i(TAG,"checkSelfPermission");
// Should we show an explanation?
if (ActivityCompat.shouldShowRequestPermissionRationale(this,
Manifest.permission.READ_CONTACTS)) {
Log.i(TAG,"shouldShowRequestPermissionRationale");
// 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.
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.READ_CONTACTS},
MY_PERMISSIONS_REQUEST_READ_CONTACTS);
} else {
Log.i(TAG,"requestPermissions");
// No explanation needed, we can request the permission.
ActivityCompat.requestPermissions(this,
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.
}
}
}
3、重寫onRequestPermissionsResult方法根據(jù)用戶的不同選擇做出響應(yīng)。
@Override
public void onRequestPermissionsResult(int requestCode,
String permissions[], int[] grantResults) {
switch (requestCode) {
case MY_PERMISSIONS_REQUEST_READ_CONTACTS: {
// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Log.i(TAG,"onRequestPermissionsResult granted");
// permission was granted, yay! Do the
// contacts-related task you need to do.
} else {
Log.i(TAG,"onRequestPermissionsResult denied");
// permission denied, boo! Disable the
// functionality that depends on this permission.
showWaringDialog();
}
return;
}
// other 'case' lines to check for other
// permissions this app might request
}
}
private void showWaringDialog() {
AlertDialog dialog = new AlertDialog.Builder(this)
.setTitle("警告!")
.setMessage("請(qǐng)前往設(shè)置->應(yīng)用->PermissionDemo->權(quán)限中打開相關(guān)權(quán)限,否則功能無法正常運(yùn)行!")
.setPositiveButton("確定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
// 一般情況下如果用戶不授權(quán)的話,功能是無法運(yùn)行的,做退出處理
finish();
}
}).show();
}
RxPermissions
官方提供的方法在一次申請(qǐng)多個(gè)權(quán)限的時(shí)候代碼邏輯寫起來比較繁瑣,于是有了RxPermissions。RxPermissions是使用Rxjava封裝的第三方的權(quán)限申請(qǐng)庫,他的特點(diǎn)是借助Rxjava的特性簡(jiǎn)化了權(quán)限申請(qǐng)的代碼邏輯,使代碼看起來簡(jiǎn)潔易讀。具體的使用方法可以參看《RxPermissions獲取運(yùn)行時(shí)權(quán)限》,里面寫的比較詳細(xì)。
參考文獻(xiàn)
Google Doc:在運(yùn)行時(shí)請(qǐng)求權(quán)限
Google Doc:正常權(quán)限和危險(xiǎn)權(quán)限
權(quán)限分類:正常權(quán)限和危險(xiǎn)權(quán)限
Android6.0動(dòng)態(tài)權(quán)限申請(qǐng)步驟以及需要注意的一些坑
Android6.0------權(quán)限申請(qǐng)管理(單個(gè)權(quán)限和多個(gè)權(quán)限申請(qǐng))
android6.0運(yùn)行時(shí)權(quán)限詳解