Permission——郭霖認為最優(yōu)的運行時權限方案

Android6.0發(fā)布這么久贝润,對運行時權限也看了很多資料绊茧,對比過幾個流行的庫。但是個人還是喜歡在項目里用自己動手封裝的東西打掘,哪怕照抄也好华畏。。尊蚁。不知道是什么原因亡笑。

前天無意聽郭神的直播。講解的是運行時權限的封裝横朋,收益頗多仑乌。依樣畫葫蘆,記錄下來琴锭,沒看直播的同學也可以看看(郭神的第二行代碼已經當工具書了晰甚,每次翻開看到郭神的簽名,都覺得真的是字如其人决帖。厕九。。)

前陣子封裝個基類庫地回,快捷開發(fā)可以直接用扁远,運行時權限正好整合進去腺阳。開始:

Permission,運行時權限

授權權限
*如果設備運行的是Android 6(API Level 23)或更高,和應用程序的targetSdkVersion是23或更高穿香,應用程序要求的權限由用戶在運行時亭引。用戶可以在任何時間撤銷權限,所以在每次運行時應用程序需要檢查是否有權限皮获。
如果設備運行的是Android 5.1(API Level 22)或更低焙蚓,或應用程序targetSdkVersion等于或低于22時,當用戶安裝的應用程序洒宝,系統會要求用戶授予權限购公。用戶的應用程序更新,如果你添加一個新的權限的應用程序的更新版本雁歌,系統會要求用戶授予權限時宏浩。一旦用戶安裝該應用程序,他們可以撤銷許可的唯一途徑是通過卸載應用程序靠瞎。

拒絕權限
*每當一個權限被拒絕應向用戶解釋使用該權限的具體用途比庄,保證功能要求的權限總是行為為目的,應用程序應該說是需要許可乏盐,允許它提供了一種方法佳窑。而權限被拒絕的途徑以下兩種:

由用戶拒絕權限請求
用戶選擇過“不要再問”,用戶權限是默默的否認父能,沒有警告

封裝

申請權限后腰毀掉給當前activity神凑,所以先定義一個回掉接口PermissionListener
public interface PermissionListener { //授權成功 void onGranted(); //授權部分 void onGranted(List<String> grantedPermission); //拒絕授權 void onDenied(List<String> deniedPermission); }
在BaseActivity里寫授權申請,首先檢查申請的權限是不是被授權了,如果不是就加入待授權數組里何吝,去申請權限溉委。如果全部已授權,就直接回掉授權成功爱榕。

/** 權限申請
 * @param permissions
 * @param listener
 */
protected void requestRunTimePermission(String[] permissions, PermissionListener listener) {

    //todo 獲取棧頂activity瓣喊,如果null。return呆细;

    this.mPermissionListener = listener;

    List<String> permissionList = new ArrayList<>();
    for (String permission : permissions) {
        if(ContextCompat.checkSelfPermission(this,permission)!= PackageManager.PERMISSION_GRANTED){
            permissionList.add(permission);
        }
    }
    if(!permissionList.isEmpty()){
        ActivityCompat.requestPermissions(this,permissionList.toArray(new String[permissionList.size()]),1);
    }else{
        listener.onGranted();
    }
}

然后重寫授權返回方法型宝。系統會返回2個數組, String[] permissions是你申請的權限絮爷,int[] grantResults是授權結果。拿出授權結果比對梨树,如果授權坑夯,加入授權數組,如果拒絕抡四,加入拒絕數組柜蜈≌套唬回掉給注冊PermissionListener的activity

/** 申請結果
 * @param requestCode
 * @param permissions
 * @param grantResults
 */
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    switch (requestCode){
        case 1:
            if (grantResults.length>0){
                List<String> deniedPermissions = new ArrayList<>();
                List<String> grantedPermissions = new ArrayList<>();
                for (int i = 0; i < grantResults.length; i++) {
                    int grantResult = grantResults[i];
                    if (grantResult != PackageManager.PERMISSION_GRANTED){
                        String permission = permissions[i];
                        deniedPermissions.add(permission);
                    }else{
                        String permission = permissions[i];
                        grantedPermissions.add(permission);
                    }
                }

                if (deniedPermissions.isEmpty()){
                    mPermissionListener.onGranted();
                }else{
                    mPermissionListener.onDenied(deniedPermissions);
                    mPermissionListener.onGranted(grantedPermissions);
                }
            }
            break;
    }
}

