關(guān)于android6.0的權(quán)限申請

谷歌在android6.0的權(quán)限管理方面做了不少的改動,android6.0以前的話需要什么權(quán)限只需要在AndroidManifest文件中進(jìn)行申請就可以了效扫,android6.0以后的話將權(quán)限分為兩類;一類是Normal Permissions昏兆,這類權(quán)限一般不涉及用戶隱私有梆,是不需要用戶進(jìn)行授權(quán)的,比如手機(jī)震動瞒御、訪問網(wǎng)絡(luò)等;另一類是Dangerous Permission神郊,一般是涉及到用戶隱私的肴裙,需要用戶進(jìn)行授權(quán)趾唱,比如讀取sdcard、訪問通訊錄等蜻懦;對于Normal Permissions的話還是跟之前一樣的做法甜癞,Dangerous Permission的話不僅需要在AndroidManifest中注冊,還需要動態(tài)申請宛乃;下面這些的就是Dangerous Permission:

group:permission-group.CONTACTS 
permission:permission.WRITE_CONTACTS 
permission:android.permission.GET_ACCOUNTS 
permission:android.permission.READ_CONTACTS

group:android.permission-group.PHONE 
permission:android.permission.READ_CALL_LOG 
permission:android.permission.READ_PHONE_STATE 
permission:android.permission.CALL_PHONE 
permission:android.permission.WRITE_CALL_LOG 
permission:android.permission.USE_SIP 
permission:android.permission.PROCESS_OUTGOING_CALLS 
permission:com.android.voicemail.permission.ADD_VOICEMAIL

group:android.permission-group.CALENDAR 
permission:android.permission.READ_CALENDAR 
permission:android.permission.WRITE_CALENDAR

group:android.permission-group.CAMERA 
permission:android.permission.CAMERA

group:android.permission-group.SENSORS 
permission:android.permission.BODY_SENSORS

group:android.permission-group.LOCATION 
permission:android.permission.ACCESS_FINE_LOCATION 
permission:android.permission.ACCESS_COARSE_LOCATION

group:android.permission-group.STORAGE 
permission:android.permission.READ_EXTERNAL_STORAGE 
permission:android.permission.WRITE_EXTERNAL_STORAGE

group:android.permission-group.MICROPHONE 
permission:android.permission.RECORD_AUDIO

group:android.permission-group.SMS 
permission:android.permission.READ_SMS 
permission:android.permission.RECEIVE_WAP_PUSH 
permission:android.permission.RECEIVE_MMS 
permission:android.permission.RECEIVE_SMS 
permission:android.permission.SEND_SMS 
permission:android.permission.READ_CELL_BROADCASTS 

對于這些權(quán)限在使用的時(shí)候就需要注意悠咱,要記得動態(tài)去申請?zhí)砑訖?quán)限;這里也講下本人的一個大致思路:

1:判斷當(dāng)前的版本是否在android6.0及以上征炼,如果不是就直接AndroidManifest中申請乔煞,
2:android6.0及以上的話,判斷用戶是否賦予該權(quán)限柒室,如果賦予該權(quán)限渡贾,就運(yùn)行進(jìn)行相應(yīng)的操作,
3:6.0及以上同時(shí)沒有賦予該權(quán)限雄右,就動態(tài)的申請并提示用戶賦予該權(quán)限空骚,,如果賦予該權(quán)限擂仍,就運(yùn)行進(jìn)行相應(yīng)的操作囤屹,如果用戶拒絕,就提示用戶拒絕該權(quán)限的賦予逢渔,同時(shí)不允許用戶進(jìn)行相應(yīng)操作肋坚,如果用戶繼續(xù)操作,還是提示用戶要賦予該權(quán)限肃廓;

其實(shí)在http://blog.csdn.net/wangwo1991/article/details/54666737;
這篇博客中已經(jīng)講過6.0權(quán)限的處理智厌,不過這是另外一種思路處理,這里要講的是通過反射和注解的方式處理6.0的權(quán)限盲赊;反射和注解的話在IOC注解里面已經(jīng)講到過了铣鹏;就直接寫成功和失敗的注解了;

成功的注解:

@Target(ElementType.METHOD)//ElementType.METHOD方法上面  Target代表放在什么位置
@Retention(RetentionPolicy.RUNTIME)//是編譯時(shí)檢測還是運(yùn)行時(shí)檢測  Retention代表什么時(shí)候去檢測
public @interface PermissionSuccess {
    public int requestCode();//請求碼
}

失敗的注解:

@Target(ElementType.METHOD)//ElementType.METHOD方法上面  Target代表放在什么位置
@Retention(RetentionPolicy.RUNTIME)//是編譯時(shí)檢測還是運(yùn)行時(shí)檢測  Retention代表什么時(shí)候去檢測
public @interface PermissionFail {
    public int requestCode();//請求碼
}

