封裝Android M動(dòng)態(tài)權(quán)限申請(qǐng)庫(kù)

這段時(shí)間歹河,由于項(xiàng)目上適配android M 中的動(dòng)態(tài)權(quán)限申請(qǐng),頻繁的寫(xiě)了一些重復(fù)的權(quán)限申請(qǐng)代碼花吟,都快想吐了秸歧,還有各種fragment中嵌套fragment的問(wèn)題,既如此何不把它封裝一下衅澈。下面直接看代碼键菱。

public class MPermission {
    private static final int PERMISSION_CODE = 0x100;
    private Object obj;
    private static Method methodOK, methodFail;
    private String[] permissions;//權(quán)限數(shù)組
    private MPermission(Object obj) {
        this.obj=obj;
        methodOK=null;
        methodFail=null;
        findMethod(obj);
    }
    private void findMethod(Object o) {
        Method[] methods = o.getClass().getDeclaredMethods();
        for (Method method : methods) {
            if (method.isAnnotationPresent(PermissionOK.class)) {
                methodOK = method;
                if(methodFail!=null){
                    break;
                }
            }else
 if(method.isAnnotationPresent(PermissionFail.class)){
                methodFail=method;
                if(methodOK!=null){
                    break;
                }
            }
        }
    }
    public static MPermission with(Object obj) {
        return new MPermission(obj);
    }
    public MPermission setPermission(String... permissions) {
        if (permissions != null && permissions.length == 0) {
            throw new RuntimeException("必須填寫(xiě)需要申請(qǐng)的權(quán)限");
        }
        this.permissions = permissions;
        return this;
    }
    public void requestPermission() {
        int index=hasPermission(permissions);
        if (index!=-1) {
            //當(dāng)檢查時(shí)發(fā)現(xiàn)系統(tǒng)不存在這個(gè)權(quán)限的時(shí)候,需要判斷當(dāng)前系統(tǒng)版本是否>=23
            if(Build.VERSION.SDK_INT>=23){
                requestPermissionApi23();
            }else{
                //此處模仿官方API中的方法 進(jìn)行回調(diào)
                //API23一下的版本直接返回失敗
                int[] grantResults = new int[permissions.length];
                for (int i = 0; i < grantResults.length; i++){
                    if(i<index){
                        grantResults[i] =PackageManager.PERMISSION_GRANTED;
                    }else {
                        grantResults[i]=PackageManager.PERMISSION_DENIED;
                    }
                }
                requestPermissionApi(grantResults);
            }
        } else {
            if(methodOK!=null) {
                try {
                    methodOK.setAccessible(true);
                    methodOK.invoke(obj, new Object[]{});
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                } catch (InvocationTargetException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    @TargetApi(Build.VERSION_CODES.M)
    private void requestPermissionApi23(){
        if(obj instanceof Activity){         
            ((Activity)obj).requestPermissions(permissions,PERMISSION_CODE);
        }else if(obj instanceof Fragment){
            ((Fragment)obj).requestPermissions(permissions,PERMISSION_CODE);
        }
    }
    private void requestPermissionApi(int[] grantResults){
        if(obj instanceof ActivityCompat.OnRequestPermissionsResultCallback){
            ((ActivityCompat.OnRequestPermissionsResultCallback)obj).onRequestPermissionsResult(PERMISSION_CODE,permissions,grantResults);
        }else if(obj instanceof Fragment){
            ((Fragment)obj).onRequestPermissionsResult(PERMISSION_CODE,permissions,grantResults);
        }
    }
    private int hasPermission(String[] permissions) {
        int index=-1;
        for (int i=0,j=permissions.length;i<j;i++) {
            if (ActivityCompat.checkSelfPermission(Zilla.APP.getApplicationContext(), permissions[i])
                    != PackageManager.PERMISSION_GRANTED) {
                index=i;
                break;
            }
        }
        return index;
    }
    public static void onRequestPermissionsResult(Object o,int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        if (requestCode == PERMISSION_CODE) {
            if (grantResults.length == permissions.length) { 
               for (int grant : grantResults) {
                    if (grant != PackageManager.PERMISSION_GRANTED) {
                        if(methodFail!=null){
                            try {
                                methodFail.invoke(o,new Object[]{});
                            } catch (IllegalAccessException e) {
                                e.printStackTrace();
                            } catch (InvocationTargetException e) {
                                e.printStackTrace();
                            }
                        }
                        return;
                    }
                }
                //權(quán)限都允許了,
                if(methodOK!=null) {
                    try {
                        methodOK.setAccessible(true);
                        methodOK.invoke(o, new Object[]{});
                    } catch (IllegalAccessException e) {
                        e.printStackTrace();
                    } catch (InvocationTargetException e) {
                        e.printStackTrace();
                    }
                }
            } else {
                if(methodFail!=null){
                    try {
                        methodFail.invoke(o,new Object[]{});
                    } catch (IllegalAccessException e) {
                        e.printStackTrace();
                    } catch (InvocationTargetException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }
}

剩下的還有兩個(gè)是注解類(lèi):

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface PermissionFail {}
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface PermissionOK {}

以上就是所以的源碼今布,他的使用方式很簡(jiǎn)單

在Fragment個(gè)Activity中你可以這樣做

//Call it anywhere you want it to.
MPermission.with(this)
        .setPermission(Manifest.permission.READ_EXTERNAL_STORAGE
        ,Manifest.permission.WRITE_EXTERNAL_STORAGE...)
        .requestPermission();
            @Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    MPermission.onRequestPermissionsResult(this,requestCode,permissions,grantResults);
}
@PermissionOK
private void valdateSuccess(){
    Log.i("權(quán)限通過(guò)");
}
@PermissionFail
public void validateFail(){
    Log.i("沒(méi)有相應(yīng)的權(quán)限");
}
如此一勞永逸纱耻,是不是很簡(jiǎn)單

歡迎共同探討更多安卓,java险耀,c/c++相關(guān)技術(shù)QQ群:392154157
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市玖喘,隨后出現(xiàn)的幾起案子甩牺,更是在濱河造成了極大的恐慌,老刑警劉巖累奈,帶你破解...
    沈念sama閱讀 217,185評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件贬派,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡澎媒,警方通過(guò)查閱死者的電腦和手機(jī)搞乏,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,652評(píng)論 3 393
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)戒努,“玉大人请敦,你說(shuō)我怎么就攤上這事〈⒚担” “怎么了侍筛?”我有些...
    開(kāi)封第一講書(shū)人閱讀 163,524評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀(guān)的道長(zhǎng)撒穷。 經(jīng)常有香客問(wèn)我匣椰,道長(zhǎng),這世上最難降的妖魔是什么端礼? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,339評(píng)論 1 293
  • 正文 為了忘掉前任禽笑,我火速辦了婚禮入录,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘佳镜。我一直安慰自己僚稿,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,387評(píng)論 6 391
  • 文/花漫 我一把揭開(kāi)白布邀杏。 她就那樣靜靜地躺著贫奠,像睡著了一般。 火紅的嫁衣襯著肌膚如雪望蜡。 梳的紋絲不亂的頭發(fā)上唤崭,一...
    開(kāi)封第一講書(shū)人閱讀 51,287評(píng)論 1 301
  • 那天,我揣著相機(jī)與錄音脖律,去河邊找鬼谢肾。 笑死,一個(gè)胖子當(dāng)著我的面吹牛小泉,可吹牛的內(nèi)容都是我干的芦疏。 我是一名探鬼主播,決...
    沈念sama閱讀 40,130評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼微姊,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼酸茴!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起兢交,我...
    開(kāi)封第一講書(shū)人閱讀 38,985評(píng)論 0 275
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤薪捍,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后配喳,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體酪穿,經(jīng)...
    沈念sama閱讀 45,420評(píng)論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,617評(píng)論 3 334
  • 正文 我和宋清朗相戀三年晴裹,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了被济。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,779評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡涧团,死狀恐怖只磷,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情泌绣,我是刑警寧澤喳瓣,帶...
    沈念sama閱讀 35,477評(píng)論 5 345
  • 正文 年R本政府宣布,位于F島的核電站赞别,受9級(jí)特大地震影響畏陕,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜仿滔,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,088評(píng)論 3 328
  • 文/蒙蒙 一惠毁、第九天 我趴在偏房一處隱蔽的房頂上張望犹芹。 院中可真熱鬧,春花似錦鞠绰、人聲如沸腰埂。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,716評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)屿笼。三九已至,卻和暖如春翁巍,著一層夾襖步出監(jiān)牢的瞬間驴一,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,857評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工灶壶, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留肝断,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,876評(píng)論 2 370
  • 正文 我出身青樓驰凛,卻偏偏與公主長(zhǎng)得像胸懈,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子恰响,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,700評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,099評(píng)論 25 707
  • 一趣钱、引言 隨著Android6.0發(fā)布,系統(tǒng)增加了一些新的特性和功能胚宦。這次的發(fā)布介紹了一種新的權(quán)限機(jī)制首有。用戶(hù)可以在...
    宇是我閱讀 7,427評(píng)論 7 41
  • 唐三大手一揮,道:“起來(lái)吧间唉。”此時(shí)的他利术,一臉微笑呈野,藍(lán)色長(zhǎng)發(fā)飄逸,那俊逸的模樣印叁,動(dòng)人心魄被冒。 看著他那和煦的笑容,戴雨...
    和煦晴天閱讀 4,279評(píng)論 0 0
  • 文/左心 4月1日正午 假寐中被 人在江湖漂呀 咋能不挨刀呀… 驚醒 手按接聽(tīng)鍵 爸爸快點(diǎn)回來(lái) 給我買(mǎi)...
    5b8fd3f74fc5閱讀 342評(píng)論 0 0