然后你的實現了BaseActivity的activity實現PermissionListener,需要申請權限的地方調用requestRunTimePermission(permissions淑履,this);在回掉方法里根據結果實現邏輯隶垮。

附:
權限可以分為危險權限和正常權限,還有特殊權限秘噪、自定義權限狸吞。
正常權限(PROTECTION_NORMAL)對用戶的隱私或安全沒有大的風險的權限在AndroidManifest.xml聲明里,如果應用需要一個正常的權限指煎,在安裝的時候系統自動授予該權限蹋偏。在
使用的時候系統不提示用戶,用戶也不能撤銷這些權限至壤。

![](http://upload-images.jianshu.io/upload_images/1454742-92054a8649e9511f.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

危險權限威始,需要使用時要檢查有沒有授權。如果沒有就彈個對話框詢問用戶授權像街。這類權限被分組了黎棠,同一組的任何一個權限被授權了,其他權限也自動被授權镰绎。如下表:

比如你需要android.permission.READ_CONTACTS 葫掉,去讀聯系人。這個權限被用戶授權跟狱,然后你用到寫入通訊錄權限permission:android.permission.WRITE_CONTACTS和permission:android.permission.GET_ACCOUNTS 時俭厚,就是授權過的,去申請就不會彈框驶臊。

don't worry be happy

傳送門,在core的baseactivity里

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末挪挤,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子关翎,更是在濱河造成了極大的恐慌扛门,老刑警劉巖,帶你破解...
    沈念sama閱讀 210,978評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件纵寝,死亡現場離奇詭異论寨,居然都是意外死亡,警方通過查閱死者的電腦和手機爽茴,發(fā)現死者居然都...
    沈念sama閱讀 89,954評論 2 384
  • 文/潘曉璐 我一進店門葬凳,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人室奏,你說我怎么就攤上這事火焰。” “怎么了胧沫?”我有些...
    開封第一講書人閱讀 156,623評論 0 345
  • 文/不壞的土叔 我叫張陵昌简,是天一觀的道長占业。 經常有香客問我,道長纯赎,這世上最難降的妖魔是什么谦疾? 我笑而不...
    開封第一講書人閱讀 56,324評論 1 282
  • 正文 為了忘掉前任,我火速辦了婚禮犬金,結果婚禮上念恍,老公的妹妹穿的比我還像新娘。我一直安慰自己佑附,他們只是感情好樊诺,可當我...
    茶點故事閱讀 65,390評論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著音同,像睡著了一般词爬。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上权均,一...
    開封第一講書人閱讀 49,741評論 1 289
  • 那天顿膨,我揣著相機與錄音,去河邊找鬼叽赊。 笑死恋沃,一個胖子當著我的面吹牛,可吹牛的內容都是我干的必指。 我是一名探鬼主播囊咏,決...
    沈念sama閱讀 38,892評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼塔橡!你這毒婦竟也來了梅割?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 37,655評論 0 266
  • 序言:老撾萬榮一對情侶失蹤葛家,失蹤者是張志新(化名)和其女友劉穎户辞,沒想到半個月后,有當地人在樹林里發(fā)現了一具尸體癞谒,經...
    沈念sama閱讀 44,104評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡底燎,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,451評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現自己被綠了弹砚。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片双仍。...
    茶點故事閱讀 38,569評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖迅栅,靈堂內的尸體忽然破棺而出殊校,到底是詐尸還是另有隱情,我是刑警寧澤读存,帶...
    沈念sama閱讀 34,254評論 4 328
  • 正文 年R本政府宣布为流,位于F島的核電站,受9級特大地震影響让簿,放射性物質發(fā)生泄漏敬察。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,834評論 3 312
  • 文/蒙蒙 一尔当、第九天 我趴在偏房一處隱蔽的房頂上張望莲祸。 院中可真熱鬧,春花似錦椭迎、人聲如沸锐帜。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,725評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽缴阎。三九已至,卻和暖如春简软,著一層夾襖步出監(jiān)牢的瞬間蛮拔,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,950評論 1 264
  • 我被黑心中介騙來泰國打工痹升, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留建炫,地道東北人。 一個月前我還...
    沈念sama閱讀 46,260評論 2 360
  • 正文 我出身青樓疼蛾,卻偏偏與公主長得像肛跌,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子察郁,可洞房花燭夜當晚...
    茶點故事閱讀 43,446評論 2 348

推薦閱讀更多精彩內容