Android 动态申请权限(AndPermission)

AndPermission

这个开源库名叫AndPermission:https://github.com/yanzhenjie/AndPermission,经过我的实践是完全解决了上述问题,推荐大家使用,有兴趣的朋友可以去star下。

AndroidStudio使用方法,gradle一句话远程依赖

compile 'com.yanzhenjie:permission:1.0.8'

Or Maven:

<dependency>
  <groupId>com.yanzhenjiegroupId>
  <artifactId>permissionartifactId>
  <version>1.0.5version>
  <type>pomtype>
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 grantedPermissions) {
        // 权限申请成功回调。
        if(requeust == 100) {
            // TODO 相应代码。
        } else if(requestCode == 101) {
            // TODO 相应代码。
        }
    }

    @Override
    public void onFailed(int requestCode, List 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 grantedPermissions) {
    // TODO 申请权限成功。
}

// 失败回调的方法,用注解即可,里面的数字是请求时的requestCode。
@PermissionNo(100)
private void getLocationNo(List 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 ;
}
-keepclassmembers class ** {
    @com.yanzhenjie.permission.PermissionNo ;
}

你可能感兴趣的:(Android--基础)