Android 6.0 M
1.1 權限動態申請
在Android 6.0中谷歌摒棄了之前的install time permissions model取而代之的是runtime permissions model。先來說說install time permissions model,這個大家不陌生,就是當Android App安裝的時候會向用戶展示一坨權限,如果此時用戶選擇安裝,則表示用戶同意將這些權限賦予App,如果用戶不同意那麼這個App就會取消安裝。runtime permissions model就牛逼了,在App安裝的時候同樣會向用戶展示所需要的權限,並且在用戶選擇安裝App的時候並不表示用戶將這些權限賦予了App,而是需要App在運行階段主動去申請這些權限。這樣做的好處顯而易見,App對權限的申請對於用戶來說變得更加透明,而且用戶對App權限的控制也更加靈活。
Android將系統權限分成了四個保護等級normal,dangerous,signature,signatureOrSystem,其中最常見的是normal permission和dangerous permission兩類。
- Normal Permissions(普通權限):不涉及用戶隱私,不需要用戶進行授權,比如訪問網絡等;
- Dangerous Permission(危險權限):涉及到用戶隱私,需要用戶進行授權,比如相機訪問、讀取SD卡等。
Runtime Permissions針對的是dangerous permissions,normal permissions 還是會在App安裝期間被默認賦予。舉例子:
加入你在6.0中聲明此權限
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
不做任何處理時,應用程序在運行時會出現一個驚喜那就是(Permission Denied)
那麼接下來看一下怎麼在代碼中進行權限的申請:
public static final int EXTERNAL_STORAGE_REQ_CODE = 15 ;
public void getRuntimePermission(){
//判斷當前Activity是否已經獲得了該權限
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.WRITE_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) {
//如果App的權限申請曾經被用戶拒絕過,就需要在這裏跟用戶做出解釋
if (ActivityCompat.shouldShowRequestPermissionRationale(this,
Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
Toast.makeText(this,"please give me the permission",Toast.LENGTH_SHORT).show();
} else {
//進行權限請求
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
EXTERNAL_STORAGE_REQ_CODE);
}
}
}
當進行權限申請,並且用戶做出選擇後會回調onRequestPermissionsResult這個方法,在這個方法中做相關處理:
@Override
public void onRequestPermissionsResult(int requestCode,
String permissions[], int[] grantResults) {
switch (requestCode) {
case EXTERNAL_STORAGE_REQ_CODE: {
// 如果請求被拒絕,那麼通常grantResults數組爲空
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
//申請成功
} else {
//申請失敗
}
return;
}
}
}
1.2 Fragment 請求權限
//如果使用ActivityCompat.requestPermissions,不會調用onRequestPermissionsResult()
//請求權限
requestPermissions(new String[]{Manifest.permission.ACCESS_COARSE_LOCATION},
MY_PERMISSIONS_REQUEST_ACCESS_COARSE_LOCATION);
//判斷是否需要 向用戶解釋,爲什麼要申請該權限
shouldShowRequestPermissionRationale(Manifest.permission.READ_CONTACTS)
1.3 WRITE_SETTINGS特殊權限申請
Android 6.0中,除了危險權限不再在安裝後授予,還有兩個特殊權限:
設置懸浮窗: SYSTEM_ALERT_WINDOW
修改系統設置:WRITE_SETTINGS
修改系統設置權限的授權 WRITE_SETTINGS,與其他權限不同
而是使用startActivityForResult,啓動系統設置的授權界面來申請
/**
* 申請權限
*/
private void requestWriteSettings()
{
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
{
//大於等於23 請求權限
if ( !Settings.System.canWrite(getApplicationContext()))
{
Intent intent = new Intent(Settings.ACTION_MANAGE_WRITE_SETTINGS);
intent.setData(Uri.parse("package:" + getPackageName()));
startActivityForResult(intent, REQUEST_CODE_WRITE_SETTINGS );
}
}else{
//小於23直接設置
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQUEST_CODE_WRITE_SETTINGS)
{
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
{
//Settings.System.canWrite方法檢測授權結果
if (Settings.System.canWrite(getApplicationContext()))
{
T.show("獲取了權限");
}else{
T.show("您拒絕了權限");
}
}
}
}