Android 6.0 運行時權限檢測
Android 6.0之前的系統用戶在安裝apk文件時會根據app聲明的權限聲稱權限列表,用戶只有在同意了申請的權限後纔可以繼續安裝應用。這樣就存在了很大的安全隱患。因此在android 6.0後的系統中對權限進行了分級。一種是normal permission,一種是 dangerous permission級別權限。
normal permission權限:
- ACCESS_LOCATION_EXTRA_COMMANDS
- ACCESS_NETWORK_STATE
- ACCESS_NOTIFICATION_POLICY
- ACCESS_WIFI_STATE
- BLUETOOTH
- BLUETOOTH_ADMIN
- BROADCAST_STICKY
- CHANGE_NETWORK_STATE
- CHANGE_WIFI_MULTICAST_STATE
- CHANGE_WIFI_STATE
- DISABLE_KEYGUARD
- EXPAND_STATUS_BAR
- GET_PACKAGE_SIZE
- INSTALL_SHORTCUT
- INTERNET
- KILL_BACKGROUND_PROCESSES
- MODIFY_AUDIO_SETTINGS
- NFC
- READ_SYNC_SETTINGS
- READ_SYNC_STATS
- RECEIVE_BOOT_COMPLETED
- REORDER_TASKS
- REQUEST_INSTALL_PACKAGES
- SET_ALARM
- SET_TIME_ZONE
- SET_WALLPAPER
- SET_WALLPAPER_HINTS
- TRANSMIT_IR
- UNINSTALL_SHORTCUT
- USE_FINGERPRINT
- VIBRATE
- WAKE_LOCK
- WRITE_SYNC_SETTINGS
dangerous permission級別權限
- permission:android.permission.WRITE_CONTACTS
- permission:android.permission.GET_ACCOUNTS
permission:android.permission.READ_CONTACTS
permission:android.permission.READ_CALL_LOG
- permission:android.permission.READ_PHONE_STATE
- * permission:android.permission.CALL_PHONE*
- permission:android.permission.WRITE_CALL_LOG
- permission:android.permission.USE_SIP
- permission:android.permission.PROCESS_OUTGOING_CALLS
permission:com.android.voicemail.permission.ADD_VOICEMAIL
permission:android.permission.READ_CALENDAR
permission:android.permission.WRITE_CALENDAR
permission:android.permission.CAMERA
permission:android.permission.BODY_SENSORS
permission:android.permission.ACCESS_FINE_LOCATION
- * permission:android.permission.ACCESS_COARSE_LOCATION*
- permission:android.permission.READ_EXTERNAL_STORAGE
permission:android.permission.WRITE_EXTERNAL_STORAGE
permission:android.permission.RECORD_AUDIO
permission:android.permission.READ_SMS
- permission:android.permission.RECEIVE_WAP_PUSH
- permission:android.permission.RECEIVE_MMS
- permission:android.permission.RECEIVE_SMS
- permission:android.permission.SEND_SMS
- * permission:android.permission.READ_CELL_BROADCASTS*
Android 6.0在我們原有的AndroidManifest.xml聲明權限的基礎上,又新增了運行時權限動態檢測(就是對dangerous permission級別權限進行動態權限監測),以下權限都需要在運行時判斷:
身體傳感器
日曆
攝像頭
通訊錄
地理位置
麥克風
電話
短信
存儲空間
dangerous permission級別權限其實是分組的,每組中包含多個權限。app在動態獲取權限時顯示的是一組權限,一旦你同意了本組權限中的一種權限在下次app調用本組中其他權限時系統默認已經授權不需要用戶再次確認(在miui系統的6.0中測試發現每次都需要再次授權)。
小實例
在android studio項目中要想測試運行時權限檢測必須在gradle中將targetSdkVersion 設置爲23。如果是小於23系統會默認授予androidmainfast.xml中聲明的權限,但是這是一種臨時的解決方法還是需要做新機制的兼容的。
android {
compileSdkVersion 23
buildToolsVersion "23.0.3"
defaultConfig {
applicationId "com.example.cike.testpermission"
minSdkVersion 15
targetSdkVersion 23
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
我們需要在app中每次需要危險權限時都去權限是否授予的檢測,檢測代碼如下:
//contextCompat.checkSelfPermission()用於檢測是否授予權限
if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.CALL_PHONE) != PackageManager.PERMISSION_GRANTED) {
//activitycompat.requestPermission()請求權限 ActivityCompat.requestPermissions(MainActivity.this, new String[] {Manifest.permission.CALL_PHONE},1);
} else {
calling();
}
完整代碼如下:
public class MainActivity extends AppCompatActivity {
private Button button;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button = (Button) findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.CALL_PHONE) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(MainActivity.this, new String[] {Manifest.permission.CALL_PHONE},1);
} else {
calling();
}
}
});
}
private void calling() {
Intent intent = new Intent(Intent.ACTION_CALL);
Uri data = Uri.parse("tel:1234567890");
intent.setData(data);
startActivity(intent);
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
if (requestCode == 1) {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
calling();
} else {
Toast.makeText(this, "權限被拒絕", Toast.LENGTH_SHORT).show();
}
return;
}
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
}