談談Android 6.0執行時許可權理解
前言
谷歌在2015年8月份時候,釋出了Android 6.0版本,代號叫做“棉花糖”(Marshmallow ),其中的很大的一部分變化,是在使用者許可權授權上,或許是感覺之前預設授權的不合理,現在6.0出來,使得使用者許可權授權變得合理。這可能也是參考IOS系統的,只有在使用者需要使用許可權的時候,才去授權請求,這樣做的目的是提高使用者體驗,當然,使用者感覺好了,受苦的是我們開發人員,原來的規則不適用了,現在我們去適應新的規則,畢竟是靠谷歌這顆大樹吃飯的嘛。
原來許可權模型
在Android 6.0版本之前,許可權都是一條龍服務的,只要使用者安裝完 , AndroidManifest清單上申請的許可權都會被系統預設授權,並且授權後也撤銷不了。這樣的弊端在哪裡呢?有些許可權可能使用者覺得不需要,比如他不想有通知的許可權,不想受到通知的干擾,那麼他就不能遮蔽通知,就是不需要的許可權,他去不掉,自主權不在他那邊。還有一些情況是,一些惡意程式,會利用這個許可權預設授權,進行惡意獲取使用者資料和攻擊。所以Android 6.0版本,一方面讓使用者更加容易的控制自己的隱私,一方面需要重新適配應用許可權。
Android 6.0許可權模型
採用新的許可權模型,只有在需要許可權的時候,才告知使用者是否授權,是在runtime時候授權,而不是在原來安裝的時候 ,同時預設情況下每次在執行時開啟頁面時候,需要先檢查是否有所需要的許可權申請。這樣的使用者的自主性提高很多,比如使用者可以給APP賦予攝像的許可權,但是可以拒絕記錄裝置位置的許可權,就是怕位置資訊上傳等等。
許可權流程
在API 23中,許可權滿足的標準流程:
但這裡有個問題,那就是在系統授權彈窗環節,提醒框會有個不再提示的核取方塊,如果使用者點選不太提示,並拒絕授權,那麼再下次授權的時候,系統授權彈窗的提示框就不會在提示,所以我們很有必要需要自定義許可權彈窗提示框,那麼流程圖就變成如下了。
許可權型別
在圖中,我們可以看到整個許可權裡,可以分為系統許可權和特殊許可權授權。系統許可權中,又分為normal和dangerous型別。
normal:這個許可權型別並不直接威脅到使用者的隱私,可以直接在manifest清單裡註冊,系統會幫我們預設授權的。
dangerous:這個可以直接給app訪問使用者一些敏感的資料,不僅需要在manifest清單裡註冊,同時在使用的時候,需要向系統請求授權。
值得注意一點,這裡有特殊許可權授權的區別,分別是SYSTEM_ALERT_WINDOW 和 WRITE_SETTINGS,雖然這兩個許可權也是屬於dangerous許可權型別,但是這兩個授權請求方式和其他dangerous許可權是不一樣的,需要特殊處理 。
normal列表:
- 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
- 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
dangerous列表:
Permission Group | Permissions |
---|---|
CALENDAR | |
CAMERA | |
CONTACTS | |
LOCATION | |
MICROPHONE | |
PHONE | |
SENSORS | |
SMS | |
STORAGE |
版本相容
當然,谷歌也是考慮到如果是以API 23之前的版本編譯的APP,在6.0的系統上執行,還是能相容的。如果是23之前的版本編譯的APP,則許可權模型走的是老的模式,也就是在一條龍的模式,在manifest清單註冊,系統會幫我們預設授權,並且也能執行。
但如果是以API 23的版本編譯的APP,那走的的必須是新的許可權模型,在遇到dangerous許可權的時候,必須進行授權的,如果沒有進行授權話,系統則會提示崩潰資訊。所以,基於6.0系統的開發的程式, 在開啟頁面的時候,必須要考慮這個頁面是否用到需要授權的許可權,頁面檢測是否已經授權過了沒。
實現方式
第一步:檢測許可權
// Assume thisActivity is the current activity int permissionCheck = ContextCompat.checkSelfPermission(thisActivity, Manifest.permission.WRITE_CALENDAR);
第二步:請求許可權
// Here, thisActivity is the current activity if (ContextCompat.checkSelfPermission(thisActivity, Manifest.permission.READ_CONTACTS) != PackageManager.PERMISSION_GRANTED) { // Should we show an explanation? if (ActivityCompat.shouldShowRequestPermissionRationale(thisActivity, 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. ActivityCompat.requestPermissions(thisActivity, 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; } // other 'case' lines to check for other // permissions this app might request } }
其中要特別注意的是,如果是針對
“android.permission.SYSTEM_ALERT_WINDOW”
“android.permission.WRITE_SETTINGS”
這兩個許可權,實現方式跟上 之前在工作中,碰到一種情況,如果是執行在6.0的版本上是需要走新的許可權模型,如果是執行在老的版本上,則需要進行一個判斷,此時碰到一個問題是, 在谷歌官方推薦中,在判斷app執行的系統是否在Android M上時,它的判斷是如下: Build.VERSION.CODENAME.equals(“MNC”); 可是在我實際適配中,發現這句卻無效的,就改用Build.VERSION.SDK_INT >= 23。的,需要另外特殊處理。
針對SYSTEM_ALERT_WINDOW許可權,需要向系統傳送一個 ACTION_MANAGE_OVERLAY_PERMISSION .這樣一個動作,同時可以用 Settings.canDrawOverlays() 方法進行判斷之前是否已經授權過了。
針對WRITE_SETTINGS許可權,需要向系統傳送一個 ACTION_MANAGE_WRITE_SETTINGS 這樣一個動作,同時可以用 Settings.System.canWrite() . 方法進行判斷之前是否已經授權過了。
具體程式碼:
Intent intent = new Intent(android.provider.Settings.ACTION_MANAGE_WRITE_SETTINGS); intent.setData(Uri.parse("package:" + getPackageName())); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); startActivity(intent);
注意點
之前在工作中,碰到一種情況,如果是執行在6.0的版本上是需要走新的許可權模型,如果是執行在老的版本上,則需要進行一個判斷,此時碰到一個問題是,在谷歌官方推薦中,在判斷app執行的系統是否在Android M上時,它的判斷是如下: Build.VERSION.CODENAME.equals(“MNC”); 可是在我實際適配中,發現這句卻無效的,就改用Build.VERSION.SDK_INT >= 23。
總結
- 首先要知道6.0版本許可權模型跟原來版本是不同的,不再是統一在manifest中預設系統授權,而是有需要的時候,向系統請求授權,提高使用者體驗。
- 瞭解許可權檢測流程,一點注意點是如果系統許可權彈窗提示框被不再提醒了,需要我們自定義提示彈窗,引導使用者去授權。
- 明白許可權型別,分為normal和dangerous型別,同時,在dangerous中還需要注意一點,SYSTEM_ALERT_WINDOW 和 WRITE_SETTINGS這兩個特殊授權請求方式,跟一般授權請求方式不同。
- 在判斷APP是否執行在Android M上,可以用版本號來判斷,可以準確點。
參考
有個具體demo: https://github.com/SpikeKing/wcl-permission-demo
流程圖: http://blog.csdn.net/caroline_wendy/article/details/50587230
相關文章
- Android 6.0 執行時許可權詳解Android
- Android 6.0 在執行時請求許可權Android
- Android6.0執行時許可權機制Android
- Android 6.0 執行時許可權管理最佳實踐Android
- Android 6.0 執行時許可權處理完全解析Android
- Android許可權管理之Android 6.0執行時許可權及解決辦法Android
- Android新特性解析一:執行時許可權Android
- Java:談談protected訪問許可權薦Java訪問許可權
- Android 6.0許可權管理筆記Android筆記
- Android資料儲存之Android 6.0執行時許可權下檔案儲存的思考Android
- Android6.0------許可權申請管理(單個許可權和多個許可權申請)Android
- 淺談PostgreSQL使用者許可權SQL
- Android6.0動態許可權管理庫Android
- 再談Android的許可證Android
- Android進階 Android6 0執行時許可權處理Android
- 談談多後臺使用者許可權 Laravel 輪子Laravel
- 大家來談談程式中使用者許可權設計
- android 6.0許可權機制的簡單封裝(支援批量申請許可權)Android封裝
- Android 8.0 執行時許可權策略變化和適配方案Android
- Android6.0許可權的動態適配Android
- 原生Android之(6.0及以上)許可權申請Android
- 淺談 Orbeon form builder 的許可權控制ORBORMUI
- 再談Android的許可證(續)Android
- 「Android6.0許可權適配| 掘金技術徵文 」Android
- android 6.0許可權申請機制(簡單案例)Android
- Android 採用AOP方式封裝6.0許可權管理Android封裝
- 【許可權】儲存過程執行時,報ORA-01031許可權不足儲存過程
- Android M 新執行時許可權開發者需要知道的一切Android
- 塗抹MySQL--第5章 MySQL資料庫中的許可權體系 - 5.1談談許可權處理邏輯MySql資料庫
- 淺談許可權管理的設計與實現
- mysql 管理:mysql 執行許可權(轉)MySql
- Android系統許可權和root許可權Android
- Android M 新的執行時許可權開發者需要知道的一切Android
- Docker容器執行時許可權和Linux系統功能DockerLinux
- Android拍照,相簿選擇圖片以及Android6.0許可權管理Android
- Android許可權管理之RxPermission解決Android 6.0 適配問題Android
- Android6.0許可權適配及相容庫的實現Android
- React-Native之Android(6.0及以上)許可權申請ReactAndroid