如图:
我们在做适配的时候有没有遇到一类需求, 比如 判断某个权限, 而这个权限是某手机自己创造的 不属于原生api, 怎么判断? 如 第三方ROM中的 [开机自启动] [后台省电] [后台打开界面] 等
现在, 有办法解决了!
很简单, 原理是通过反射AppOpsManager取得支持的变量, 理论上 华为小米 魅族这些新增的权限都会在这个类里面增加常量值, 我们只需要反射遍历这些常量值即可:
以[后台弹出界面] 权限为例:
我们在app里加入这个函数, 运行app 后观察log日志 观察哪些权限的变量名和[后台弹出界面] 的意思比较和相似, 进行定位
/**
* 通过这个获取所有的OPS Field, 理论上第三方系统厂商都是修改这个来实现新增权限的, 这个可以解决比如miui的自启动和后台弹出界面等
*/
fun getAllOPSField(context: Context) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
val manager = context.getSystemService(Context.APP_OPS_SERVICE) as AppOpsManager
val f = manager.javaClass.declaredFields
for (field in f) {
if (field.type == Int::class.java && Modifier.isStatic(field.modifiers)) {
field.isAccessible = true
println("${field.name} = ${field.get(null)}")
}
}
}
}
然后通过一下代码判断该权限
@RequiresApi(Build.VERSION_CODES.KITKAT)
fun checkOp(context: Context, op: Int): Boolean {
val version = Build.VERSION.SDK_INT
if (version >= 19) {
val manager = context.getSystemService(Context.APP_OPS_SERVICE) as AppOpsManager
try {
val managerClass = manager.javaClass
val method = managerClass.getDeclaredMethod(
"checkOp",
Int::class.java,
Int::class.java,
String::class.