首先判斷當(dāng)前系統(tǒng)的版本哀蘑;

/**
     * 判斷其是不是6.0以上的版本
     * @return
     */
    public static boolean isOverMarshmallow(){
        return Build.VERSION.SDK_INT>=Build.VERSION_CODES.M;
    }

根據(jù)系統(tǒng)的版本去執(zhí)行權(quán)限的申請或者相應(yīng)的操作诚卸;

      //首先判斷當(dāng)前的版本是不是6.0和6.0以上
        if (!PermissionUtils.isOverMarshmallow()) {
            //如果不是6.0以上,  反射獲取執(zhí)行方法
            PermissionUtils.executeSuccess(mObject,mRequestCode);
            return;
        }
        //如果是6.0以上那么首先需要判斷是否授予權(quán)限
        List<String> deniedPermission=PermissionUtils.getDeniedPermission(mObject,mPermisson);
        //如果授予了 反射獲取執(zhí)行方法
        if(deniedPermission.size()==0){
            //全部都是授予過權(quán)限的
            PermissionUtils.executeSuccess(mObject,mRequestCode);
        }else{
            //如果沒有授予 那么我們就申請
            ActivityCompat.requestPermissions(PermissionUtils.getActivity(mObject),
                    deniedPermission.toArray(new String[deniedPermission.size()]),
                    mRequestCode);
        }

如果是6.0及以上并沒有授予權(quán)限绘迁,就需要去動態(tài)申請合溺,谷歌提供了

ActivityCompat.requestPermissions(PermissionUtils.getActivity(mObject),
                    deniedPermission.toArray(new String[deniedPermission.size()]),
                    mRequestCode);

方法可以去申請權(quán)限,當(dāng)然了肯定還要去處理申請后的回調(diào)缀台;

  public static void requestPermissionsResult(Object mObject,int requestCode, String[] permissions, int[] grantResults) {
        //再次獲取是否授予的權(quán)限
        List<String> deniedPermission=PermissionUtils.getDeniedPermission(mObject,permissions);
        if(deniedPermission.size()==0){
            //這些權(quán)限全部同一
            PermissionUtils.executeSuccess(mObject,requestCode);
        }else{
            //申請中權(quán)限中有用戶不同意的
            PermissionUtils.executeFailMethod(mObject,requestCode);
        }
    }

申請的過程以及成功或者失敗都是通過反射來執(zhí)行和實(shí)現(xiàn)棠赛;如果是成功的話,通過invoke();方法去執(zhí)行相應(yīng)的操作;

  public static void executeSuccess(Object mOhject, int requestCode) {
        //獲取class中所有的方法
        Method[] methods = mOhject.getClass().getDeclaredMethods();
        for(Method method:methods){
            System.out.println("--------"+method);
            //獲取該方法上有沒有打這個成功的標(biāo)記
            PermissionSuccess successMethod = method.getAnnotation(PermissionSuccess.class);
            if(successMethod!=null){
                //代表該方法打了標(biāo)記
                //遍歷找到打了標(biāo)記的方法并且我們的請求碼要一致
                int methodCode = successMethod.requestCode();
                if(methodCode==requestCode){
                    //這個就是我們要找的成功的方法
                    //反射執(zhí)行該方法
                    executeMethod(mOhject,method);
                }
            }
        }
    }

