安卓權(quán)限申請(qǐng)封裝處理框架枕屉。測(cè)試支持4.0+。項(xiàng)目源于正式處理Android權(quán)限問題時(shí),沒找到簡單廓奕、能滿足被拒絕權(quán)限自動(dòng)會(huì)到系統(tǒng)設(shè)置處理的框架,按自己的編程習(xí)慣造一個(gè)熟悉的輪子還是蠻好的档叔。第一次使用Android Studio桌粉,還是Eclipse敲代碼爽。來自一個(gè)(獨(dú)愛HTML+CSS來構(gòu)建用戶界面的)Android很早入門的新手衙四。
項(xiàng)目用到了
XXPermissions
中的權(quán)限列表铃肯、國產(chǎn)手機(jī)權(quán)限設(shè)置頁面跳轉(zhuǎn)列表,借鑒了其中的權(quán)限結(jié)果onRequestPermissionsResult
的接收方式传蹈。
Github:https://github.com/xiangyuecn/Android-UsesPermission
特性
- 一個(gè)函數(shù)調(diào)用處理權(quán)限申請(qǐng)的所有問題押逼,被拒絕的權(quán)限重復(fù)詢問步藕,被永久拒絕的權(quán)限(記住選擇、不再詢問)打開App授權(quán)系統(tǒng)設(shè)置挑格。
- 函數(shù)式調(diào)用咙冗,代碼簡潔明晰,閱讀源碼不用跳來跳去漂彤。
- 明確的授權(quán)結(jié)果回調(diào)雾消,要么有(True),要么沒有(False)显歧。
- 默認(rèn)0界面仪或,調(diào)用者無需知道、提供士骤、導(dǎo)入任何界面包括文件范删,但可深度定制。
- 中性拷肌,默認(rèn)非弓雖J式到旦、有回旋余地的對(duì)待拒絕權(quán)限的場(chǎng)景。
- 理論上支持任何Android版本(但僅在 4.0 - 9.0 模擬器上進(jìn)行了測(cè)試)巨缘。
演示
可直接編譯test_app
項(xiàng)目進(jìn)行測(cè)試添忘,或者下載.assets/test_app-debug-xxx.apk
測(cè)試安裝包。
快速使用
直接復(fù)制lib_comm/src/main/java/ecomm/lib_comm/permission
里面的文件到你的程序里面即可使用若锁。
示例代碼
//假設(shè)需要獲取攝像頭搁骑、錄音權(quán)限,直接在調(diào)用的地方實(shí)現(xiàn)抽象類又固,調(diào)用邏輯能簡單直觀不少
new UsesPermission(MainActivity.this, Permission.CAMERA, Permission.RECORD_AUDIO){
@Override
protected void onTrue(@NonNull ArrayList<String> lowerPermissions) {
//獲取了全部權(quán)限執(zhí)后行此函數(shù)仲器,
}
@Override
protected void onFalse(@NonNull ArrayList<String> rejectFinalPermissions, @NonNull ArrayList<String> rejectPermissions, @NonNull ArrayList<String> invalidPermissions) {
//未全部授權(quán)時(shí)執(zhí)行此函數(shù)
}
//要么實(shí)現(xiàn)上面兩個(gè)方法即可,onTrue或onFalse只會(huì)有一個(gè)會(huì)被調(diào)用一次
//要么僅僅實(shí)現(xiàn)下面這個(gè)方法仰冠,不管授權(quán)了幾個(gè)權(quán)限都會(huì)調(diào)用一次
@Override
protected void onComplete(@NonNull ArrayList<String> resolvePermissions, @NonNull ArrayList<String> lowerPermissions, @NonNull ArrayList<String> rejectFinalPermissions, @NonNull ArrayList<String> rejectPermissions, @NonNull ArrayList<String> invalidPermissions) {
//完成回調(diào)乏冀,可能全部已授權(quán)、全部未授權(quán)洋只、或者部分已授權(quán)
//通過resolvePermissions.contains(Permission.XXX)來判斷權(quán)限是否已授權(quán)
}
};
默認(rèn)行為邏輯
- 先直接發(fā)起權(quán)限申請(qǐng)
- 普通權(quán)限(沒永久拒絕的權(quán)限)如果被拒絕(非永久拒絕)辆沦,后續(xù)會(huì)安排再彈框申請(qǐng)一次(防用戶誤選)。
- 如果授權(quán)結(jié)果有被永久拒絕的识虚,這部分權(quán)限會(huì)和第二步權(quán)限申請(qǐng)一起彈框跳轉(zhuǎn)到App授權(quán)系統(tǒng)設(shè)置肢扯。
- 彈一次框處理被永久拒絕的權(quán)限(彈一次夠了)姿搜,跳轉(zhuǎn)到App授權(quán)系統(tǒng)設(shè)置界面仁烹。
可參考重寫onTips
方法修改此行為,做到不彈提示或者多次彈提示授權(quán)筒占。
UsesPermission類文檔
import ecomm.lib_comm.permission.Permission;
這個(gè)類對(duì)外只有一個(gè)構(gòu)造函數(shù)妻献,直接new
直接調(diào)起授權(quán)請(qǐng)求蛛株。使用過程中只需重寫這個(gè)類的相應(yīng)函數(shù)來控制授權(quán)請(qǐng)求行為。無多余育拨、也不提供對(duì)外控制的方法谨履。
構(gòu)造函數(shù)
UsesPermission(activity,permissions,defaultTips="")
調(diào)用構(gòu)造函數(shù)立即會(huì)調(diào)起授權(quán)請(qǐng)求,對(duì)permissions
列表中的權(quán)限進(jìn)行申請(qǐng)熬丧。
請(qǐng)求過程中會(huì)根據(jù)onTips
返回的結(jié)果來控制提示信息笋粟、和授權(quán)請(qǐng)求流程,defaultTips
是onTips
默認(rèn)實(shí)現(xiàn)使用到的提示信息默認(rèn)值析蝴,默認(rèn)為""字符串害捕;具體邏輯參考onTips
。
回調(diào)類可重寫函數(shù)
這些函數(shù)都是可以選擇重寫闷畸,默認(rèn)提供了空實(shí)現(xiàn)尝盼,不實(shí)現(xiàn)也沒關(guān)系。
void onTrue(lowerPermissions)
權(quán)限已全部授權(quán)時(shí)的回調(diào)佑菩,不管什么情況盾沫,onTrue
和onFalse
肯定有一個(gè)會(huì)回調(diào)。注意:方法內(nèi)跟API版本有關(guān)的方法調(diào)用殿漠,應(yīng)自行判斷API版本赴精,因?yàn)榈桶姹続PI中高版本權(quán)限請(qǐng)求全部會(huì)放行。
lowerPermissions
:如果是在低版本API上處理不支持的高版本新權(quán)限時(shí)绞幌,會(huì)忽略此項(xiàng)權(quán)限的檢測(cè)的檢測(cè)蕾哟,默許放行,此時(shí)本參數(shù)將帶上此權(quán)限莲蜘。
void onFalse(rejectFinalPermissions,rejectPermissions,invalidPermissions)
未授權(quán)時(shí)回調(diào)谭确,不管什么情況,True和False肯定有一個(gè)會(huì)回調(diào)
rejectFinalPermissions
:被永久拒絕的權(quán)限列表菇夸,為rejectPermissions
的子集琼富,空數(shù)組代表沒有此項(xiàng)。
rejectPermissions
:被拒絕的權(quán)限列表庄新,空數(shù)組代表沒有此項(xiàng)鞠眉。
invalidPermissions
:未在manifest
里聲明的權(quán)限列表,不會(huì)出現(xiàn)在rejectFinalPermissions
中择诈,空數(shù)組代表沒有此項(xiàng)械蹋。
void onComplete(resolvePermissions,lowerPermissions,rejectFinalPermissions,rejectPermissions,invalidPermissions)
授權(quán)完成時(shí)回調(diào),會(huì)在onTrue
和onFalse
之一回調(diào)后調(diào)用羞芍。
resolvePermissions
:已授權(quán)的權(quán)限列表哗戈。
lowerPermissions
:參考onTrue
,為resolvePermissions
的子集荷科。
剩余參數(shù)參考onFalse
唯咬。
控制類可重寫函數(shù)
這些函數(shù)都是用來控制授權(quán)行為纱注,都提供了默認(rèn)實(shí)現(xiàn)。
String onTips(viewTipsCount,permissions,isFinal)
整個(gè)類里面最核心胆胰,邏輯最復(fù)雜的一個(gè)方法(雖然默認(rèn)實(shí)現(xiàn)只有3行代碼)狞贱。此方法控制著整個(gè)權(quán)限請(qǐng)求的流程,彈不彈提示蜀涨,嘗不嘗試重新申請(qǐng)瞎嬉,都是它說了算。
授權(quán)請(qǐng)求發(fā)起前會(huì)回調(diào)此方法厚柳,用來生成設(shè)置提示信息氧枣,也是來決定是否提示和進(jìn)行授權(quán)。如果返回null别垮,代表不進(jìn)行下下一步操作便监;返回字符串會(huì)進(jìn)行提示然后進(jìn)行請(qǐng)求授權(quán)。注意:這個(gè)方法宰闰,會(huì)有不同權(quán)限進(jìn)行多次調(diào)用茬贵;如果用戶選點(diǎn)擊了取消默認(rèn)這些權(quán)限不會(huì)再調(diào)起請(qǐng)求(可重寫onCancelTips
修改此行為)。
默認(rèn)行為為:
- 先直接發(fā)起權(quán)限申請(qǐng)
viewTipsCount=0
- 普通權(quán)限(非永久拒絕)如果被拒絕(非永久拒絕)移袍,后續(xù)會(huì)安排再彈框申請(qǐng)一次(防誤選)解藻。
- 如果結(jié)果有被永久拒絕,這部分權(quán)限會(huì)和后面的永久權(quán)限申請(qǐng)一起彈框處理葡盗。
- 彈一次框處理被永久拒絕的權(quán)限(彈一次夠了)螟左,跳轉(zhuǎn)到App授權(quán)系統(tǒng)設(shè)置界面
viewTipsCount=1+
@param viewTipsCount 0-n 是第幾次準(zhǔn)備彈提示框。
0:申請(qǐng)前的引導(dǎo)提示觅够,返回null代表不彈提示胶背,直接調(diào)起授權(quán)。
注意:第0次包含所有權(quán)限(不含帶自定義授權(quán)請(qǐng)求的權(quán)限)喘先,無法區(qū)分是不是永久拒絕的權(quán)限钳吟。
1+:被永久拒絕的權(quán)限申請(qǐng),或普通權(quán)限上一輪被拒窘拯。
注意:為1的時(shí)候红且,如果權(quán)限帶自定義的授權(quán)請(qǐng)求方式,就算返回了null涤姊,也會(huì)進(jìn)行提示并調(diào)用授權(quán)請(qǐng)求暇番。
@param permissions 被拒絕的權(quán)限列表
@param isFinal 這個(gè)權(quán)限列表是不是永久被拒絕的權(quán)限,true是思喊,false為未永久拒絕
@return 返回提示信息壁酬;返回值為null不進(jìn)行申請(qǐng);為空字符串時(shí)自動(dòng)生成合理的提示。
字符串內(nèi)容支持特定占位符:
{Auto}:用自動(dòng)生成提示內(nèi)容替換
{Names}:自動(dòng)替換被拒絕的權(quán)限名稱
如:'xx"{Names}"xx' => 'xx"權(quán)限名1,權(quán)限名2,權(quán)限名3"xx'
String onCancelTips(viewCancelCount,permissions,isFinal)
不建議重寫舆乔,取消了也彈提示真不友好岳服,彈出了提示時(shí),用戶點(diǎn)擊了取消時(shí)的額外提示信息蜕煌。返回null徹底不再調(diào)起提示派阱,默認(rèn)就是返回null。這個(gè)回調(diào)的用法和onTips
一模一樣斜纪,只是這個(gè)僅僅作用在點(diǎn)擊了取消時(shí)。注意:重寫這個(gè)方法應(yīng)該慎重文兑,最多viewCancelCount
幾次后就返回null
盒刚,避免出現(xiàn)無法取消永遠(yuǎn)彈框的問題。
viewCancelCount
1-n
當(dāng)前這次請(qǐng)求是第幾次取消绿贞。
String onTipsDialogView(tips,isCancel,viewTipsCount,permissions,isFinal,okCall,cancelCall)
授權(quán)提示彈框因块,重寫此方法自定義彈框行為,默認(rèn)使用系統(tǒng)AlertDialog
彈框籍铁。只要求必須回調(diào)okCall
涡上,cancelCall
中的任何一個(gè),怎么顯示界面拒名、顯示多少個(gè)界面 -> 隨意吩愧。
Permission類文檔
import ecomm.lib_comm.permission.Permission;
這個(gè)類封裝了8.0版本的危險(xiǎn)權(quán)限列表,并且提供了對(duì)應(yīng)的權(quán)限名稱映射增显。
權(quán)限列表
使用過程中推薦使用這個(gè)類里面定義的權(quán)限雁佳,比如Permission.CAMERA
。如果用Manifest.permission.CAMERA
也可以同云,他們是等價(jià)的糖权。
靜態(tài)方法
String QueryName(permission)
查詢權(quán)限對(duì)應(yīng)的名稱,比如Permission.CAMERA
對(duì)應(yīng)的名稱為相機(jī)
炸站。
String QueryNames(permissions)
獲取權(quán)限名稱列表星澳,如權(quán)限名1,權(quán)限名2,權(quán)限名3
,此方法用于方便的生成授權(quán)提示信息旱易。
最佳實(shí)踐
使用默認(rèn)實(shí)現(xiàn)
不重寫onTips
即為默認(rèn)實(shí)現(xiàn)禁偎。
請(qǐng)求授權(quán)時(shí)直接彈出請(qǐng)求,用戶如果點(diǎn)了拒絕(非永久)咒唆,后續(xù)還會(huì)彈一次提示届垫,防止誤點(diǎn)。如果有被永久拒絕的權(quán)限全释,會(huì)彈提示装处,轉(zhuǎn)到系統(tǒng)設(shè)置。
授權(quán)前先提示
在調(diào)起授權(quán)前先彈提示,其他行為和默認(rèn)實(shí)現(xiàn)一樣妄迁。重寫onTips
方法:
@Override
protected String onTips(int viewTipsCount, @NonNull ArrayList<String> permissions, boolean isFinal) {
if(viewTipsCount<=1) {
return "";
}
return null;
}
不授權(quán)永遠(yuǎn)彈提示
如果不授權(quán)功能是沒法使用的場(chǎng)景寝蹈,可以一直彈提示,直到用戶點(diǎn)擊了取消為止(可重寫onCancelTips
讓無法取消登淘,但不建議)箫老。重寫onTips
方法:
protected String onTips(int viewTipsCount, @NonNull ArrayList<String> permissions, boolean isFinal) {
if(viewTipsCount>0) {//如果需要授權(quán)調(diào)起前先提醒,直接把這個(gè)if去掉就行了
return "";
}
return null;
}
靜默方式授權(quán)
如果權(quán)限被拒絕黔州,不彈任何提示耍鬓,也不跳轉(zhuǎn)權(quán)限系統(tǒng)設(shè)置界面。僅僅用來調(diào)起授權(quán)請(qǐng)求流妻。但對(duì)于需要引導(dǎo)才能進(jìn)行權(quán)限設(shè)置的除外(如安裝牲蜀、懸浮窗權(quán)限)。重寫onTips
方法:
protected String onTips(int viewTipsCount, @NonNull ArrayList<String> permissions, boolean isFinal) {
return null;
}
自定義提示界面
默認(rèn)實(shí)現(xiàn)在彈提示的時(shí)候使用的是系統(tǒng)AlertDialog
彈框绅这,可重寫onTipsDialogView
方法來使用自己的提示界面涣达。比如HiPermission
的這種蠻美觀友好的界面:
這個(gè)庫不提供界面實(shí)現(xiàn),需要自行實(shí)現(xiàn)证薇。
更多實(shí)現(xiàn)
參考test_app
目錄中的MainActivity
度苔,里面有已實(shí)現(xiàn)的代碼。
相關(guān)源碼請(qǐng)前往Github查閱浑度,如果這個(gè)庫有幫助到您寇窑,請(qǐng) Star 一下。