Android6.0動態(tài)權(quán)限框架

翻了翻簡書的文章動態(tài),已經(jīng)快有小兩年沒有寫過文章了钱烟,時間過的可真快晰筛,轉(zhuǎn)眼嫡丙,18年又要過去了。

image.png

正好最近項目也在做targetSdkVersion升級到28读第,之前對6.0略微了解點(diǎn)曙博,個人感覺,動態(tài)權(quán)限的使用這里不太友好怜瞒,需要在Activity 或者 Fragment 中重寫onRequestPermissionsResult 方法父泳,然后處理個個權(quán)限的申請結(jié)果,耦合性很高吴汪,于是惠窄,就寫了一個輕量級的權(quán)限申請框架,在這篇文章中分為3個步驟為大家講解漾橙。

  • 1.權(quán)限的基本知識
  • 2.介紹一下框架的使用
  • 3.這個權(quán)限框架是怎么實(shí)現(xiàn)的

一杆融、權(quán)限的基本知識

google 從M版本(Android6.0,TargetSdkVersion 23)開始引入的動態(tài)權(quán)限,所以要想使用動態(tài)授權(quán)霜运,請保證TargetSdkVersion 大于等于23脾歇。

Google Android 6.0適配文檔

之前TargetSdkVersion 小于23 時,app不需要動態(tài)授權(quán)淘捡,我們可以默默的搞事情藕各,甚至在8.0的手機(jī)上也是默認(rèn)授予權(quán)限的,現(xiàn)在GooglePlay 強(qiáng)制要求TargetSdkVersion 大于等于26案淋,國內(nèi)的應(yīng)用市場明年也要開始效仿google,如果達(dá)不到規(guī)定的版本座韵,app是不允許上架的。所以TargetSdkVersion升級踢京,是早晚的事誉碴。

  • 特此說明一點(diǎn):國外6.0以下的手機(jī)是沒有權(quán)限設(shè)置頁面的,只是國內(nèi)的廠商自作聰明6.0以下加入了權(quán)限設(shè)置頁面瓣距,而且加入就加入吧黔帕,搞的他們自身都是bug,導(dǎo)致我們使用正常的api去檢測國內(nèi)廠商6.0以下手機(jī)時,檢測的都是錯誤的結(jié)果蹈丸,所以6.0以下手機(jī)請通過成黄,try catch 去捕獲異常,然后做特殊處理逻杖。
  • 權(quán)限檢查
PermissionChecker.checkSelfPermission(activity, permission) == PackageManager.PERMISSION_GRANTED

這里用PermissionChecker檢查是否授予了某項權(quán)限奋岁,兼容性更好一點(diǎn)


  • 申請權(quán)限
requestPermissions(permissions, REQUEST_CODE);

permissions 是一個數(shù)組,可以申請多個權(quán)限荸百,REQUEST_CODE 為請求碼用于在onRequestPermissionsResult中處理結(jié)果


  • 處理權(quán)限
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
 //處理對應(yīng)的權(quán)限結(jié)果
}

基本概念已經(jīng)介紹完了闻伶,動態(tài)權(quán)限中使用到的就是這三個方法


那么都什么權(quán)限需要我們?nèi)ド暾埬兀?/strong>

當(dāng)然是涉及到用戶隱私的權(quán)限了,在google文檔中叫做危險權(quán)限 (Dangerous permissions and permission groups)這里又涉及到了一個權(quán)限組的概念够话,我們就拿 sdcard 為例簡單說一下蓝翰,READ_EXTERNAL_STORAGEWRITE_EXTERNAL_STORAGE (讀寫sdcard)權(quán)限同屬于STORAGE的權(quán)限組光绕,只要申請了其中一個權(quán)限,另一個就不必再申請了畜份,系統(tǒng)會默認(rèn)授予這個權(quán)限組的所有權(quán)限诞帐。

下面列出所有的危險權(quán)限與權(quán)限組

image.png

二、框架的使用

  • app下 build.gradle中
