说动态权限之前,我们先看一下app下build.gradle文件里面的几个参数,分别是:
- compileSdkVersion
- buildToolsVersion
- minSdkVersion
- targetSdkVersion
现在用Android Studio创建新项目,这些参数都会默认创建好,但是如果看一些之前的项目,还是有必要弄清楚这些参数的。
> compileSdkVersion
编译app时用的SDK版本
> buildToolsVersion
- 构建工具的版本。该工具的目录在你的sdk路径/build-tools/下,当我们下载一个开源项目时,我们本地下载的buildTools不一定和开源项目一致,这时并不一定要下载和上面一致的builTools,只要改成本地有的即可。
- buildToolsVersion对应的值,可以比compilesdkVersion大,并不一定要一致,只不过现在创建项目时,默认都一致了。
> minSdkVersion
应用可以运行的最低版。例如:
minSdkVersion = 19,19对应的Android系统是4.4,那么最终该apk就不能在Android4.4以下的系统上运行
> targetSdkVersion
- 主要起到向前兼容的作用,这个参数也涉及到了动态权限的问题,我们知道Android6.0开始出现了动态权限的概念,即sdkversion=23.
- 假如我们项目的targetSdkVersion=22,如果运行在Android6.0甚至更高版本上,我们发现并没有问题,因为只兼容到了22,而从23开始才需要动态获取权限
- 那是不是不做动态获取权限的适配就行了,也不会有问题。但是Android6.0以上,用户是可以手动去设置里面,改变应用权限的,如果用户手动关掉了权限,你的应用又没有对应的适配和提示,那么有些功能就无法使用,甚至造成崩溃
所以我们做项目时,应该适配最新版本,最好和官方一致
既然必须要做适配,那么我们就来看看如何动态获取权限,这里我直接用一个开源框架,RXpermissions
按照正常流程我们一般需要考虑三点:
- 用户同意权限,然后进行后续操作
- 用户拒绝,那么可以对话框提示该权限的重要性,并让用户再次获取
- 用户点击了永不提示,如果这样影响了软件的使用,那是必须要提示用户的
下面给出对应代码
public static void requestPermission(final FragmentActivity activity){
RxPermissions rxPermissions = new RxPermissions(activity);
rxPermissions.requestEach(Manifest.permission.WRITE_EXTERNAL_STORAGE)
.subscribe(new Consumer<Permission>() {
@Override
public void accept(Permission permission) throws Exception {
if (permission.granted) {// 同意了
} else if (permission.shouldShowRequestPermissionRationale) {
// 拒绝了
showRationaleDialog(activity);
} else {
// 选择了不再提醒
showOpenAppSettingDialog(activity);
}
}
});
}
private static void showRationaleDialog(final FragmentActivity activity) {
if (activity == null) return;
new AlertDialog.Builder(activity)
.setTitle(android.R.string.dialog_alert_title)
.setMessage("请同意授权,否则该功能不能正常使用!")
.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
requestPermission(activity);
}
})
.setCancelable(false)
.create()
.show();
}
private static void showOpenAppSettingDialog(final FragmentActivity activity) {
if (activity == null) return;
new AlertDialog.Builder(activity)
.setTitle(android.R.string.dialog_alert_title)
.setMessage("请手动到设置页面授权,否则功能不能正常使用!")
.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
launchAppDetailsSettings();
}
})
.setCancelable(false)
.create()
.show();
}
/**
* Launch the application's details settings.
*/
private static void launchAppDetailsSettings() {
Intent intent = new Intent("android.settings.APPLICATION_DETAILS_SETTINGS");
intent.setData(Uri.parse("package:" + Utils.getApp().getPackageName()));
Utils.getApp().startActivity(intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
}
针对三种情况,都给出了对应的解决方案,实际应用中可以根据具体需求对应处理。