Android 6.0
Permission
change
彥彬
Permission before 6.0
大部分的人應該都這樣做
Apps support 6.0
APP安裝行為
1. 6.0以下手機 + 支援6.0的APP
2. 6.0 以下手機 + 不支援6.0的APP
3. 6.0 以上手機 + 不支援 6.0 的APP
4. 6.0 以上手機 + 支援 6.0 的 APP
安裝時需要同意權限
安裝時需要同意權限
安裝時需要同意權限
安裝時不需要同意權限
Permission overview
Permission category
● Normal permission
● Dangerous permission
Normal Permission
● 只需要在 manifest 宣告就好
● 使用者不必同意該權限
● 使用者不會知道使用了該權限
Dangerous Permission
● 使用者可自行決定是否使用該權限
● 可在設定中關閉
Permission group
● Dangerous permission 分成 9 組
● 一次同意整組權限
Permission groups
CALENDAR
● READ_CALENDAR
● WRITE_CALENDAR
CAMERA
● CAMERA
CONTACTS
● READ_CONTACTS
● WRITE_CONTACTS
● GET_ACCOUNTS
LOCATION
● ACCESS_FINE_LOCATION
● ACCESS_COARSE_LOCATION
MICROPHONE
● RECORD_AUDIO
PHONE
● READ_PHONE_STATE
● CALL_PHONE
● READ_CALL_LOG
● WRITE_CALL_LOG
● ADD_VOICEMAIL
● USE_SIP
● PROCESS_OUTGOING_CALLS
SENSORS
● BODY_SENSORS
SMS
● SEND_SMS
● RECEIVE_SMS
● READ_SMS
● RECEIVE_WAP_PUSH
● RECEIVE_MMS
STORAGE
● READ_EXTERNAL_STORAGE
● WRITE_EXTERNAL_STORAGE
Permission API
API 使用流程
checkSelfPermission
繼續執行
requestPermissions
PERMISSION_GRANTED
PERMISSION_DENIED
onRequest
PermissionsResult
Error handling
PERMISSION_GRANTED
PERMISSION_DENIED
APIs
int Context#checkSelfPermission(String permission)
void Activity/Fragment#RequestPermissions(String[] permissions, int
requestCode)
void Activity/Fragment#onRequestPermissionsResult(int requestCode, String[]
permissions, int[] grantResults )
boolean Activity/Fragment#shouldShowRequestPermissionRationale(String
permission)
要求權限
if (checkSelfPermission(Manifest.permission.READ_CONTACTS)
!= PackageManager.PERMISSION_GRANTED) {
// Should we show an explanation?
if (shouldShowRequestPermissionRationale(Manifest.permission.READ_CONTACTS)) {
// 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.
} else {
// No explanation needed, we can request the permission.
requestPermissions(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.
}
}
處理回應
@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) {
// permission was granted, yay! Do the
// contacts-related task you need to do.
} else {
// permission denied, boo! Disable the
// functionality that depends on this permission.
}
return;
}
}
}
處理“不要再詢問我”
shouldShowRequestPermissionRationale(permission) == false
相容性
● 需要檢查 Build.VERSION_CODE < 23
● 或是使用 Support v4
Asking for permission
一般時機
● 需要時再要求(map, 定位...)
● 永遠不要有預設立場,在onCreate檢查
● 發送 Intent 時也需要權限
Service?
1. 一開APP 馬上要求權限
2. 需要時發出Notification
3. 隨時提醒使用者
Extras
建議
● 盡量隔離外部資源
● Permission API再包裝一層
Screen overlay
● 無法更改權限屬正常行為
偷偷被藏起來的權限...
● Manifest.permission.WRITE_SETTINGS
● Manifest.permission.CHANGE_NETWORK_STATE
● Manifest.permission.SYSTEM_ALERT_WINDOW
pre23| preinstalled permissions
● Android M 之後預設無法使用
● Manifest.permission.WRITE_SETTINGS 可以經由 intent
ACTION_MANAGE_WRITE_SETTINGS 開啟
Reference
https://www.youtube.com/watch?v=5xVh-
7ywKpE&index=9&list=PLWz5rJ2EKKc_Tt7q77qwyKRgytF1RzRx8

Android 6.0 permission change