安卓權限申請封裝處理框架。測試支持4.0+。項目源於正式處理Android權限問題時,沒找到簡單、能滿足被拒絕權限自動會到系統設置處理的框架,按自己的編程習慣造一個熟悉的輪子還是蠻好的。第一次使用Android Studio,還是Eclipse敲代碼爽。來自一個(獨愛HTML+CSS來構建用戶界面的)Android很早入門的新手。
項目用到了
XXPermissions
中的權限列表、國產手機權限設置頁面跳轉列表,借鑒了其中的權限結果onRequestPermissionsResult
的接收方式。
Github:https://github.com/xiangyuecn/Android-UsesPermission
特性
- 一個函數調用處理權限申請的所有問題,被拒絕的權限重復詢問,被永久拒絕的權限(記住選擇、不再詢問)打開App授權系統設置。
- 函數式調用,代碼簡潔明晰,閱讀源碼不用跳來跳去。
- 明確的授權結果回調,要么有(True),要么沒有(False)。
- 默認0界面,調用者無需知道、提供、導入任何界面包括文件,但可深度定制。
- 中性,默認非弓雖J式、有回旋余地的對待拒絕權限的場景。
- 理論上支持任何Android版本(但僅在 4.0 - 9.0 模擬器上進行了測試)。
演示
可直接編譯test_app
項目進行測試,或者下載.assets/test_app-debug-xxx.apk
測試安裝包。
快速使用
直接復制lib_comm/src/main/java/ecomm/lib_comm/permission
里面的文件到你的程序里面即可使用。
示例代碼
//假設需要獲取攝像頭、錄音權限,直接在調用的地方實現抽象類,調用邏輯能簡單直觀不少
new UsesPermission(MainActivity.this, Permission.CAMERA, Permission.RECORD_AUDIO){
@Override
protected void onTrue(@NonNull ArrayList<String> lowerPermissions) {
//獲取了全部權限執后行此函數,
}
@Override
protected void onFalse(@NonNull ArrayList<String> rejectFinalPermissions, @NonNull ArrayList<String> rejectPermissions, @NonNull ArrayList<String> invalidPermissions) {
//未全部授權時執行此函數
}
//要么實現上面兩個方法即可,onTrue或onFalse只會有一個會被調用一次
//要么僅僅實現下面這個方法,不管授權了幾個權限都會調用一次
@Override
protected void onComplete(@NonNull ArrayList<String> resolvePermissions, @NonNull ArrayList<String> lowerPermissions, @NonNull ArrayList<String> rejectFinalPermissions, @NonNull ArrayList<String> rejectPermissions, @NonNull ArrayList<String> invalidPermissions) {
//完成回調,可能全部已授權、全部未授權、或者部分已授權
//通過resolvePermissions.contains(Permission.XXX)來判斷權限是否已授權
}
};
默認行為邏輯
- 先直接發起權限申請
- 普通權限(沒永久拒絕的權限)如果被拒絕(非永久拒絕),后續會安排再彈框申請一次(防用戶誤選)。
- 如果授權結果有被永久拒絕的,這部分權限會和第二步權限申請一起彈框跳轉到App授權系統設置。
- 彈一次框處理被永久拒絕的權限(彈一次夠了),跳轉到App授權系統設置界面。
可參考重寫onTips
方法修改此行為,做到不彈提示或者多次彈提示授權。
UsesPermission類文檔
import ecomm.lib_comm.permission.Permission;
這個類對外只有一個構造函數,直接new
直接調起授權請求。使用過程中只需重寫這個類的相應函數來控制授權請求行為。無多余、也不提供對外控制的方法。
構造函數
UsesPermission(activity,permissions,defaultTips="")
調用構造函數立即會調起授權請求,對permissions
列表中的權限進行申請。
請求過程中會根據onTips
返回的結果來控制提示信息、和授權請求流程,defaultTips
是onTips
默認實現使用到的提示信息默認值,默認為""字符串;具體邏輯參考onTips
。
回調類可重寫函數
這些函數都是可以選擇重寫,默認提供了空實現,不實現也沒關系。
void onTrue(lowerPermissions)
權限已全部授權時的回調,不管什么情況,onTrue
和onFalse
肯定有一個會回調。注意:方法內跟API版本有關的方法調用,應自行判斷API版本,因為低版本API中高版本權限請求全部會放行。
lowerPermissions
:如果是在低版本API上處理不支持的高版本新權限時,會忽略此項權限的檢測的檢測,默許放行,此時本參數將帶上此權限。
void onFalse(rejectFinalPermissions,rejectPermissions,invalidPermissions)
未授權時回調,不管什么情況,True和False肯定有一個會回調
rejectFinalPermissions
:被永久拒絕的權限列表,為rejectPermissions
的子集,空數組代表沒有此項。
rejectPermissions
:被拒絕的權限列表,空數組代表沒有此項。
invalidPermissions
:未在manifest
里聲明的權限列表,不會出現在rejectFinalPermissions
中,空數組代表沒有此項。
void onComplete(resolvePermissions,lowerPermissions,rejectFinalPermissions,rejectPermissions,invalidPermissions)
授權完成時回調,會在onTrue
和onFalse
之一回調后調用。
resolvePermissions
:已授權的權限列表。
lowerPermissions
:參考onTrue
,為resolvePermissions
的子集。
剩余參數參考onFalse
。
控制類可重寫函數
這些函數都是用來控制授權行為,都提供了默認實現。
String onTips(viewTipsCount,permissions,isFinal)
整個類里面最核心,邏輯最復雜的一個方法(雖然默認實現只有3行代碼)。此方法控制着整個權限請求的流程,彈不彈提示,嘗不嘗試重新申請,都是它說了算。
授權請求發起前會回調此方法,用來生成設置提示信息,也是來決定是否提示和進行授權。如果返回null,代表不進行下下一步操作;返回字符串會進行提示然后進行請求授權。注意:這個方法,會有不同權限進行多次調用;如果用戶選點擊了取消默認這些權限不會再調起請求(可重寫onCancelTips
修改此行為)。
默認行為為:
- 先直接發起權限申請
viewTipsCount=0
- 普通權限(非永久拒絕)如果被拒絕(非永久拒絕),后續會安排再彈框申請一次(防誤選)。
- 如果結果有被永久拒絕,這部分權限會和后面的永久權限申請一起彈框處理。
- 彈一次框處理被永久拒絕的權限(彈一次夠了),跳轉到App授權系統設置界面
viewTipsCount=1+
@param viewTipsCount 0-n 是第幾次准備彈提示框。
0:申請前的引導提示,返回null代表不彈提示,直接調起授權。
注意:第0次包含所有權限(不含帶自定義授權請求的權限),無法區分是不是永久拒絕的權限。
1+:被永久拒絕的權限申請,或普通權限上一輪被拒。
注意:為1的時候,如果權限帶自定義的授權請求方式,就算返回了null,也會進行提示並調用授權請求。
@param permissions 被拒絕的權限列表
@param isFinal 這個權限列表是不是永久被拒絕的權限,true是,false為未永久拒絕
@return 返回提示信息;返回值為null不進行申請;為空字符串時自動生成合理的提示。
字符串內容支持特定占位符:
{Auto}:用自動生成提示內容替換
{Names}:自動替換被拒絕的權限名稱
如:'xx"{Names}"xx' => 'xx"權限名1,權限名2,權限名3"xx'
String onCancelTips(viewCancelCount,permissions,isFinal)
不建議重寫,取消了也彈提示真不友好,彈出了提示時,用戶點擊了取消時的額外提示信息。返回null徹底不再調起提示,默認就是返回null。這個回調的用法和onTips
一模一樣,只是這個僅僅作用在點擊了取消時。注意:重寫這個方法應該慎重,最多viewCancelCount
幾次后就返回null
,避免出現無法取消永遠彈框的問題。
viewCancelCount
1-n
當前這次請求是第幾次取消。
String onTipsDialogView(tips,isCancel,viewTipsCount,permissions,isFinal,okCall,cancelCall)
授權提示彈框,重寫此方法自定義彈框行為,默認使用系統AlertDialog
彈框。只要求必須回調okCall
,cancelCall
中的任何一個,怎么顯示界面、顯示多少個界面 -> 隨意。
Permission類文檔
import ecomm.lib_comm.permission.Permission;
這個類封裝了8.0版本的危險權限列表,並且提供了對應的權限名稱映射。
權限列表
使用過程中推薦使用這個類里面定義的權限,比如Permission.CAMERA
。如果用Manifest.permission.CAMERA
也可以,他們是等價的。
靜態方法
String QueryName(permission)
查詢權限對應的名稱,比如Permission.CAMERA
對應的名稱為相機
。
String QueryNames(permissions)
獲取權限名稱列表,如權限名1,權限名2,權限名3
,此方法用於方便的生成授權提示信息。
最佳實踐
使用默認實現
不重寫onTips
即為默認實現。
請求授權時直接彈出請求,用戶如果點了拒絕(非永久),后續還會彈一次提示,防止誤點。如果有被永久拒絕的權限,會彈提示,轉到系統設置。
授權前先提示
在調起授權前先彈提示,其他行為和默認實現一樣。重寫onTips
方法:
@Override
protected String onTips(int viewTipsCount, @NonNull ArrayList<String> permissions, boolean isFinal) {
if(viewTipsCount<=1) {
return "";
}
return null;
}
不授權永遠彈提示
如果不授權功能是沒法使用的場景,可以一直彈提示,直到用戶點擊了取消為止(可重寫onCancelTips
讓無法取消,但不建議)。重寫onTips
方法:
protected String onTips(int viewTipsCount, @NonNull ArrayList<String> permissions, boolean isFinal) {
if(viewTipsCount>0) {//如果需要授權調起前先提醒,直接把這個if去掉就行了
return "";
}
return null;
}
靜默方式授權
如果權限被拒絕,不彈任何提示,也不跳轉權限系統設置界面。僅僅用來調起授權請求。但對於需要引導才能進行權限設置的除外(如安裝、懸浮窗權限)。重寫onTips
方法:
protected String onTips(int viewTipsCount, @NonNull ArrayList<String> permissions, boolean isFinal) {
return null;
}
自定義提示界面
默認實現在彈提示的時候使用的是系統AlertDialog
彈框,可重寫onTipsDialogView
方法來使用自己的提示界面。比如HiPermission
的這種蠻美觀友好的界面:
這個庫不提供界面實現,需要自行實現。
更多實現
參考test_app
目錄中的MainActivity
,里面有已實現的代碼。
相關源碼請前往Github查閱,如果這個庫有幫助到您,請 Star 一下。