dependencies {
compile 'com.mj:dynamicpermission:1.0.0'
}
  • 或者直接下載源碼 copy 三個類到項目中就可以爆雹,文章末尾會給出下載地址


    image.png
DynamicPermissionEmitter permissionEmitter = new DynamicPermissionEmitter(this);

permissionEmitter.emitterPermission(new DynamicPermissionEmitter.ApplyPermissionsCallback() {

            @Override
            public void applyPermissionResult(Map<String, DynamicPermissionEntity> permissionEntityMap) {
                DynamicPermissionEntity permissionEntity = permissionEntityMap.get(permissionName);
                if (permissionEntity.isGranted()) {
                    //權(quán)限允許停蕉,可以搞事情了
                } else if (permissionEntity.shouldShowRequestPermissionRational()) {
                    //勾選不在提示,且點(diǎn)擊了拒絕顶别,在這里給用戶提示權(quán)限的重要性谷徙,給一個友好的提示
                } else {
                    //拒絕了權(quán)限,不能亂搞
                }
            }
        }, permissionName);

this 指:FragmentActivity 或 v4包下的 Fragment,為什么需要這個參數(shù)驯绎,后面講解實(shí)現(xiàn)的時候會做說明

通過permissionEmitter發(fā)射權(quán)限,
@params1 傳入一個處理權(quán)限結(jié)果的回調(diào)
@params2 傳入需要申請的權(quán)限名稱谋旦,可以以數(shù)組的形式將權(quán)限名稱傳入剩失,支持多個權(quán)限

至此權(quán)限的使用就介紹完了,使用起來還是比較簡單的册着,而且已經(jīng)應(yīng)用到幾百萬日活的app中


三拴孤、如何實(shí)現(xiàn)的?

  • 先貼一段DynamicPermissionEmitter 構(gòu)造方法大家就知道怎么回事了
/**
     * 構(gòu)造方法
     *
     * @param activity fragmentActivity
     */
    public DynamicPermissionEmitter(@NonNull FragmentActivity activity) {
        try {
            generateApplyPermissionFragment(activity.getSupportFragmentManager());

        } catch (Exception e) {
            handleFragmentException(activity, e);
        }
    }

    /**
     * 構(gòu)造方法
     *
     * @param fragment v4 包下的 fragment
     */
    @SuppressLint("LongLogTag")
    public DynamicPermissionEmitter(@NonNull Fragment fragment) {
        try {
            generateApplyPermissionFragment(fragment.getChildFragmentManager());
        } catch (Exception e) {
            Log.e(TAG, "DynamicPermissionEmitter fragment", e);
        }
    }


    /**
     *
     * @param activity fragment
     * @param e        exception
     */
    @SuppressLint("LongLogTag")
    private void handleFragmentException(@NonNull FragmentActivity activity, Exception e) {
        FragmentManager supportFragmentManager = activity.getSupportFragmentManager();
        if (supportFragmentManager != null) {
            List<Fragment> fragments = supportFragmentManager.getFragments();
            if (fragments != null) {
                for (int i = 0; i < fragments.size(); i++) {
                    Fragment fragment = fragments.get(i);
                    if (TAG.equals(fragment.getTag())) {
                        continue;
                    }
                    try {
                        generateApplyPermissionFragment(fragment.getChildFragmentManager());
                    } catch (Exception e1) {
                        Log.e(TAG, "DynamicPermissionEmitter activity", e);
                    }
                    break;
                }
            }
        }
    }

    /**
     * 生成申請權(quán)限的fragment
     *
     * @param fragmentManager fragmentManager
     */
    private void generateApplyPermissionFragment(@NonNull FragmentManager fragmentManager) throws Exception {
        this.fragmentManager = fragmentManager;
        Fragment mFragment = fragmentManager.findFragmentByTag(DYNAMIC_PERMISSION_FRAGMENT_TAG);
        // 保證一個activity 或 fragment 只添加一個permission fragment
        if (mFragment != null) {
            dynamicPermissionFragment = (DynamicPermissionFragment) mFragment;
        } else {
            dynamicPermissionFragment = DynamicPermissionFragment.newInstance();
            fragmentManager
                    .beginTransaction()
                    .add(dynamicPermissionFragment, DYNAMIC_PERMISSION_FRAGMENT_TAG)
                    .commitNow();
        }
    }
  • 從上面代碼可以看出所有構(gòu)造方法都調(diào)用了generateApplyPermissionFragment方法甲捏,這個方法中生成了一個 與用戶無任何交互的Fragment 也就是用戶看不見的Fragment,我們的所有權(quán)限申請演熟、檢查、結(jié)果處理都是在這個Fragment中司顿。

  • 這也能解釋出為什么使用的時候需要傳入FragmentActivity 或者 Fragment 芒粹,因為我們需要FragmentManager來加入一個看不見的Fragment 。

  • 至此大家應(yīng)該了解了這個權(quán)限申請到底是怎么回事了大溜,DynamicPermissionFragment的代碼我就不貼出來了化漆,有興趣的可以下載源碼,去看钦奋,里邊就是用到了最基本的權(quán)限申請座云、權(quán)限檢查、onRequestPermissionsResult 處理結(jié)果付材,最后通過回調(diào)的形式返回的

