Android 6.0 權限行為變更詳解
- 2019 年 12 月 26 日
- 筆記
運行時權限說明
Android 6.0 引入了一種新的權限模式,使得用戶可以在運行 APP 的時候對一些比較敏感的權限進行管理。這種新的模式可以讓用戶更好的了解和控制權限,同時為應用精簡了安裝和自動更新過程。
對於以 Android 6.0 或者更高版本為目標平台的應用,務必在運行的時候檢查和請求權限(針對一些危險權限)否則,如果直接調用相關需要特殊權限的方法的話,會導致 APP 的崩潰。檢查是否已經擁有權限了可以使用方法 checkSelfPerssion()
如果要請求權限使用方法 requestPermissions
方法。這兩個方法都是在 API 23 後引入的,也就是說在之前的 API 中是沒有這倆方法的。如果你的 minSdkVersion 設置的值是在 23 以下的話,直接調用上面的方法會有這種提示 Call requires API level 23 (current min is 21):........

提示說的很清除了,調用這種方法是需要 API 23 的,而當前 min 是 21,也就說明你的 APP 是可以運行在 Android 5.0 系統的手機上面的,然而 checkSelfPermission
方法是在 Android 6.0 才引進的,所以會有這種錯誤的提示。那麼畢竟現在 Android 5.0 的系統還是有很多用戶量的,這個時候我們應該怎麼辦呢?這個時候 ActivityCompat
和 ContextComapt
就派上用途的,這個兩個類是 Android API 特意為了考慮軟件向前兼容考慮的。
什麼樣的權限需要請求用戶授權呢?
對於一些敏感的用戶數據,比如一些牽扯到讀寫功能的權限是需要向用戶請求權限的。對於一些無關緊要的權限,可以在安裝的時候系統自動將這些權限授予了我們的應用。
普通權限,如果應用程序在其清單中聲明了,則系統會在安裝時自動授予應用程序該權限,系統不會提示用戶授權普通權限,用戶也無法撤銷
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
FOREGROUND_SERVICE
GET_PACKAGE_SIZE
INSTALL_SHORTCUT
INTERNET
KILL_BACKGROUND_PROCESSES
MANAGE_OWN_CALLS
MODIFY_AUDIO_SETTINGS
NFC
READ_SYNC_SETTINGS
READ_SYNC_STATS
RECEIVE_BOOT_COMPLETED
REORDER_TASKS
REQUEST_COMPANION_RUN_IN_BACKGROUND
REQUEST_COMPANION_USE_DATA_IN_BACKGROUND
REQUEST_DELETE_PACKAGES
REQUEST_IGNORE_BATTERY_OPTIMIZATIONS
SET_ALARM
SET_WALLPAPER
SET_WALLPAPER_HINTS
TRANSMIT_IR
USE_FINGERPRINT
VIBRATE
WAKE_LOCK
WRITE_SYNC_SETTINGS
危險權限:危險權限涵蓋應用程序需要涉及用戶私人信息的數據或資源的區域,或者可能會影響用戶存儲數據或其他應用程序的操作。這種權限就需要動態申請了

應用必須通過 <users-permission>
在應用清單中標誌來聲明 APP 所需要的權限。例如,需要發送 SMS 消息的應用程序需要在清單文件中聲明下面的權限:如何獲取權限
<uses-permission android:name = 「android.permission.SEND_SMS」 />
如果在清單中列出的權限,不會對用戶的隱形或者設備造成太大的風險,這個時候系統會自動給你的應用授權。如果在應用清單中列出了危險權限(可能影響用戶隱私或者設備正常運行的權限)這個時候就需要在代碼中調用向對應的 API 動態請求獲取權限了。
請求提示危險權限
只有危險權限才需要我們在代碼中動態向用戶請求,Android 要求用戶授予危險權限的方式是和用戶設備上運行的 Android 系統的版本以及我們的應用所針對的系統版本有關的。
運行時請求(Android 6.0以及更高版本)
由於國內 Android 系統都是在正宗 Android 系統的基礎上二次開發的,所以在這種特性的問題上會和正宗的 Android 系統有不同。 舉個例子 :比如你將你開發的 APP 的 targetSDKVersion 設置為 23 以下的話,如果在原生的 Android 系統上,運行的時候是不需要運行時請求危險權限的,因為這個特性是在 API 23 才加入的。但是如果你這樣設置的話,在國內的手機上運行還是有問題的(比如小米手機)如果你沒有動態申請危險權限,會導致你的 APP 崩潰,也就是說 targetSDKVersion 這個屬性對國內的非原生 Android 手機不是那麼管用。針對國內的手機建議是:最好 targetSDKVersion 的版本是是最新的,代碼裏面的 API 也要對應 targetSDKVersion 版本的 API 這樣才能保證最大程度的兼容 這句話可能有點不好理解,我再舉個例子:比如,在小米手機 8.0 系統上,你設置了 targetSDKVersion 為 22,這個時候如果是原生 Android 系統的話是不需要再動態申請權限了,但是在小米上還是需要的的,這個時候你調用 checkSelfPermission
等等動態調用權限的方法,你會發現還是會出現各種問題,當你把 targetSDKVersion 調整為 23 就可以了。這就是上面那句話的意思。
在需要一些危險權限的時候,必須要向用戶動態請求,用戶會看到一個系統的對話框,告訴用戶這個應用程序需要訪問那個權限,讓用戶選擇 拒絕 或者 允許,如果用戶拒絕權限請求,則下次應用請求權限的時候,彈出的對話框會增加一個 不再提醒 選擇框,如果用戶選擇 不再詢問 並點擊 拒絕 ,則系統不會再彈出權限請求框

注意這個對話框,不同的定製系統是不一樣,是不能更改的
實際運用
上面講了那麼多概念性的內容,現在來進行實際運用
比如,我的下一步操作需要讀寫內存卡權限,那麼代碼如何書寫
- 1.首先應該檢查應用有沒有獲取此權限
- 2.判斷是否需要展示解釋
- 3.請求權限
- 4.處理回調
下面就一步一步的來詳細說明好了,以上就是最基本的運用方法,其他的一些框架都在這個基礎上封裝的。
注意: 一定要按照上面的順序來進行(缺少任何步驟都不行),否則在有些系統的手機上會有各種問題。