简介
满足Android手机6.0以上动态权限,一行代码即可实现动态权限的申请及检测,已适配目前市场上大部分手机,这个库本来是自己用的,但是大家都知道,目前国产手机品牌众多。要向适配百分百的手机简直是不可能。所以我就把他分享出来,一是希望能帮助更多的人,而是希望把大家的适配方案都集中起来,帮助更多的人。
功能介绍
一、权限
1.支持所有危险权限
2.支持悬浮窗权限
3.支持Android O 的安装未知应用权限
4.支持通知权限且支持Android O的Channel
5.支持以上所有权限的检查,你可以检查以上的这些权限是否已经被授权,尽管通常情况下你不需要做检查只需要调用OkPermission.checkAndApply{}方法即可,但是该库还是提供了检查权限的方法。
二、页面跳转
1.支持权限管理页面的跳转
2.支持安装未知应用权限页面的跳转
3.支持悬浮窗权限设置页面的跳转
4.支持通知权限设置页面的跳转且支持Android O的Channel,可跳转到指定Channel的权限设置页面。
5.以上所有页面跳转均已适配我身边现有的手机设备。
01).锤子T1(smartisan os v3.7.2)
02).小米MAX2(MIUI 10.3)
03).小米5(MIUI 10.3)
04).华为P8MAX(EMUI4.0.3)
05).华为P10(EMUI 9.0)
06).华为P30(EMUI 9.1)
07).荣耀6plus(EMUI 4.0.1)
08).荣耀note10(EMUI 9.0)
09).魅族note5(Flyme 7.0.1.0A)
10).三星A7
11).三星note3
12).三星S10(ONE UI 1.1)
13).乐视2(5.9.028s稳定版)
14).realme X(ColorOs v6.0)
我的设备有限如果有哪位兄台发现了我没有适配到的手机欢迎将适配代码分享出来,可以直接在下面留言也可以在Github上提交issues。虽然你的手机设备我可能没有适配到但绝对不会影响你使用该库。原因有二,其一是没有适配到的页面或适配但跳转会失败的页面最终会跳转到AppDetail你的应用详情页面不会出现崩溃的现象,还有就是所有的权限设置页面一般都可以从AppDetail进入。其二就是你可以自定通过调用接口自己手动实现适配,而且只需要考虑你自己的适配就行了。自己适配的方法会在后面详细讲解。
三、下载
第一步:添加 JitPack 仓库到你项目根目录的 gradle 文件中。
allprojects {
repositories {
//... 省略N行代码
maven { url 'https://jitpack.io' }
}
}
第二步:添加这个依赖。
dependencies {
implementation 'com.github.kelinZhou:OkPermission:3.0.3'
}
使用
一行代码申请动态权限
如果你想申请清单文件中注册了的所有权限,支持使用checkAndApply方法即可:
OkPermission.with(this)
.checkAndApply { granted, permissions ->
if (granted) {
Toast.makeText(this, "权限已全部获取", Toast.LENGTH_SHORT).show()
} else {
Toast.makeText(this, "未获取全部权限", Toast.LENGTH_SHORT).show()
}
}
如果要获取拨打电话和调用相机的权限。
OkPermission.with(this)
.addDefaultPermissions(
Manifest.permission.CALL_PHONE,
Manifest.permission.CAMERA
).checkAndApply { granted, permissions ->
if (granted) {
Toast.makeText(this, "权限已全部获取", Toast.LENGTH_SHORT).show()
} else {
Toast.makeText(this, "未获取全部权限", Toast.LENGTH_SHORT).show()
}
}
当用户拒绝权限且不再提醒后会引导用户前往设置页面。引导时会有弹窗,而这个弹窗是可以自定义的。
如果要自定义可以向下面这样。
OkPermission.with(this)
.addDefaultPermissions(
Manifest.permission.CALL_PHONE,
Manifest.permission.CAMERA
)
.interceptMissingPermissionDialog {
AlertDialog.Builder(this)
.setCancelable(false)
.setTitle("帮助")
.setMessage("缺少拨打电话和拍照权限,请前往设置。")
.setNegativeButton("退出") { _, _ ->
it.continueWorking(false)
}
.setPositiveButton("设置") { _, _ ->
it.continueWorking(true)
}.show()
}.checkAndApply { granted, permissions ->
if (permissions.isEmpty()) {
Toast.makeText(this, "权限已全部获取", Toast.LENGTH_SHORT).show()
} else {
Toast.makeText(this, "未获取全部权限", Toast.LENGTH_SHORT).show()
}
}
支持APK安装权限,且已适配我手头上现有的手机。
OkPermission.with(this)
.addDefaultPermissions(Manifest.permission.REQUEST_INSTALL_PACKAGES)
.checkAndApply { granted, permissions ->
if (granted) {
Toast.makeText(this, "可以安装APK了", Toast.LENGTH_SHORT).show()
} else {
Toast.makeText(this, "没有安装APK权限", Toast.LENGTH_SHORT).show()
}
}
支持通知权限且支持Android8.0中Channel且支持多个Channel。
OkPermission.with(this)
.addNotificationPermission(false, "Channel1", "Channel2", "Channel3"/*ChannelN ……*/)
.checkAndApply { granted, permissions ->
if (granted) {
Toast.makeText(this, "用户已同意了全部的通知权限", Toast.LENGTH_SHORT).show()
} else {
Toast.makeText(this, "用户拒绝了通知权限", Toast.LENGTH_SHORT).show()
}
}
支持悬浮窗权限。
OkPermission.with(this)
.addDefaultPermissions(Manifest.permission.SYSTEM_ALERT_WINDOW)
.checkAndApply { granted, permissions ->
if (granted) {
Toast.makeText(this, "悬浮窗权限已开启", Toast.LENGTH_SHORT).show()
} else {
Toast.makeText(this, "悬浮窗权限已禁用", Toast.LENGTH_SHORT).show()
}
}
支持GPS开关,定位时不但需要定位权限,还需要开启GPS开关。你可以这样写:
if (OkPermission.with(this).addDefaultPermissions(OkPermission.permission.GPS).isGranted()) {
OkPermission.with(this)
.addDefaultPermissions(*OkPermission.permission_group.ACCESS_LOCATION)
.checkAndApply { granted, permissions ->
if (granted) {
Toast.makeText(this, "定位权限已开启", Toast.LENGTH_SHORT).show()
} else {
Toast.makeText(this, "定位权限已禁用", Toast.LENGTH_SHORT).show()
}
}
} else {
AlertDialog.Builder(this)
.setTitle("提示:")
.setMessage("需要打开系统定位开关,用于定位服务。")
.setNegativeButton("暂不开启"){ dialog, which ->
dialog.dismiss()
}
.setPositiveButton("去设置"){dialog, which ->
dialog.dismiss()
OkPermission.with(this)
.addDefaultPermissions(OkPermission.permission.GPS)
.checkAndApplyOnly()
}.show()
}
支持系统设置权限
OkPermission.with(this)
.addDefaultPermissions(Manifest.permission.WRITE_SETTINGS)
.checkAndApply { granted, permissions ->
if (granted) {
Toast.makeText(this, "系统设置权限已开启", Toast.LENGTH_SHORT).show()
} else {
Toast.makeText(this, "系统设置权限已禁用", Toast.LENGTH_SHORT).show()
}
}
支持检测某些权限是否已开启。
val granted = OkPermission.with(this)
.addDefaultPermissions(
Manifest.permission.CALL_PHONE,
Manifest.permission.CAMERA,
Manifest.permission.REQUEST_INSTALL_PACKAGES
).isGranted()
if (granted) {
Toast.makeText(this, "可以使用全部的权限", Toast.LENGTH_SHORT).show()
}
支持跳转到指定的权限设置页面,且已适配目前手头上的全部手机。
//跳转到权限设置页面,如果跳转失败则会跳转到应用详情页。
OkPermission.gotoPermissionSettingPage(this)
//跳转到Apk安装权限设置页面,需要判断当前SDK版本。
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
OkPermission.gotoInstallPermissionPage(this)
} else {
Toast.makeText(this, "当前系统版本过低", Toast.LENGTH_SHORT).show()
}
//跳转到系统设置页面
OkPermission.gotoWriteSettingsPage(this)
//跳转到GPS开启页面
OkPermission.gotoGPSSettingsPage(this)
//跳转到通知权限设置页面,可以指定ChannelId,如果指定这跳转到指定Channel的通知设置页面,如果不指定这跳转到通知的总开关设置页面。
OkPermission.gotoNotificationPermissionPage(this/*, "ChannelId"*/)
//跳转到悬浮窗权限设置页面。
OkPermission.gotoSystemWindowPermissionPage(this)
机型适配
所有设置页面的跳转均已适配我手头上现有的手机,如果你发现了未适配的手机可以通过自定义SettingIntentGenerator
类来实现,并请求你将适配代码也就是你自定义的SettingIntentGenerator
类贴到Issues里面或发送到我邮箱kelin410@163.com,万分感谢。
下面是自定义SettingIntentGenerator
的用法。
OkPermission.with(this)
.addDefaultPermissions(
Manifest.permission.CALL_PHONE,
Manifest.permission.CAMERA
).interceptSettingIntentGenerator { permission ->
if (isMiUi10) {//先判读是不是自己想要拦截的系统
MiUi10SettingIntentGenerator() //返回你的适配方案。然后感谢你将该类的代码分享出来帮助更多的人,感谢!
} else {
null //返回了null就表示不自己适配,而是使用默认的适配。
}
}
.checkAndApply { granted, permissions ->
if (granted) {
Toast.makeText(this, "权限已全部获取", Toast.LENGTH_SHORT).show()
} else {
Toast.makeText(this, "未获取全部权限", Toast.LENGTH_SHORT).show()
}
}
所有的权限都是通过PermissionsApplicant
类申请的,而PermissionsApplicant
也是可以自定义的。如果你需要自定义PermissionsApplicant
可以像下面这样。
OkPermission.with(this)
.addDefaultPermissions(
Manifest.permission.CALL_PHONE,
Manifest.permission.CAMERA,
Manifest.permission.REQUEST_INSTALL_PACKAGES
)
.interceptCheckPermissionType(object :OkPermission.MakeApplicantInterceptor{
/**
* 是否拦截,如果你希望拦截本次创建则返回true,否则应当返回false。只有在返回true的时候 makeApplicant方法才会执行。
*
* @param permission 你要申请的权限中的其中一个。
*/
override fun interceptMake(permission: Permission): Boolean {
return permission.permission == Manifest.permission.REQUEST_INSTALL_PACKAGES && isMIUI10()
}
/**
* 根据一个权限返回其所对应的权限申请器。该方法只有在interceptMake方法返回true的时候再回被执行。
*
* @param permission 你要申请的权限中的其中一个。
*/
override fun makeApplicant(permission: Permission): Class<out PermissionsApplicant> {
return MIUIPermissionsApplicant::class.java
}
})
.checkAndApply { granted, permissions ->
if (granted) {
Toast.makeText(this, "权限已全部获取", Toast.LENGTH_SHORT).show()
} else if (!permissions.contains(Manifest.permission.REQUEST_INSTALL_PACKAGES)) {
Toast.makeText(this, "安装权限已获取", Toast.LENGTH_SHORT).show()
} else {
Toast.makeText(this, "未获取全部权限", Toast.LENGTH_SHORT).show()
}
}
最后奉上GitHub地址如果您觉得有用,还望给个Star,您的鼓励将是我继续创作和维护的动力。感谢!!!
网友评论