1. 程式人生 > >Android O 8.0 執行時許可權適配方案

Android O 8.0 執行時許可權適配方案

一.序

在之前的文章聊聊Android M 6.0 的執行時許可權曾提到過,Google Play開發者明年勢必要努力將targetsdkversion升級到26的過程中。官網的文件:向 Android 8.0 遷移應用 已經給大家了一個升級指南。當然動態許可權也是需要關注的一部分。可能有部分開發者已經將targetsdkversion升級到23了。可是當targetsdkversion升級到26的時候,同樣因為API的改動,也許會遇到問題。本文來介紹一下。這其中會遇到的問題。以及解決方案。

二.Android O(8.0)執行時許可權策略變化

許可權

在 Android 8.0 之前,如果應用在執行時請求許可權並且被授予該許可權,系統會錯誤地將屬於同一許可權組並且在清單中註冊的其他許可權也一起授予應用。

對於針對 Android 8.0 的應用,此行為已被糾正。系統只會授予應用明確請求的許可權。然而,一旦使用者為應用授予某個許可權,則所有後續對該許可權組中許可權的請求都將被自動批准。

例如,假設某個應用在其清單中列出 READ_EXTERNAL_STORAGE 和 WRITE_EXTERNAL_STORAGE。應用請求 READ_EXTERNAL_STORAGE,並且使用者授予了該許可權。如果該應用針對的是 API 級別 24 或更低級別,系統還會同時授予 WRITE_EXTERNAL_STORAGE,因為該許可權也屬於同一 STORAGE 許可權組並且也在清單中註冊過。如果該應用針對的是 Android 8.0,則系統此時僅會授予 READ_EXTERNAL_STORAGE;不過,如果該應用後來又請求 WRITE_EXTERNAL_STORAGE,則系統會立即授予該許可權,而不會提示使用者。

總結:

  1. 以前,申請一個子許可權會自動獲取許可權組中其他子許可權。組內其他子許可權可以直接使用。
  2. 現在,申請一個子許可權,組內其他子許可權不會自動獲取。使用組內其他子許可權的時候。需要再次申請。(但是這種情況不會彈出系統的許可權申請框)如果不申請。會FC。

三.解決方案:

3.1 許可權分組

同組許可權一起申請。當我們申請許可權時。申請同組的多個許可權時,也只會彈出一次申請框。所以不如一起申請。

public class PermissionGroup {

 ......

 //Storage許可權
 protected static String[] ABS_STORAGE = new String[] {
      Manifest.permission
.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE }; //Phone許可權 protected static String[] ABS_PHONE = new String[] { Manifest.permission.READ_PHONE_STATE, Manifest.permission.CALL_PHONE, Manifest.permission.READ_CALL_LOG, Manifest.permission.WRITE_CALL_LOG, Manifest.permission.USE_SIP, Manifest.permission.PROCESS_OUTGOING_CALLS }; ...... }

3.2 控制權限組粒度

因為機型問題,本以為可以定義好通用的PHONE許可權,然後一起申請,可是這也依賴於App中Manifest列表裡具體聲明瞭哪些許可權。假如我們僅僅在Manifest中聲明瞭<uses-permission android:name="android.permission.READ_PHONE_STATE"/>許可權。卻要申請Phone組內的全部許可權。有些機型會返回授權失敗。所以控制粒度。

public class PermissionConstant extends PermissionGroup {

  public static String[] PHONE;
  public static String[] STORAGE;

  static {

    PHONE = new String[] {
        Manifest.permission.READ_PHONE_STATE
    };

    STORAGE = ABS_STORAGE;
  }
}

3.3 申請整個許可權組。

所以當我們申請許可權的時候,就直接申請整組許可權吧。這樣就會完美適配Android O了。

後續會用一個元件來解決這個問題。