个人博客:haichenyi.com。感谢关注
总所周知,Android 6.0以上的版本,google对权限做了更严格的限制,不能app自动给权限,必须要让用户选择是否给权限。如果,用户不给权限,辣么,用这个功能的时候,app会造成崩溃,所以,最简单的办法就是,用户不给权限,不让用户用这个功能,也就是页面不做跳转。
当时,刚出来这个权限问题的时候,本人用原生的写,写了封装,搞了好长时间,总感觉各种不爽,各种不舒服,后来好了,大牛封装了一个开源框架——RxPermission,一行代码解决动态申请权限问题。
依赖
implementation 'com.tbruyelle.rxpermissions2:rxpermissions:0.9.4@aar'
工具类
package com.haichenyi.myproject.utils
import android.app.Activity
import android.content.Intent
import android.net.Uri
import android.os.Build
import android.os.Environment
import android.provider.Settings
import android.support.v7.app.AlertDialog
import com.haichenyi.myproject.R
import com.tbruyelle.rxpermissions2.RxPermissions
import java.io.File
import java.io.FileInputStream
import java.io.IOException
import java.util.*
/**
* Author: 海晨忆
* Date: 2018/2/28
* Desc:
*/
object RxPerUtils {
/**
* 请求权限的获取方法
* activity:Activity对象
* permissions:需要获取的权限,可以传多个
* aloe: (b: Boolean):一个参数的回调方法,b为true,表示用户给了权限,false,表示没有给权限
*/
fun requestPermission(activity: Activity, vararg permissions: String, aloe: (b: Boolean) -> Unit) {
RxPermissions(activity).request(*permissions)
.subscribe { aBoolean -> aloe(aBoolean) }
}
/**
* 当用户拒绝给权限的时候调用,跳转权限设置页面,让用户手动给权限
* activity:Activity对象
* permissionName:权限名称
* msg:提示信息
*/
fun setupPermission(activity: Activity, permissionName: String, msg: String,
aloe: () -> Unit) {
AlertDialog.Builder(activity, R.style.Theme_AppCompat_Dialog).setTitle("权限申请")
.setMessage(String.format(Locale.getDefault(),
"请在“权限”中开启“%1s权限”,以正常使用%2s", permissionName, msg))
.setCancelable(false)
.setNegativeButton(android.R.string.cancel) { dialog, which -> aloe }.setPositiveButton("去设置") { dialog, which ->
if (isMiUi()) {
setMiUiPermissions(activity)
} else {
activity.startActivityForResult(Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
.setData(Uri.fromParts("package", activity.packageName, null)), 1000)
}
}.create().show()
}
private fun setMiUiPermissions(activity: Activity) {
if (isMiUi()) {
try {
// MIUI 8
activity.startActivityForResult(Intent("miui.intent.action.APP_PERM_EDITOR")
.setClassName("com.miui.securitycenter",
"com.miui.permcenter.permissions.PermissionsEditorActivity")
.putExtra("extra_pkgname", activity.packageName), 1000)
} catch (e: Exception) {
try {
// MIUI 5/6/7
activity.startActivityForResult(Intent("miui.intent.action.APP_PERM_EDITOR")
.setClassName("com.miui.securitycenter",
"com.miui.permcenter.permissions.AppPermissionsEditorActivity")
.putExtra("extra_pkgname", activity.packageName), 1000)
} catch (e1: Exception) {
// 否则跳转到应用详情
activity.startActivityForResult(Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
.setData(Uri.fromParts("package", activity.packageName,
null)), 1000)
}
}
}
}
private fun isMiUi(): Boolean {
val device = Build.MANUFACTURER
if (device == "Xiaomi") {
try {
val prop = Properties()
prop.load(FileInputStream(File(Environment.getRootDirectory(), "build.prop")))
return (prop.getProperty("ro.miui.ui.version.code", null) != null
|| prop.getProperty("ro.miui.ui.version.name", null) != null
|| prop.getProperty("ro.miui.internal.storage", null) != null)
} catch (e: IOException) {
e.printStackTrace()
}
}
return false
}
}
调用
RxPerUtils.requestPermission(this, Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE) {
if (it) {
//这里写你自己的逻辑,已经获得权限,做你自己的业务逻辑操作
ToastUtils.showTipMsg("已经获得权限")
} else {
RxPerUtils.setupPermission(this, "相机和存储",
"相机功能") {
}
}
}
请求权限的整个过程就是:
- 用RxPermission去请求权限,需要传activity对象,然后就是你需要获取的权限(可以传多个),再就是回调方法
- 在回调方法里面做判断,用户是否给了权限,如果给了,就走你正常的逻辑。如果没有给,就弹对话框提示用户,去设置页面给权限。
就这么简单,方法都封装好了,如果,你嫌弃系统自带的对话框样式不好看,你也可以自己写一个样式。项目就不传了,如果你有之前的代码,就直接把我这几个方法拷贝过去用就可以了,没有之前的代码,就去瞅瞅之前的博客吧。