從 Android 6.0(API 級別 23)開始,用戶開始在應用運行時向其授予權限,而不是在應用安裝時授予。此方法可以簡化應用安裝過程,因爲用戶在安裝或更新應用時不需要授予權限。它還讓用戶可以對應用的功能進行更多控制;例如,用戶可以選擇爲相機應用提供相機訪問權限,而不提供設備位置的訪問權限。用戶可以隨時進入應用的“Settings”屏幕調用權限。
系統權限分爲兩類:正常權限和危險權限:
1.正常權限不會直接給用戶隱私權帶來風險。如果您的應用在其清單中列出了正常權限,系統將自動授予該權限。
2.危險權限會授予應用訪問用戶機密數據的權限。如果您的應用在其清單中列出了正常權限,系統將自動授予該權限。如果您列出了危險權限,則用戶必須明確批准您的應用使用這些權限。
3.特殊權限:有許多權限其行爲方式與正常權限及危險權限都不同。SYSTEM_ALERT_WINDOW 和 WRITE_SETTINGS 特別敏感,因此大多數應用不應該使用它們。如果某應用需要其中一種權限,必須在清單中聲明該權限,並且發送請求用戶授權的 intent。系統將向用戶顯示詳細管理屏幕,以響應該 intent。
任何權限都可屬於一個權限組,包括正常權限和應用定義的權限。但權限組僅當權限危險時才影響用戶體驗。
危險權限和權限組如下:
動態權限申請步驟如下:
1、AndroidManifest.xml聲明權限如下:
<uses-permission android:name="android.permission.CAMERA"/>
2、判斷系統版本是否是6.0及其以上:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M){}
3、檢測是否擁有權限:
if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {//應用沒有該權限}
4、是否需要顯示解釋需要權限原因提示:
if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.CAMERA)) {//是否應該繼續顯示對話框}
5、權限申請:
ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.CAMERA}, 0);
完整的申請代碼如下:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M){
if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {//應用沒有該權限
if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.CAMERA)) {//是否應該繼續顯示對話框
//之前請求過拒絕了 返回true
//如果用戶在過去拒絕了權限請求,並在權限請求系統對話框中選擇了 Don't ask again 選項,此方法將返回 false。如果設備規範禁止應用具有該權限,此方法也會返回 false
new AlertDialog.Builder(MainActivity.this).setTitle("申請權限").setMessage("拍照需要申請相機權限,是否允許?").setPositiveButton("取消",null).setNegativeButton("確定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
//點擊確定的時候再次進行權限的申請
ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.CAMERA}, 0);
}
}).show();
} else {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA}, 0);
}
}
}
6、權限申請回調處理:
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
switch (requestCode) {
case 0:
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Toast.makeText(this,"申請相機權限成功",Toast.LENGTH_LONG).show();
} else {
Toast.makeText(this,"申請相機權限失敗",Toast.LENGTH_LONG).show();
}
break;
default:
break;
}
}
基本的申請流程就是這樣,當然因爲Android是開源平臺,所以不同的手機廠商作了不同的處理,雖然大體一致,但是難免會存在Bug,所以推薦使用封裝好的權限請求框架AndPermission。
特殊權限的使用後續再研究。