Android 6.0權限管理


Android 6.0權限管理

關於權限管理

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

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

通用權限和危險權限

通用權限

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

通用權限列表:

  • 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需要什么權限組,而不是個別的某個權限。

(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()

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

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

requestPermissions()

申請權限,調用后系統會顯示一個請求用戶授權的提示對話框,App不能配置和修改這個對話框。
1、 如果需要提示用戶這個權限相關的信息或說明,需要在調用 requestPermissions() 之前處理,該方法有兩個參數:

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

2、當用戶處理完授權操作時,會回調Activity或者Fragment的onRequestPermissionsResult()方法。

onRequestPermissionsResult()

處理權限結果回調,當用戶處理完授權操作時,系統會自動回調該方法,此時返回三個參數,可以判斷用戶是否允許了申請的權限

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

shouldShowRequestPermissionRationale()

是否應該顯示請求權限的說明。
1、當第一次請求權限時,用戶拒絕了,此時再調用shouldShowRequestPermissionRationale()后會返回true,顯示為什么需要這個權限的說明。
2、用戶在第一次拒絕某個權限后,下次再次申請時,授權的dialog中將會出現“不再提醒”選項,一旦選中勾選了,那么下次申請將不會提示用戶。此時調用shouldShowRequestPermissionRationale()會返回false
3、設備的策略禁止當前應用獲取這個權限的授權:shouldShowRequestPermissionRationale()返回false

Permission Builder

一個自己實現的Permission輔助庫,幫助我們能夠快速而簡潔的在Android上申請權限。

Github地址:PermissiongBuilder
博客地址:cpacm


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM