Android權(quán)限管理PermissionsDispatcher2.3.2使用+原生6.0權(quán)限使用

PermissionsDispatcher2.3.2使用

Android6.0權(quán)限官網(wǎng)
https://developer.android.com/about/versions/marshmallow/android-6.0-changes.html?hl=zh-cn
系統(tǒng)權(quán)限:
https://developer.android.com/training/permissions/index.html?hl=zh-cn
權(quán)限的最佳做法:
https://developer.android.com/training/permissions/best-practices.html?hl=zh-cn#testing
該庫的github地址
https://github.com/hotchemi/PermissionsDispatcher

權(quán)限

Gradle配置

使用PermissionsDispatcher官份,需要在project的 build.gradle中添加


(1)當(dāng)Studio的版本在2.2之上

在app module中的build.gradle中添加:

dependencies {
  compile 'com.github.hotchemi:permissionsdispatcher:${latest.version}'
  annotationProcessor 'com.github.hotchemi:permissionsdispatcher-processor:${latest.version}'
}

目前${latest.version}
最新的是2.3.2幅聘。


(2)當(dāng)Studio的版低于2.2

在工程目錄下build.gradle 文件中添加:

buildscript {  
  dependencies {  
    classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'  
  }  
}  

然后在app module中的build.gradle中添加:(必須在app module中添加)


apply plugin: 'android-apt'  
  
dependencies {  
  compile 'com.github.hotchemi:permissionsdispatcher:${latest.version}'  
  apt 'com.github.hotchemi:permissionsdispatcher-processor:${latest.version}'  
}  

用法:

1.注解

PermissionsDispatcher只介紹幾個(gè)注解,保持其通用API簡潔:

注:帶注釋的方法一定不能private。

注解 需要 描述
@RuntimePermissions ? 在Activity或者Fragment中需要添加,來處理權(quán)限的問題
@NeedsPermission ? 注釋其執(zhí)行需要一個(gè)或多個(gè)許可的作用的方法(當(dāng)用戶授予了權(quán)限之后,會(huì)調(diào)用使用此注解的方法)
@OnShowRationale 注釋這解釋了為什么需要許可/秒/方法。它通過在一個(gè)PermissionRequest可用于繼續(xù)或中止在用戶輸入的當(dāng)前的許可請求對象
@OnPermissionDenied 注釋這是調(diào)用的方法痕貌,如果用戶不授予的權(quán)限
@OnNeverAskAgain 注釋如果用戶選擇讓設(shè)備“不再詢問”有關(guān)許可被調(diào)用的方法

具體使用如下:


@RuntimePermissions
public class MainActivity extends AppCompatActivity {

    @NeedsPermission(Manifest.permission.CAMERA)
    void showCamera() {
        getSupportFragmentManager().beginTransaction()
                .replace(R.id.sample_content_fragment, CameraPreviewFragment.newInstance())
                .addToBackStack("camera")
                .commitAllowingStateLoss();
    }

    @OnShowRationale(Manifest.permission.CAMERA)
    void showRationaleForCamera(final PermissionRequest request) {
        new AlertDialog.Builder(this)
            .setMessage(R.string.permission_camera_rationale)
            .setPositiveButton(R.string.button_allow, (dialog, button) -> request.proceed())
            .setNegativeButton(R.string.button_deny, (dialog, button) -> request.cancel())
            .show();
    }

    @OnPermissionDenied(Manifest.permission.CAMERA)
    void showDeniedForCamera() {
        Toast.makeText(this, R.string.permission_camera_denied, Toast.LENGTH_SHORT).show();
    }

    @OnNeverAskAgain(Manifest.permission.CAMERA)
    void showNeverAskForCamera() {
        Toast.makeText(this, R.string.permission_camera_neverask, Toast.LENGTH_SHORT).show();
    }
}

2.自動(dòng)生成的類

Activity繼承了AppCompatActivity,是的糠排,如果使用PermissionsDispatcher進(jìn)行權(quán)限管理舵稠,那么Activity就要繼承AppCompatActivity。這就要使用到了兼容包里的類了入宦。同樣此時(shí)相應(yīng)Activity中使用的主題哺徊,也需要進(jìn)行修改,修改成相應(yīng)兼容包里的主題乾闰。
在編譯時(shí)唉工,PermissionsDispatcher產(chǎn)生的一類MainActivityPermissionsDispatcher([活動(dòng)名稱] + PermissionsDispatcher),您可以使用安全地訪問這些許可保護(hù)的方法汹忠。

