一.序
在之前的文章聊聊Android M 6.0 的運行時權(quán)限曾提到過抚垃,Google Play開發(fā)者明年勢必要努力將targetsdkversion升級到26的過程中听皿。官網(wǎng)的文檔:向 Android 8.0 遷移應(yīng)用 已經(jīng)給大家了一個升級指南。當(dāng)然動態(tài)權(quán)限也是需要關(guān)注的一部分室埋。可能有部分開發(fā)者已經(jīng)將targetsdkversion升級到23了∷浚可是當(dāng)targetsdkversion升級到26的時候,同樣因為API的改動尤蛮,也許會遇到問題媳友。本文來介紹一下。這其中會遇到的問題产捞。以及解決方案醇锚。
二.Android O(8.0)運行時權(quán)限策略變化
借用官網(wǎng)的文檔
權(quán)限
在 Android 8.0 之前,如果應(yīng)用在運行時請求權(quán)限并且被授予該權(quán)限坯临,系統(tǒng)會錯誤地將屬于同一權(quán)限組并且在清單中注冊的其他權(quán)限也一起授予應(yīng)用搂抒。
對于針對 Android 8.0 的應(yīng)用艇搀,此行為已被糾正。系統(tǒng)只會授予應(yīng)用明確請求的權(quán)限求晶。然而焰雕,一旦用戶為應(yīng)用授予某個權(quán)限,則所有后續(xù)對該權(quán)限組中權(quán)限的請求都將被自動批準(zhǔn)芳杏。
例如矩屁,假設(shè)某個應(yīng)用在其清單中列出 READ_EXTERNAL_STORAGE 和 WRITE_EXTERNAL_STORAGE。應(yīng)用請求 READ_EXTERNAL_STORAGE,并且用戶授予了該權(quán)限。如果該應(yīng)用針對的是 API 級別 24 或更低級別衩婚,系統(tǒng)還會同時授予 WRITE_EXTERNAL_STORAGE莱预,因為該權(quán)限也屬于同一 STORAGE 權(quán)限組并且也在清單中注冊過。如果該應(yīng)用針對的是 Android 8.0但壮,則系統(tǒng)此時僅會授予 READ_EXTERNAL_STORAGE;不過,如果該應(yīng)用后來又請求 WRITE_EXTERNAL_STORAGE约郁,則系統(tǒng)會立即授予該權(quán)限,而不會提示用戶但两。
總結(jié):
- 以前鬓梅,申請一個子權(quán)限會自動獲取權(quán)限組中其他子權(quán)限。組內(nèi)其他子權(quán)限可以直接使用谨湘。
- 現(xiàn)在绽快,申請一個子權(quán)限,組內(nèi)其他子權(quán)限不會自動獲取紧阔。使用組內(nèi)其他子權(quán)限的時候坊罢。需要再次申請。(但是這種情況不會彈出系統(tǒng)的權(quán)限申請框)如果不申請擅耽。會FC活孩。
三.解決方案:
3.1 權(quán)限分組
同組權(quán)限一起申請。當(dāng)我們申請權(quán)限時秫筏。申請同組的多個權(quán)限時诱鞠,也只會彈出一次申請框。所以不如一起申請这敬。
public class PermissionGroup {
......
//Storage權(quán)限
protected static String[] ABS_STORAGE = new String[] {
Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE
};
//Phone權(quán)限
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 控制權(quán)限組粒度
因為機型問題航夺,本以為可以定義好通用的PHONE權(quán)限,然后一起申請崔涂,可是這也依賴于App中Manifest列表里具體聲明了哪些權(quán)限阳掐。假如我們僅僅在Manifest中聲明了<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
權(quán)限。卻要申請Phone組內(nèi)的全部權(quán)限。有些機型會返回授權(quán)失敗缭保。所以控制粒度汛闸。
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 申請整個權(quán)限組。
所以當(dāng)我們申請權(quán)限的時候艺骂,就直接申請整組權(quán)限吧诸老。這樣就會完美適配Android O了。
后續(xù)會用一個組件來解決這個問題钳恕。