Android 6.0權限管理

Android 6.0權限管理

關於權限管理

Android6.0 發佈以後,Android 的權限系統被從新設計。在 23 以前 App 的權限只會在用戶安裝的時候詢問一次,App一旦安裝後就可使用全部的權限了,而從 23 以後,App 能夠直接安裝,App 只有在運行時須要使用某些權限時纔會向用戶詢問是否受權,此時系統會彈出一個對話框讓用戶選擇確認或者取消受權,同時用戶也能夠在設置頁面對每一個 App 的權限進行管理。重要:這個對話框須要開發者手動調用,且不可自行定製樣式html

Android Developer 文章:
System Permissions
Requesting Permissions at Run Time
Permissions Best Practicesjava

通用權限和危險權限

通用權限

通用權限是指不涉及用戶隱私,只須要在Manifest中聲明便可的權限,好比網絡、藍牙等,只要 app 安裝,這些權限默認都是被app容許使用的。android

通用權限列表:git

  • 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_IGNORE_BATTERY_OPTIMIZATIONS
  • 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

危險權限

全部危險的Android系統權限屬於權限組,若是APP運行在Android 6.0 (API level 23)或者更高級別的設備中,並且targetSdkVersion>=23時,系統將會自動採用動態權限管理策略。
此類權限也必須在Manifest中申明,不然申請時不提使用用戶,直接回調開發者權限被拒絕。
同一個權限組的任何一個權限被受權了,這個權限組的其餘權限也自動被受權。例如,一旦WRITE_CONTACTS被受權了,App也有READ_CONTACTSGET_ACCOUNTS了。
申請某一個權限的時候系統彈出的Dialog是對整個權限組的說明,而不是單個權限。例如我申請READ_EXTERNAL_STORAGE,系統會提示"容許xxx訪問設備上的照片、媒體內容和文件嗎?"。
若是App運行在Android 5.1 (API level 22)或者更低級別的設備中,或者targetSdkVersion<=22時(此時設備能夠是Android 6.0 (API level 23)或者更高),在全部系統中仍將採用舊的權限管理策略,系統會要求用戶在安裝的時候授予權限。其次,系統就告訴用戶App須要什麼權限組,而不是個別的某個權限。github

(targetSdkVersion>=23)
Dangous Permissions數組

Permission Group Permissions
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

兩個特殊的權限

SYSTEM_ALERT_WINDOWWRITE_SETTINGS 這兩個權限比較特殊,不能經過代碼申請方式獲取,必須得用戶打開軟件設置頁手動打開,才能受權。官方建議須要申請該權限時引導用戶跳轉到Setting中本身去開啓權限開關。網絡

public static int OVERLAY_PERMISSION_REQ_CODE = 1234;

@TargetApi(Build.VERSION_CODES.M)
public void requestDrawOverLays() {
    if (!Settings.canDrawOverlays(MainActivity.this)) {
        Toast.makeText(this, "can not DrawOverlays", Toast.LENGTH_SHORT).show();
        Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION, Uri.parse("package:" + MainActivity.this.getPackageName()));
        startActivityForResult(intent, OVERLAY_PERMISSION_REQ_CODE);
    } else {
        // Already hold the SYSTEM_ALERT_WINDOW permission, do addview or something.
    }
}

@TargetApi(Build.VERSION_CODES.M)
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == OVERLAY_PERMISSION_REQ_CODE) {
        if (!Settings.canDrawOverlays(this)) {
            // SYSTEM_ALERT_WINDOW permission not granted...
            Toast.makeText(this, "Permission Denieddd by user.Please Check it in Settings", Toast.LENGTH_SHORT).show();
        } else {
            Toast.makeText(this, "Permission Allowed", Toast.LENGTH_SHORT).show();
            // Already hold the SYSTEM_ALERT_WINDOW permission, do addview or something.
        }
    }
}

權限申請流程

權限申請流程

checkSelfPermission()

一、檢查某一個權限的當前狀態,在請求某個權限時應該檢查這個權限是否已經被用戶受權,已經受權的權限應該跳過申請。
二、該方法有一個參數是權限名稱,有一個int的返回值,可判斷檢查的權限當前的狀態。app

if (ContextCompat.checkSelfPermission(context, Manifest.permission.READ_CONTACTS)
        != PackageManager.PERMISSION_GRANTED) {
    // 沒有權限
}else{
    // 有權限了
}

requestPermissions()

申請權限,調用後系統會顯示一個請求用戶受權的提示對話框,App不能配置和修改這個對話框。
一、 若是須要提示用戶這個權限相關的信息或說明,須要在調用 requestPermissions() 以前處理,該方法有兩個參數:ide

int requestCode //會在回調onRequestPermissionsResult()時返回,用來判斷是哪一個受權申請的回調。
    String[] permissions//權限數組,你須要申請的的權限的數組

二、當用戶處理完受權操做時,會回調Activity或者Fragment的onRequestPermissionsResult()方法。ui

onRequestPermissionsResult()

處理權限結果回調,當用戶處理完受權操做時,系統會自動回調該方法,此時返回三個參數,能夠判斷用戶是否容許了申請的權限

int requestCode // 在調用requestPermissions()時的第一個參數。
    String[] permissions //權限數組,在調用requestPermissions()時的第二個參數。
    int[] grantResults //受權結果數組,對應permissions,具體值和上方提到的PackageManager中的兩個常量作比較。

shouldShowRequestPermissionRationale()

是否應該顯示請求權限的說明。
一、當第一次請求權限時,用戶拒絕了,此時再調用shouldShowRequestPermissionRationale()後會返回true,顯示爲何須要這個權限的說明。
二、用戶在第一次拒絕某個權限後,下次再次申請時,受權的dialog中將會出現「再也不提醒」選項,一旦選中勾選了,那麼下次申請將不會提示用戶。此時調用shouldShowRequestPermissionRationale()會返回false
三、設備的策略禁止當前應用獲取這個權限的受權:shouldShowRequestPermissionRationale()返回false

Permission Builder

一個本身實現的Permission輔助庫,幫助咱們可以快速而簡潔的在Android上申請權限。

Github地址:PermissiongBuilder
博客地址:cpacm

相關文章
相關標籤/搜索