MainActivityPermissionsDispatcher需要自己編譯才會(huì)有:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    findViewById(R.id.button_camera).setOnClickListener(v -> {
      // NOTE: delegate the permission handling to generated method
      MainActivityPermissionsDispatcher.showCameraWithCheck(this);
    });
    findViewById(R.id.button_contacts).setOnClickListener(v -> {
      // NOTE: delegate the permission handling to generated method
      MainActivityPermissionsDispatcher.showContactsWithCheck(this);
    });
}

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    // NOTE: delegate the permission handling to generated method
    MainActivityPermissionsDispatcher.onRequestPermissionsResult(this, requestCode, grantResults);
}

添加SDK支持版本的兩種方式:

  • 1淋硝、AndroidManifest
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="18" />
  • 2、在注解的時(shí)候添加sdk版本控制

@RuntimePermissions
public class MainActivity extends AppCompatActivity {

    @NeedsPermission(value = Manifest.permission.WRITE_EXTERNAL_STORAGE, maxSdkVersion = 18)
    void getStorage() {
        // ...
    }
    
}

使用步驟:

一宽菜、在Manifest中添加權(quán)限
  <uses-permission android:name="android.permission.CAMERA" />
二谣膳、在Activity中添加注解

@RuntimePermissions
public class MainActivity extends AppCompatActivity {


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ButterKnife.bind(this);
    }

    /**
     * 顯示相機(jī)權(quán)限
     */

    @NeedsPermission(Manifest.permission.CAMERA)
    void showCamera() {//處理當(dāng)用戶允許該權(quán)限時(shí)需要處理的方法
        getSupportFragmentManager().beginTransaction()
                .replace(R.id.sample_content_fragment, CameraPreviewFragment.newInstance())
                .addToBackStack("camera")
                .commitAllowingStateLoss();


    }


    @OnShowRationale(Manifest.permission.CAMERA)
    void showRationaleForCamera(final PermissionRequest request) {// 提示用戶權(quán)限使用的對話框
        new AlertDialog
                .Builder(this)
                .setMessage("是否打開權(quán)限")
                .setPositiveButton("允許", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        request.proceed();
                    }
                })
                .setNegativeButton("拒絕", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        request.cancel();
                    }
                })
                .show();
    }

    /**
     * 如果用戶拒絕該權(quán)限執(zhí)行的方法
     */
    @OnPermissionDenied(Manifest.permission.CAMERA)
    void showDeniedForCamera() {
        Toast.makeText(this, "獲取權(quán)限失敗", Toast.LENGTH_SHORT).show();
    }

    @OnNeverAskAgain(Manifest.permission.CAMERA)
    void showNeverAskForCamera() {
        Toast.makeText(this, "再次獲取權(quán)限", Toast.LENGTH_SHORT).show();
    }
三、重寫回調(diào)方法铅乡,并且使用MainActivityPermissionsDispatcher(此方法編譯生成【Activity】+PermissionsDispatcher)
  /**
     * 權(quán)限請求回調(diào)继谚,提示用戶之后,用戶點(diǎn)擊“允許”或者“拒絕”之后調(diào)用此方法
     *
     * @param requestCode  定義的權(quán)限編碼
     * @param permissions  權(quán)限名稱
     * @param grantResults 允許/拒絕
     */
    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        MainActivityPermissionsDispatcher.onRequestPermissionsResult(this, requestCode, grantResults);
    }


    @OnClick({R.id.button_camera, R.id.button_contacts})
    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.button_camera:
//                show(this, "相機(jī)");
//                默認(rèn)是沒有此類的阵幸,需要編譯下才會(huì)有此類
                MainActivityPermissionsDispatcher.showCameraWithCheck(this);

                break;
       
        }
    }

注意

  • 使用到的權(quán)限需要在Mnifest里面注冊
  • PermissionsDispatcher依賴于support-v4由默認(rèn)庫花履,以便能夠使用一些權(quán)限compat的類。
  • 需要添加support-v13庫一起PermissionsDispatcher在您的項(xiàng)目挚赊,它將使原生片段支持





原生6.0權(quán)限使用

Android 6.0 變更

另請參閱
Android 6.0 API 概覽

Android 6.0(API 級(jí)別 23)除了提供諸多新特性和功能外诡壁,還對系統(tǒng)和 API 行為做出了各種變更。
如果您之前發(fā)布過 Android 應(yīng)用荠割,請注意您的應(yīng)用可能受到這些平臺(tái)變更的影響妹卿。

運(yùn)行時(shí)權(quán)限

