1. 程式人生 > >Android 動態申請許可權(AndPermission)

Android 動態申請許可權(AndPermission)

AndPermission

AndroidStudio使用方法,gradle一句話遠端依賴

compile 'com.yanzhenjie:permission:1.0.8'

Or Maven:

<dependency>
  <groupId>com.yanzhenjie</groupId>
  <artifactId>permission</artifactId>
  <version>1.0.5</version>
  <type>pom</type>
</dependency
>

Eclipse 下載jar包,或者下載原始碼。
申請許可權

一個許可權

AndPermission.with(this)
    .requestCode(100)
    .permission(Manifest.permission.WRITE_CONTACTS)
    .send();

多個許可權

AndPermission.with(this)
    .requestCode(100)
    .permission(Manifest.permission.WRITE_CONTACTS, Manifest.permission.READ_SMS)
    .send
();

在使用到特殊許可權時,只需要在Activity、Fragment中直接呼叫,等到AndPermission回撥時即可執行相應的程式碼。

注意
1. 如果你的Activity繼承的是AppCompatActivity、FragmentActivity或者它們的子類,那麼你直接請求許可權就可以。
2. 如果你的Fragment繼承的是android.support.v4.app.Fragment或者它的子類,那麼你直接請求許可權就可以。
3. 如果你繼承的是android.app.Activity、android.app.Fragment、在6.0以下的手機是沒有onRequestPermissionsResult()方法的,所以需要在申請許可權前判斷:

// 先判斷是否有許可權。

if(AndPermission.hasPermission(this, Manifest.permission.READ_SMS)) {
    // 有許可權,直接do anything.
} else {
    // 申請許可權。
    AndPermission.with(this)
        .requestCode(100)
        .permission(Manifest.permission.WRITE_CONTACTS, Manifest.permission.READ_SMS)
        .send();
}

回撥結果

方式一:利用Listener方式回撥

@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
    // 只需要呼叫這一句,其它的交給AndPermission吧,最後一個引數是PermissionListener。
    AndPermission.onRequestPermissionsResult(requestCode, permissions, grantResults, listener);
}

private PermissionListener listener = new PermissionListener() {
    @Override
    public void onSucceed(int requestCode, List<String> grantedPermissions) {
        // 許可權申請成功回撥。
        if(requeust == 100) {
            // TODO 相應程式碼。
        } else if(requestCode == 101) {
            // TODO 相應程式碼。
        }
    }

    @Override
    public void onFailed(int requestCode, List<String> deniedPermissions) {
        // 許可權申請失敗回撥。

        // 使用者否勾選了不再提示並且拒絕了許可權,那麼提示使用者到設定中授權。
        if (AndPermission.hasAlwaysDeniedPermission(this, deniedPermissions)) {
            // 第一種:用預設的提示語。
            AndPermission.defaultSettingDialog(this, REQUEST_CODE_SETTING).show();

            // 第二種:用自定義的提示語。
            // AndPermission.defaultSettingDialog(this, REQUEST_CODE_SETTING)
            // .setTitle("許可權申請失敗")
            // .setMessage("我們需要的一些許可權被您拒絕或者系統發生錯誤申請失敗,請您到設定頁面手動授權,否則功能無法正常使用!")
            // .setPositiveButton("好,去設定")
            // .show();

            // 第三種:自定義dialog樣式。
            // SettingService settingService = 
            //    AndPermission.defineSettingDialog(this, REQUEST_CODE_SETTING);
            // 你的dialog點選了確定呼叫:
            // settingService.execute();
            // 你的dialog點選了取消呼叫:
            // settingService.cancel();
        }
    }
};

方式二:利用註解回撥
只需要重寫Activity/Fragment的一個方法,然後提供一個授權時回撥的方法即可:

@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
    // 只需要呼叫這一句,第一個引數是當前Acitivity/Fragment,回撥方法寫在當前Activity/Framgent。
    AndPermission.onRequestPermissionsResult(this, requestCode, permissions, grantResults);
}

// 成功回撥的方法,用註解即可,裡面的數字是請求時的requestCode。
@PermissionYes(100)
private void getLocationYes(List<String> grantedPermissions) {
    // TODO 申請許可權成功。
}

// 失敗回撥的方法,用註解即可,裡面的數字是請求時的requestCode。
@PermissionNo(100)
private void getLocationNo(List<String> deniedPermissions) {
    // 使用者否勾選了不再提示並且拒絕了許可權,那麼提示使用者到設定中授權。
    if (AndPermission.hasAlwaysDeniedPermission(this, deniedPermissions)) {
        // 第一種:用預設的提示語。
       AndPermission.defaultSettingDialog(this, REQUEST_CODE_SETTING).show();
    }
}

如果你會用了,你就可以大刀闊斧的幹了,部落格中講到的各種複雜邏輯,AndPermission自動完成。

Rationale拒絕一次後,再次提示使用者許可權作用

方式一:使用AndPermssion預設MD風格對話方塊

AndPermission.with(this)
    .requestCode(REQUEST_CODE_PERMISSION_LOCATION)
    .permission(Manifest.permission.ACCESS_FINE_LOCATION)
    .rationale((requestCode, rationale) ->
        // 此對話方塊可以自定義,呼叫rationale.resume()就可以繼續申請。
        AndPermission.rationaleDialog(PermissionActivity.this, rationale).show()
    )
    .send()

方式二:自定義對話方塊

AndPermission.with(this)
    .requestCode(REQUEST_CODE_PERMISSION_LOCATION)
    .permission(Manifest.permission.ACCESS_FINE_LOCATION)
    .rationale(rationaleListener)
    .send()

/**
 * Rationale支援,這裡自定義對話方塊。
 */
private RationaleListener rationaleListener = (requestCode, rationale) -> {
    AlertDialog.build(this)
        .setTitle("友好提醒")
        .setMessage("您已拒絕過定位許可權,沒有定位許可權無法為您推薦附近妹子,請把定位許可權賜給我吧!")
        .setPositiveButton("好,給你", (dialog, which) -> {
            rationale.resume();
        })
        .setNegativeButton("我拒絕", (dialog, which) -> {
            rationale.cancel();
        }).show();
};

混淆

  1. 如果使用Listener接受回撥結果,不用任何配置。

  2. 使用註解的方式回撥結果,在proguard-rules.pro中新增如下配置

-keepclassmembers class ** {
    @com.yanzhenjie.permission.PermissionYes <methods>;
}
-keepclassmembers class ** {
    @com.yanzhenjie.permission.PermissionNo <methods>;
}