Android 6.0 動態(tài)權(quán)限介紹

android 6.0開始谷歌推行新的權(quán)限管理機制——動態(tài)權(quán)限管理,類似于ios上的權(quán)限申請,權(quán)限的獲取不再是在app安裝時進行,而是在運行時申請。

當然并不是所有的權(quán)限都需要動態(tài)申請,谷歌把權(quán)限劃分為兩大類,普通權(quán)限和危險權(quán)限。對于普通權(quán)限,還是和之前一樣在AndroidManifest.xml里申請就行,而對于危險權(quán)限,就必須在運行時動態(tài)申請,得到用戶的授權(quán)后才可使用。
下面羅列的是普通權(quán)限分類下的權(quán)限:

  • 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
  • FLASHLIGHT
  • GET_PACKAGE_SIZE
  • INTERNET
  • KILL_BACKGROUND_PROCESSES
  • MODIFY_AUDIO_SETTINGS
  • NFC
  • READ_SYNC_SETTINGS
  • READ_SYNC_STATS
  • RECEIVE_BOOT_COMPLETED
  • REORDER_TASKS
  • REQUEST_INSTALL_PACKAGES
  • SET_TIME_ZONE
  • SET_WALLPAPER
  • SET_WALLPAPER_HINTS
  • TRANSMIT_IR
  • USE_FINGERPRINT
  • VIBRATE
  • WAKE_LOCK
  • WRITE_SYNC_SETTINGS
  • SET_ALARM
  • INSTALL_SHORTCUT
  • UNINSTALL_SHORTCUT

可以看出普通權(quán)限都是和手機本身有關(guān)的功能,而用戶數(shù)據(jù)的權(quán)限(包括幾乎所有app都要申請的讀寫SD卡得權(quán)限)已被劃入危險權(quán)限中。
API23中新增了幾個與權(quán)限有關(guān)的接口
第一個是用于檢查權(quán)限的接口,該接口可以通過ContextCompat調(diào)用,也可以在當前的activity里直接調(diào)用。

// Assume thisActivity is the current activity
int permissionCheck = ContextCompat.checkSelfPermission(thisActivity,
        Manifest.permission.WRITE_CALENDAR);

該接口的返回值代表權(quán)限查詢的結(jié)果,PackageManager.PERMISSION_GRANTED表示用戶已經(jīng)授權(quán),PackageManager.PERMISSION_DENIED表示用戶還沒有授權(quán),這是需要使用另一個接口進行權(quán)限申請。這個方法在使用時不需要再判斷系統(tǒng)版本了,因為方法內(nèi)部會區(qū)分版本,如果是API23以下會直接通過檢查manifest的方式進行。

public static void requestPermissions (Activity activity, String[] 
                  permissions, int requestCode)

參數(shù)的第一個activity,也就是說權(quán)限的申請必須在UI線程去做,第二個參數(shù)是要申請的權(quán)限數(shù)組,第三個參數(shù)請求碼用于在回調(diào)時區(qū)分不同的權(quán)限申請(比如你可能在同一個activity的兩處申請了兩個不同的權(quán)限)。

通過實現(xiàn)接口

ActivityCompat.OnRequestPermissionsResultCallback中的
public abstract void onRequestPermissionsResult (int requestCode, String[]
               permissions, int[] grantResults)

activity就能接收到請求申請結(jié)果。grantResults數(shù)組記錄了每個權(quán)限申請的結(jié)果。requestCode就是剛剛申請時的值。

即使為了安全,也不能不考慮用戶體驗,為了防止用戶被過多的打擾,API 23還提出了pemisssion_group權(quán)限組概念,即把權(quán)限分組,用戶只要授權(quán)了某個組里的某一個權(quán)限,那么該組的其他權(quán)限就不需要再次授權(quán)了。比如用戶已經(jīng)授權(quán)了READ_PHONE_STATE,那么下次再申請CALL_PHONE時就不會再彈窗讓用戶授權(quán)了。

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

另一個API,ActivityCompat.shouldShowRequestPermissionRationale

public static boolean shouldShowRequestPermissionRationale (Activity
                         activity, String permission)

用來檢查是否之前用戶已經(jīng)拒絕過這個權(quán)限了,包括已經(jīng)勾選了不再提示的,這種情況下,可能需要進行提示,告訴用戶這個權(quán)限app用來做什么。

另外有兩個特殊的權(quán)限,SYSTEM_ALERT_WINDOW 和 WRITE_SETTINGS,這兩個權(quán)限的管理在系統(tǒng)應(yīng)用管理里,如果需要使用,需要通過intent方式啟動該管理頁面,用戶允許后方可使用,判斷是否有這兩個權(quán)限的方法分別是

Settings.canDrawOverlays(Context) //SYSTEM_ALERT_WINDOW
Settings.System.canWrite(Context) //WRITE_SETTINGS

另外可以再intent指定URI,這樣在啟動應(yīng)用管理UI后可以直接進入指定app的管理頁面,如下的方式。

Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION);
intent.setData(Uri.parse("package:com.app.my"));
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
this.startActivity(intent);

當然這些變化只有在app改變編譯時使用的sdk版本到23時才需要用到,如果編譯時sdk版本不是23,那么會以兼容方式運行,系統(tǒng)仍然會通過靜態(tài)方式進行權(quán)限檢查。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容