此版本引入了一種新的權(quán)限模式,如今蔑鹦,用戶可直接在運(yùn)行時(shí)管理應(yīng)用權(quán)限夺克。這種模式讓用戶能夠更好地了解和控制權(quán)限,同時(shí)為應(yīng)用開發(fā)者精簡了安裝和自動(dòng)更新過程嚎朽。用戶可為所安裝的各個(gè)應(yīng)用分別授予或撤銷權(quán)限铺纽。
對于以 Android 6.0(API 級(jí)別 23)或更高版本為目標(biāo)平臺(tái)的應(yīng)用,請務(wù)必在運(yùn)行時(shí)檢查和請求權(quán)限哟忍。要確定您的應(yīng)用是否已被授予權(quán)限狡门,請調(diào)用新增的 checkSelfPermission()
方法陷寝。要請求權(quán)限,請調(diào)用新增的 [requestPermissions()](https://developer.android.com/reference/android/app/Activity.html?hl=zh-cn#requestPermissions(java.lang.String[], int))
方法融撞。即使您的應(yīng)用并不以 Android 6.0(API 級(jí)別 23)為目標(biāo)平臺(tái),您也應(yīng)該在新權(quán)限模式下測試您的應(yīng)用粗蔚。

使用步驟

1尝偎、在AndroidManifest文件中添加需要的權(quán)限。

這個(gè)步驟和我們之前的開發(fā)并沒有什么變化鹏控,試圖去申請一個(gè)沒有聲明的權(quán)限可能會(huì)導(dǎo)致程序崩潰致扯。

2、檢查權(quán)限
if (ContextCompat.checkSelfPermission(this,
                Manifest.permission.READ_CONTACTS)
        != PackageManager.PERMISSION_GRANTED) {
}else{
    //
}

這里涉及到一個(gè)API当辐,ContextCompat.checkSelfPermission抖僵,主要用于檢測某個(gè)權(quán)限是否已經(jīng)被授予,方法返回值為PackageManager.PERMISSION_DENIED或者PackageManager.PERMISSION_GRANTED缘揪。當(dāng)返回DENIED就需要進(jìn)行申請授權(quán)了耍群。

3、申請授權(quán)
 ActivityCompat.requestPermissions(this,
                new String[]{Manifest.permission.READ_CONTACTS},
                MY_PERMISSIONS_REQUEST_READ_CONTACTS);

該方法是異步的找筝,第一個(gè)參數(shù)是Context蹈垢;第二個(gè)參數(shù)是需要申請的權(quán)限的字符串?dāng)?shù)組;第三個(gè)參數(shù)為requestCode袖裕,主要用于回調(diào)的時(shí)候檢測曹抬。可以從方法名requestPermissions以及第二個(gè)參數(shù)看出急鳄,是支持一次性申請多個(gè)權(quán)限的谤民,系統(tǒng)會(huì)通過對話框逐一詢問用戶是否授權(quán)。

4疾宏、處理權(quán)限申請回調(diào)
@Override
public void onRequestPermissionsResult(int requestCode,
        String permissions[], int[] grantResults) {
    switch (requestCode) {
        case MY_PERMISSIONS_REQUEST_READ_CONTACTS: {
            // If request is cancelled, the result arrays are empty.
            if (grantResults.length > 0
                && grantResults[0] == PackageManager.PERMISSION_GRANTED) {

                // permission was granted, yay! Do the
                // contacts-related task you need to do.

            } else {

                // permission denied, boo! Disable the
                // functionality that depends on this permission.
            }
            return;
        }
    }
}

首先驗(yàn)證requestCode定位到你的申請张足,然后驗(yàn)證grantResults對應(yīng)于申請的結(jié)果,這里的數(shù)組對應(yīng)于申請時(shí)的第二個(gè)權(quán)限字符串?dāng)?shù)組坎藐。如果你同時(shí)申請兩個(gè)權(quán)限兢榨,那么grantResults的length就為2,分別記錄你兩個(gè)權(quán)限的申請結(jié)果顺饮。如果申請成功吵聪,就可以做你的事情了~

具體使用詳見demo,GitHub:https://github.com/huangshuyuan/PermissionsDispatcherDemo

參考文檔:http://blog.csdn.net/lmj623565791/article/details/50709663

補(bǔ)充

現(xiàn)在網(wǎng)上不少關(guān)于權(quán)限的庫兼雄,可以直接用的吟逝,在GitHub上搜索即可
https://github.com/search?o=desc&q=android+permission&s=stars&type=Repositories&utf8=%E2%9C%93

github

