安卓權(quán)限申請(qǐng)?zhí)幚砜蚣蹵ndroid-UsesPermission

安卓權(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

特性

  1. 一個(gè)函數(shù)調(diào)用處理權(quán)限申請(qǐng)的所有問題押逼,被拒絕的權(quán)限重復(fù)詢問步藕,被永久拒絕的權(quán)限(記住選擇、不再詢問)打開App授權(quán)系統(tǒng)設(shè)置挑格。
  2. 函數(shù)式調(diào)用咙冗,代碼簡潔明晰,閱讀源碼不用跳來跳去漂彤。
  3. 明確的授權(quán)結(jié)果回調(diào)雾消,要么有(True),要么沒有(False)显歧。
  4. 默認(rèn)0界面仪或,調(diào)用者無需知道、提供士骤、導(dǎo)入任何界面包括文件范删,但可深度定制。
  5. 中性拷肌,默認(rèn)非弓雖J式到旦、有回旋余地的對(duì)待拒絕權(quán)限的場(chǎng)景。
  6. 理論上支持任何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)行為邏輯

  1. 先直接發(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è)置肢扯。
  2. 彈一次框處理被永久拒絕的權(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)求流程,defaultTipsonTips默認(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)佑菩,不管什么情況盾沫,onTrueonFalse肯定有一個(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ì)在onTrueonFalse之一回調(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)行為為:

  1. 先直接發(fā)起權(quán)限申請(qǐng) viewTipsCount=0
    • 普通權(quán)限(非永久拒絕)如果被拒絕(非永久拒絕)移袍,后續(xù)會(huì)安排再彈框申請(qǐng)一次(防誤選)解藻。
    • 如果結(jié)果有被永久拒絕,這部分權(quán)限會(huì)和后面的永久權(quán)限申請(qǐng)一起彈框處理葡盗。
  2. 彈一次框處理被永久拒絕的權(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 一下。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末俺泣,一起剝皮案震驚了整個(gè)濱河市疗认,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌伏钠,老刑警劉巖横漏,帶你破解...
    沈念sama閱讀 211,290評(píng)論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異熟掂,居然都是意外死亡缎浇,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,107評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門赴肚,熙熙樓的掌柜王于貴愁眉苦臉地迎上來素跺,“玉大人,你說我怎么就攤上這事誉券≈秆幔” “怎么了?”我有些...
    開封第一講書人閱讀 156,872評(píng)論 0 347
  • 文/不壞的土叔 我叫張陵踊跟,是天一觀的道長踩验。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么箕憾? 我笑而不...
    開封第一講書人閱讀 56,415評(píng)論 1 283
  • 正文 為了忘掉前任牡借,我火速辦了婚禮,結(jié)果婚禮上袭异,老公的妹妹穿的比我還像新娘钠龙。我一直安慰自己,他們只是感情好御铃,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,453評(píng)論 6 385
  • 文/花漫 我一把揭開白布碴里。 她就那樣靜靜地躺著,像睡著了一般畅买。 火紅的嫁衣襯著肌膚如雪并闲。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,784評(píng)論 1 290
  • 那天谷羞,我揣著相機(jī)與錄音,去河邊找鬼溜徙。 笑死湃缎,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的蠢壹。 我是一名探鬼主播嗓违,決...
    沈念sama閱讀 38,927評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼图贸!你這毒婦竟也來了蹂季?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,691評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤疏日,失蹤者是張志新(化名)和其女友劉穎偿洁,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體沟优,經(jīng)...
    沈念sama閱讀 44,137評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡涕滋,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,472評(píng)論 2 326
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了挠阁。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片宾肺。...
    茶點(diǎn)故事閱讀 38,622評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖侵俗,靈堂內(nèi)的尸體忽然破棺而出锨用,到底是詐尸還是另有隱情,我是刑警寧澤隘谣,帶...
    沈念sama閱讀 34,289評(píng)論 4 329
  • 正文 年R本政府宣布增拥,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏跪者。R本人自食惡果不足惜棵帽,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,887評(píng)論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望渣玲。 院中可真熱鬧逗概,春花似錦、人聲如沸忘衍。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,741評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽铅搓。三九已至,卻和暖如春搀捷,著一層夾襖步出監(jiān)牢的瞬間星掰,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評(píng)論 1 265
  • 我被黑心中介騙來泰國打工嫩舟, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留氢烘,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,316評(píng)論 2 360
  • 正文 我出身青樓家厌,卻偏偏與公主長得像播玖,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子饭于,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,490評(píng)論 2 348