歡迎star,或者大家有什么想法或問題朦拖,隨時聯(lián)系我,我們一起讓它變的更加強(qiáng)大

image.png

github下載地址

csdn下載地址

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末厌衔,一起剝皮案震驚了整個濱河市璧帝,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌葵诈,老刑警劉巖裸弦,帶你破解...
    沈念sama閱讀 211,290評論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件祟同,死亡現(xiàn)場離奇詭異,居然都是意外死亡理疙,警方通過查閱死者的電腦和手機(jī)晕城,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,107評論 2 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來窖贤,“玉大人砖顷,你說我怎么就攤上這事≡呶啵” “怎么了滤蝠?”我有些...
    開封第一講書人閱讀 156,872評論 0 347
  • 文/不壞的土叔 我叫張陵,是天一觀的道長授嘀。 經(jīng)常有香客問我物咳,道長,這世上最難降的妖魔是什么蹄皱? 我笑而不...
    開封第一講書人閱讀 56,415評論 1 283
  • 正文 為了忘掉前任览闰,我火速辦了婚禮,結(jié)果婚禮上巷折,老公的妹妹穿的比我還像新娘压鉴。我一直安慰自己,他們只是感情好锻拘,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,453評論 6 385
  • 文/花漫 我一把揭開白布油吭。 她就那樣靜靜地躺著,像睡著了一般署拟。 火紅的嫁衣襯著肌膚如雪婉宰。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,784評論 1 290
  • 那天芯丧,我揣著相機(jī)與錄音芍阎,去河邊找鬼。 笑死缨恒,一個胖子當(dāng)著我的面吹牛谴咸,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播骗露,決...
    沈念sama閱讀 38,927評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼岭佳,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了萧锉?” 一聲冷哼從身側(cè)響起珊随,我...
    開封第一講書人閱讀 37,691評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后叶洞,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體鲫凶,經(jīng)...
    沈念sama閱讀 44,137評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,472評論 2 326
  • 正文 我和宋清朗相戀三年衩辟,在試婚紗的時候發(fā)現(xiàn)自己被綠了螟炫。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,622評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡艺晴,死狀恐怖昼钻,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情封寞,我是刑警寧澤然评,帶...
    沈念sama閱讀 34,289評論 4 329
  • 正文 年R本政府宣布,位于F島的核電站狈究,受9級特大地震影響碗淌,放射性物質(zhì)發(fā)生泄漏谦炒。R本人自食惡果不足惜贯莺,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,887評論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦谜喊、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,741評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽锡足。三九已至,卻和暖如春珠插,著一層夾襖步出監(jiān)牢的瞬間缤底,已是汗流浹背徙歼。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評論 1 265
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留魄梯,地道東北人桨螺。 一個月前我還...
    沈念sama閱讀 46,316評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像酿秸,于是被迫代替她去往敵國和親灭翔。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,490評論 2 348

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