Android權限管理PermissionsDispatcher2.3.2使用+原生6.0權限使用


PermissionsDispatcher2.3.2使用

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


權限

Gradle配置

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


(1)當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)當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只介紹幾個注解,保持其通用API簡潔:

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

注解 需要 描述
@RuntimePermissions 在Activity或者Fragment中需要添加,來處理權限的問題
@NeedsPermission 注釋其執行需要一個或多個許可的作用的方法(當用戶授予了權限之后,會調用使用此注解的方法)
@OnShowRationale   注釋這解釋了為什么需要許可/秒/方法。它通過在一個PermissionRequest可用於繼續或中止在用戶輸入的當前的許可請求對象
@OnPermissionDenied   注釋這是調用的方法,如果用戶不授予的權限
@OnNeverAskAgain   注釋如果用戶選擇讓設備“不再詢問”有關許可被調用的方法

具體使用如下:

@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.自動生成的類

Activity繼承了AppCompatActivity,是的,如果使用PermissionsDispatcher進行權限管理,那么Activity就要繼承AppCompatActivity。這就要使用到了兼容包里的類了。同樣此時相應Activity中使用的主題,也需要進行修改,修改成相應兼容包里的主題。
在編譯時,PermissionsDispatcher產生的一類MainActivityPermissionsDispatcher([活動名稱] + PermissionsDispatcher),您可以使用安全地訪問這些許可保護的方法。

MainActivityPermissionsDispatcher需要自己編譯才會有:

@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、在注解的時候添加sdk版本控制
@RuntimePermissions
public class MainActivity extends AppCompatActivity {

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

}

使用步驟:

一、在Manifest中添加權限
  <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);
    }

    /**
     * 顯示相機權限
     */

    @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("是否打開權限")
                .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();
    }

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

    @OnNeverAskAgain(Manifest.permission.CAMERA)
    void showNeverAskForCamera() {
        Toast.makeText(this, "再次獲取權限", Toast.LENGTH_SHORT).show();
    }
三、重寫回調方法,並且使用MainActivityPermissionsDispatcher(此方法編譯生成【Activity】+PermissionsDispatcher)
  /**
     * 權限請求回調,提示用戶之后,用戶點擊“允許”或者“拒絕”之后調用此方法
     *
     * @param requestCode  定義的權限編碼
     * @param permissions  權限名稱
     * @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, "相機");
//                默認是沒有此類的,需要編譯下才會有此類
                MainActivityPermissionsDispatcher.showCameraWithCheck(this);

                break;

        }
    }

注意

  • 使用到的權限需要在Mnifest里面注冊
  • PermissionsDispatcher依賴於support-v4由默認庫,以便能夠使用一些權限compat的類。
  • 需要添加support-v13庫一起PermissionsDispatcher在您的項目,它將使原生片段支持





原生6.0權限使用

Android 6.0 變更

另請參閱
Android 6.0 API 概覽

Android 6.0(API 級別 23)除了提供諸多新特性和功能外,還對系統和 API 行為做出了各種變更。
如果您之前發布過 Android 應用,請注意您的應用可能受到這些平台變更的影響。

運行時權限

此版本引入了一種新的權限模式,如今,用戶可直接在運行時管理應用權限。這種模式讓用戶能夠更好地了解和控制權限,同時為應用開發者精簡了安裝和自動更新過程。用戶可為所安裝的各個應用分別授予或撤銷權限。
對於以 Android 6.0(API 級別 23)或更高版本為目標平台的應用,請務必在運行時檢查和請求權限。要確定您的應用是否已被授予權限,請調用新增的 checkSelfPermission()
方法。要請求權限,請調用新增的 requestPermissions()
方法。即使您的應用並不以 Android 6.0(API 級別 23)為目標平台,您也應該在新權限模式下測試您的應用。

使用步驟

1、在AndroidManifest文件中添加需要的權限。

這個步驟和我們之前的開發並沒有什么變化,試圖去申請一個沒有聲明的權限可能會導致程序崩潰。

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

這里涉及到一個API,ContextCompat.checkSelfPermission,主要用於檢測某個權限是否已經被授予,方法返回值為PackageManager.PERMISSION_DENIED或者PackageManager.PERMISSION_GRANTED。當返回DENIED就需要進行申請授權了。

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

該方法是異步的,第一個參數是Context;第二個參數是需要申請的權限的字符串數組;第三個參數為requestCode,主要用於回調的時候檢測。可以從方法名requestPermissions以及第二個參數看出,是支持一次性申請多個權限的,系統會通過對話框逐一詢問用戶是否授權。

4、處理權限申請回調
@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;
        }
    }
}

首先驗證requestCode定位到你的申請,然后驗證grantResults對應於申請的結果,這里的數組對應於申請時的第二個權限字符串數組。如果你同時申請兩個權限,那么grantResults的length就為2,分別記錄你兩個權限的申請結果。如果申請成功,就可以做你的事情了~

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

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



作者:流水潺湲
鏈接:http://www.jianshu.com/p/d299f22dfbdb
來源:簡書
著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。

補充

現在網上不少關於權限的庫,可以直接用的,在GitHub上搜索即可
https://github.com/search?o=desc&q=android+permission&s=stars&type=Repositories&utf8=%E2%9C%93


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM