很简单, 原理是通过反射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.java
).apply {
isAccessible = true
}
val isAllowNum =
method.invoke(manager, op, Binder.getCallingUid(), context.packageName) as Int
return AppOpsManager.MODE_ALLOWED == isAllowNum
} catch (e: Exception) {
e.printStackTrace()
}
}
return false
}
最后给出我自己通过以上方法记录到的变量值 (以MIUI11为例)
const val MIUI_OP_END = 10028
const val MIUI_OP_START = 10000
const val MODE_ALLOWED = 0
const val MODE_ASK = 5
const val MODE_DEFAULT = 3
const val MODE_ERRORED = 2
const val MODE_FOREGROUND = 4
const val MODE_IGNORED = 1
const val MODE_UNKNOWN = -1
const val OP_ACCEPT_HANDOVER = 74
const val OP_ACCESS_NOTIFICATIONS = 25
const val OP_ACCESS_XIAOMI_ACCOUNT = 10015
const val OP_ACTIVATE_VPN = 47
const val OP_ADD_VOICEMAIL = 52
const val OP_ANSWER_PHONE_CALLS = 69
const val OP_ASSIST_SCREENSHOT = 50
const val OP_ASSIST_STRUCTURE = 49
const val OP_AUDIO_ACCESSIBILITY_VOLUME = 64
const val OP_AUDIO_ALARM_VOLUME = 37
const val OP_AUDIO_BLUETOOTH_VOLUME = 39
const val OP_AUDIO_MASTER_VOLUME = 33
const val OP_AUDIO_MEDIA_VOLUME = 36
const val OP_AUDIO_NOTIFICATION_VOLUME = 38
const val OP_AUDIO_RING_VOLUME = 35
const val OP_AUDIO_VOICE_VOLUME = 34
const val OP_AUTO_START = 10008 //是否允许自启动权限
const val OP_BACKGROUND_LOCATION = 10027 //后台定位权限
const val OP_BACKGROUND_START_ACTIVITY = 10021 //后台弹出界面
const val OP_BIND_ACCESSIBILITY_SERVICE = 73
const val OP_BLUETOOTH_CHANGE = 10002
const val OP_BLUETOOTH_SCAN = 77
const val OP_BODY_SENSORS = 56
const val OP_BOOT_COMPLETED = 10007
const val OP_CALL_PHONE = 13
const val OP_CAMERA = 26
const val OP_CHANGE_WIFI_STATE = 71
const val OP_COARSE_LOCATION = 0
const val OP_DATA_CONNECT_CHANGE = 10003
const val OP_DELETE_CALL_LOG = 10013
const val OP_DELETE_CONTACTS = 10012
const val OP_DELETE_MMS = 10011
const val OP_DELETE_SMS = 10010
const val OP_EXACT_ALARM = 10014
const val OP_FINE_LOCATION = 1
const val OP_GET_ACCOUNTS = 62
const val OP_GET_ANONYMOUS_ID = 10024
const val OP_GET_INSTALLED_APPS = 10022
const val OP_GET_TASKS = 10019
const val OP_GET_UDEVICE_ID = 10025
const val OP_GET_USAGE_STATS = 43
const val OP_GPS = 2
const val OP_INSTALL_SHORTCUT = 10017 //安装快捷方式
const val OP_INSTANT_APP_START_FOREGROUND = 68
const val OP_MANAGE_IPSEC_TUNNELS = 75
const val OP_MOCK_LOCATION = 58
const val OP_MONITOR_HIGH_POWER_LOCATION = 42
const val OP_MONITOR_LOCATION = 41
const val OP_MUTE_MICROPHONE = 44
const val OP_NEIGHBORING_CELLS = 12
const val OP_NFC = 10016
const val OP_NFC_CHANGE = 10009
const val OP_NONE = -1
const val OP_PICTURE_IN_PICTURE = 67
const val OP_PLAY_AUDIO = 28
const val OP_POST_NOTIFICATION = 11
const val OP_PROCESS_OUTGOING_CALLS = 54
const val OP_PROJECT_MEDIA = 46
const val OP_READ_CALENDAR = 8
const val OP_READ_CALL_LOG = 6
const val OP_READ_CELL_BROADCASTS = 57
const val OP_READ_CLIPBOARD = 29
const val OP_READ_CONTACTS = 4
const val OP_READ_EXTERNAL_STORAGE = 59
const val OP_READ_ICC_SMS = 21
const val OP_READ_MMS = 10005
const val OP_READ_NOTIFICATION_SMS = 10018
const val OP_READ_PHONE_NUMBERS = 65
const val OP_READ_PHONE_STATE = 51
const val OP_READ_SMS = 14
const val OP_RECEIVE_EMERGECY_SMS = 17
const val OP_RECEIVE_MMS = 18
const val OP_RECEIVE_SMS = 16
const val OP_RECEIVE_WAP_PUSH = 19
const val OP_RECORD_AUDIO = 27
const val OP_REQUEST_DELETE_PACKAGES = 72
const val OP_REQUEST_INSTALL_PACKAGES = 66
const val OP_RUN_ANY_IN_BACKGROUND = 70
const val OP_RUN_IN_BACKGROUND = 63
const val OP_SEND_MMS = 10004
const val OP_SEND_SMS = 20
const val OP_SERVICE_FOREGROUND = 10023
const val OP_SHOW_DEAMON_NOTIFICATION = 10026
const val OP_SHOW_WHEN_LOCKED = 10020
const val OP_START_FOREGROUND = 76
const val OP_SYSTEM_ALERT_WINDOW = 24
const val OP_TAKE_AUDIO_FOCUS = 32
const val OP_TAKE_MEDIA_BUTTONS = 31
const val OP_TOAST_WINDOW = 45
const val OP_TURN_SCREEN_ON = 61
const val OP_USE_FINGERPRINT = 55
const val OP_USE_SIP = 53
const val OP_VIBRATE = 3
const val OP_WAKE_LOCK = 40
const val OP_WIFI_CHANGE = 10001
const val OP_WIFI_SCAN = 10
const val OP_WRITE_CALENDAR = 9
const val OP_WRITE_CALL_LOG = 7
const val OP_WRITE_CLIPBOARD = 30
const val OP_WRITE_CONTACTS = 5
const val OP_WRITE_EXTERNAL_STORAGE = 60
const val OP_WRITE_ICC_SMS = 22
const val OP_WRITE_MMS = 10006
const val OP_WRITE_SETTINGS = 23
const val OP_WRITE_SMS = 15
const val OP_WRITE_WALLPAPER = 48
是不是很眼熟?..OP_AUTO_START (自启动), .OP_BACKGROUND_START_ACTIVITY (后台弹出界面)
#那判断完成了怎么跳转?
看我另一篇文章 Intent跳转到[自启动]页面全网最全适配机型解决方案(持续更新)
欢迎加入技术交流群: 418263790