通過反射獲取該類中所有的方法恭朗,根據(jù)傳入的requestCode和方法注解中的methodCode對比,如果一致的話依疼,就調(diào)用executeMethod();去執(zhí)行痰腮;

  private static void executeMethod(Object mOhject,Method method) {
        //反射執(zhí)行方法  第一個參數(shù)是該方法是屬于哪個類  第二個參數(shù)是傳參數(shù)
        try {
            method.setAccessible(true);//運(yùn)行執(zhí)行私有方法
            method.invoke(mOhject,new Object[]{});//反射執(zhí)行方法
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
    }

獲取失敗的處理和執(zhí)行也是一樣的;

    /**
     * 執(zhí)行失敗的方法
     * @param mObject
     * @param requestCode
     */
    public static void executeFailMethod(Object mObject, int requestCode) {
        //獲取class中所有的方法
        Method[] methods = mObject.getClass().getDeclaredMethods();
        for(Method method:methods){
            System.out.println("--------"+method);
            //獲取該方法上有沒有打這個失敗的標(biāo)記
            PermissionFail failMethod = method.getAnnotation(PermissionFail.class);
            if(failMethod!=null){
                //代表該方法打了標(biāo)記
                //遍歷找到打了標(biāo)記的方法并且我們的請求碼要一致
                int methodCode = failMethod.requestCode();
                if(methodCode==requestCode){
                    //這個就是我們要找的成功的方法
                    //反射執(zhí)行該方法
                    executeMethod(mObject,method);
                }
            }
        }
    }

這里提供了Activity律罢、Fragment以及FragmentActivity的使用膀值,調(diào)用下面這些方法進(jìn)行請求碼和需要申請的權(quán)限;

  //傳請求碼
    public PermissionHelper requestCode(int requestCode) {
        this.mRequestCode = requestCode;
        return this;
    }

    //傳請求權(quán)限
    public PermissionHelper requestPermission(String... permisson) {
        this.mPermisson = permisson;
        return this;
    }

使用的時(shí)候肯定是要先進(jìn)行權(quán)限的申請误辑;

PermissionHelper.with(MainActivity.this).
                        requestPermission(new String[]{Manifest.permission.CALL_PHONE}).
                        requestCode(CALL_PHONE_REQUEST_DODE).
                        request();
@PermissionSuccess(requestCode =CALL_PHONE_REQUEST_DODE)
    private void callPhone(){
        Intent intent=new Intent(Intent.ACTION_CALL);
        Uri data=Uri.parse("tel:"+"15889548152");
        intent.setData(data);
        startActivity(intent);
    }

這里是成功要執(zhí)行的相應(yīng)操作沧踏;如果需要對失敗也進(jìn)行相應(yīng)提示的話,寫一個失敗的方法就可以了巾钉,也可以不處理翘狱;

@PermissionFail(requestCode =CALL_PHONE_REQUEST_DODE)
    private void callPhoneFail(){
        Toast.makeText(this, "你拒絕了撥打電話", Toast.LENGTH_SHORT).show();
    }

下面這個的話是申請結(jié)果的一個回調(diào);

  @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        PermissionHelper.requestPermissionsResult(this,requestCode,permissions,grantResults);
    }

這樣就ok了砰苍,使用起來還是蠻簡單的潦匈,效果如下:

GIF.gif

源碼地址:http://pan.baidu.com/s/1sldiMx3

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市赚导,隨后出現(xiàn)的幾起案子茬缩,更是在濱河造成了極大的恐慌,老刑警劉巖吼旧,帶你破解...
    沈念sama閱讀 211,194評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件凰锡,死亡現(xiàn)場離奇詭異,居然都是意外死亡圈暗,警方通過查閱死者的電腦和手機(jī)掂为,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,058評論 2 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來员串,“玉大人菩掏,你說我怎么就攤上這事£羌茫” “怎么了智绸?”我有些...
    開封第一講書人閱讀 156,780評論 0 346
  • 文/不壞的土叔 我叫張陵,是天一觀的道長访忿。 經(jīng)常有香客問我瞧栗,道長,這世上最難降的妖魔是什么海铆? 我笑而不...
    開封第一講書人閱讀 56,388評論 1 283
  • 正文 為了忘掉前任迹恐,我火速辦了婚禮,結(jié)果婚禮上卧斟,老公的妹妹穿的比我還像新娘殴边。我一直安慰自己憎茂,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,430評論 5 384
  • 文/花漫 我一把揭開白布锤岸。 她就那樣靜靜地躺著竖幔,像睡著了一般。 火紅的嫁衣襯著肌膚如雪是偷。 梳的紋絲不亂的頭發(fā)上拳氢,一...
    開封第一講書人閱讀 49,764評論 1 290
  • 那天,我揣著相機(jī)與錄音蛋铆,去河邊找鬼馋评。 笑死,一個胖子當(dāng)著我的面吹牛刺啦,可吹牛的內(nèi)容都是我干的留特。 我是一名探鬼主播,決...
    沈念sama閱讀 38,907評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼玛瘸,長吁一口氣:“原來是場噩夢啊……” “哼磕秤!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起捧韵,我...
    開封第一講書人閱讀 37,679評論 0 266
  • 序言:老撾萬榮一對情侶失蹤市咆,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后再来,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體蒙兰,經(jīng)...
    沈念sama閱讀 44,122評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,459評論 2 325
  • 正文 我和宋清朗相戀三年芒篷,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了搜变。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,605評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡针炉,死狀恐怖挠他,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情篡帕,我是刑警寧澤殖侵,帶...
    沈念sama閱讀 34,270評論 4 329
  • 正文 年R本政府宣布,位于F島的核電站镰烧,受9級特大地震影響拢军,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜怔鳖,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,867評論 3 312
  • 文/蒙蒙 一茉唉、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦度陆、人聲如沸艾凯。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,734評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽趾诗。三九已至,卻和暖如春鸿竖,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背铸敏。 一陣腳步聲響...
    開封第一講書人閱讀 31,961評論 1 265
  • 我被黑心中介騙來泰國打工缚忧, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人杈笔。 一個月前我還...
    沈念sama閱讀 46,297評論 2 360
  • 正文 我出身青樓闪水,卻偏偏與公主長得像,于是被迫代替她去往敵國和親蒙具。 傳聞我的和親對象是個殘疾皇子球榆,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,472評論 2 348

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