有興趣可以研究一下其他的庫,已經(jīng)把根據(jù)星級(jí)排名前幾名的粘貼出來了
PermissionsDispatcher https://github.com/hotchemi/PermissionsDispatcher
RxPermissions https://github.com/tbruyelle/RxPermissions
easypermissions https://github.com/googlesamples/easypermissions
Dexter https://github.com/Karumi/Dexter
PermissionHelper https://github.com/k0shk0sh/PermissionHelper
AndPermission https://github.com/yanzhenjie/AndPermission

我的博客:http://blog.csdn.net/Imshuyuan/article/details/64919365

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末赦肋,一起剝皮案震驚了整個(gè)濱河市块攒,隨后出現(xiàn)的幾起案子励稳,更是在濱河造成了極大的恐慌,老刑警劉巖囱井,帶你破解...
    沈念sama閱讀 218,941評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件驹尼,死亡現(xiàn)場離奇詭異,居然都是意外死亡庞呕,警方通過查閱死者的電腦和手機(jī)新翎,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,397評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來住练,“玉大人地啰,你說我怎么就攤上這事〗补洌” “怎么了亏吝?”我有些...
    開封第一講書人閱讀 165,345評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長盏混。 經(jīng)常有香客問我蔚鸥,道長,這世上最難降的妖魔是什么许赃? 我笑而不...
    開封第一講書人閱讀 58,851評(píng)論 1 295
  • 正文 為了忘掉前任株茶,我火速辦了婚禮,結(jié)果婚禮上图焰,老公的妹妹穿的比我還像新娘启盛。我一直安慰自己,他們只是感情好技羔,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,868評(píng)論 6 392
  • 文/花漫 我一把揭開白布僵闯。 她就那樣靜靜地躺著,像睡著了一般藤滥。 火紅的嫁衣襯著肌膚如雪鳖粟。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,688評(píng)論 1 305
  • 那天拙绊,我揣著相機(jī)與錄音向图,去河邊找鬼。 笑死标沪,一個(gè)胖子當(dāng)著我的面吹牛榄攀,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播金句,決...
    沈念sama閱讀 40,414評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼檩赢,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了违寞?” 一聲冷哼從身側(cè)響起贞瞒,我...
    開封第一講書人閱讀 39,319評(píng)論 0 276
  • 序言:老撾萬榮一對情侶失蹤偶房,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后军浆,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體棕洋,經(jīng)...
    沈念sama閱讀 45,775評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,945評(píng)論 3 336
  • 正文 我和宋清朗相戀三年乒融,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了掰盘。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,096評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡簇抵,死狀恐怖庆杜,靈堂內(nèi)的尸體忽然破棺而出射众,到底是詐尸還是另有隱情碟摆,我是刑警寧澤,帶...
    沈念sama閱讀 35,789評(píng)論 5 346
  • 正文 年R本政府宣布叨橱,位于F島的核電站典蜕,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏罗洗。R本人自食惡果不足惜愉舔,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,437評(píng)論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望伙菜。 院中可真熱鬧轩缤,春花似錦、人聲如沸贩绕。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,993評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽淑倾。三九已至馏鹤,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間娇哆,已是汗流浹背湃累。 一陣腳步聲響...
    開封第一講書人閱讀 33,107評(píng)論 1 271
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留碍讨,地道東北人治力。 一個(gè)月前我還...
    沈念sama閱讀 48,308評(píng)論 3 372
  • 正文 我出身青樓,卻偏偏與公主長得像勃黍,于是被迫代替她去往敵國和親琴许。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,037評(píng)論 2 355

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

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,167評(píng)論 25 707
  • afinalAfinal是一個(gè)android的ioc溉躲,orm框架 https://github.com/yangf...
    passiontim閱讀 15,434評(píng)論 2 45
  • 焦慮榜田,本來狀態(tài)調(diào)整得挺好的了益兄,稍微有點(diǎn)動(dòng)力了,但是又被打亂了箭券。在家也覺得壓抑净捅。也沒有可以傾訴的人。工作壓力好大辩块』琢活...
    bud_and_bun閱讀 134評(píng)論 0 0
  • 文/牽著影子去流浪 迎風(fēng)于一片蛙鳴的月色里 傾聽你行走塵世的低語 恍如前塵往事的月華 涼涼里纏綿云雨 濯洗一簾幽夢...
    老影子閱讀 334評(píng)論 0 1
  • 昨晚半夜開始就不舒服,斷斷續(xù)續(xù)的時(shí)睡時(shí)醒废亭。最近幾天国章,胃口挺好的,持續(xù)的晚上不吃飯計(jì)劃也被打破豆村,所以昨晚又是到了差不...
    天龍?zhí)枪?/span>閱讀 96評(píng)論 0 0