fix: 改进 NotificationManager 服务实例获取和验证逻辑

main
mojo 1 month ago
parent 4e5054f6d3
commit 9934938dac

@ -107,13 +107,34 @@ object NotificationManger {
} }
private fun getServiceInstance(context: Context): Any? { private fun getServiceInstance(context: Context): Any? {
// 优先使用已注册的服务实例MyService.instance // 优先使用已缓存的实例
if (serviceInstance != null) { if (serviceInstance != null && serviceInstance is NotificationListenerService) {
// LogUtils.info("NotificationManager: using cached service instance") val service = serviceInstance as NotificationListenerService
return serviceInstance // 验证服务是否仍然有效(通过检查 onListenerConnected 是否被调用)
if (isServiceValid(service)) {
return serviceInstance
} else {
// 实例无效,清除缓存
serviceInstance = null
}
} }
// 尝试从服务类的静态字段获取实例 // 优先尝试直接获取 MyService.instance系统绑定的实例
try {
val myServiceClass = Class.forName("com.galaxy.demo.MyService")
val instanceField = myServiceClass.getDeclaredField("instance")
instanceField.isAccessible = true
val instance = instanceField.get(null) as? NotificationListenerService
if (instance != null && isServiceValid(instance)) {
LogUtils.info("NotificationManager: got instance from MyService.instance")
serviceInstance = instance
return instance
}
} catch (e: Exception) {
LogUtils.info("NotificationManager: failed to get MyService.instance: ${e.message}")
}
// 尝试从服务类的静态字段获取实例(备用方案)
val serviceClass = findServiceClass(context) val serviceClass = findServiceClass(context)
if (serviceClass == null) { if (serviceClass == null) {
LogUtils.info("NotificationManager: service class not found") LogUtils.info("NotificationManager: service class not found")
@ -121,13 +142,43 @@ object NotificationManger {
} }
LogUtils.info("NotificationManager: found service class ${serviceClass.name}") LogUtils.info("NotificationManager: found service class ${serviceClass.name}")
serviceInstance = getInstance(serviceClass) val instance = getInstance(serviceClass)
if (serviceInstance == null) { if (instance != null && instance is NotificationListenerService && isServiceValid(instance)) {
LogUtils.info("NotificationManager: failed to get service instance") serviceInstance = instance
} else {
LogUtils.info("NotificationManager: service instance obtained successfully") LogUtils.info("NotificationManager: service instance obtained successfully")
return instance
} else {
LogUtils.info("NotificationManager: failed to get valid service instance")
serviceInstance = null
return null
}
}
private fun isServiceValid(service: NotificationListenerService): Boolean {
return try {
// 尝试使用反射检查 isBound 属性(如果存在)
val isBoundMethod = try {
service.javaClass.getMethod("isBound")
} catch (e: NoSuchMethodException) {
null
}
if (isBoundMethod != null) {
val isBound = isBoundMethod.invoke(service) as? Boolean
if (isBound == false) {
return false
}
}
// 如果无法检查 isBound直接假设有效实际验证在 getNotifications 中进行)
true
} catch (e: SecurityException) {
LogUtils.info("NotificationManager: service is not bound by system")
false
} catch (e: Exception) {
// 如果无法验证,假设有效(实际验证在 getNotifications 中进行)
true
} }
return serviceInstance
} }
private fun isNotificationListenerEnabled(context: Context): Boolean { private fun isNotificationListenerEnabled(context: Context): Boolean {
@ -192,42 +243,33 @@ object NotificationManger {
} }
private fun getNotifications(instance: Any): List<StatusBarNotification>? { private fun getNotifications(instance: Any): List<StatusBarNotification>? {
val service = instance as? NotificationListenerService
if (service == null) {
LogUtils.info("NotificationManager: instance is not NotificationListenerService")
return null
}
return try { return try {
// 确保实例是 NotificationListenerService 类型 // 尝试使用反射检查 isBound如果 API 可用)
val service = instance as? NotificationListenerService val isBound = try {
if (service != null) { val isBoundMethod = service.javaClass.getMethod("isBound")
// 直接调用方法,避免反射调用导致的 SecurityException isBoundMethod.invoke(service) as? Boolean ?: true
val result = service.activeNotifications } catch (e: NoSuchMethodException) {
return result?.toList() ?: emptyList() // isBound 方法不存在(旧版本 Android直接尝试调用
true
} catch (e: Exception) {
true
} }
// 如果类型转换失败,使用反射(可能触发 SecurityException if (!isBound) {
val method: Method = instance.javaClass.getMethod("getActiveNotifications") LogUtils.info("NotificationManager: service is not bound, clearing cache")
method.isAccessible = true serviceInstance = null
val result = method.invoke(instance)
if (result == null) {
LogUtils.info("NotificationManager: getActiveNotifications returned null")
return null return null
} }
val notifications = when { // 直接调用方法获取通知(这里会抛出 SecurityException 如果服务无效)
result is Array<*> -> { val result = service.activeNotifications
result.filterIsInstance<StatusBarNotification>() result?.toList() ?: emptyList()
}
result is List<*> -> {
result.filterIsInstance<StatusBarNotification>()
}
else -> {
LogUtils.info("NotificationManager: unexpected result type: ${result.javaClass.name}")
null
}
}
// notifications?.let {
// LogUtils.info("NotificationManager: retrieved ${it.size} active notifications")
// }
notifications
} catch (e: SecurityException) { } catch (e: SecurityException) {
LogUtils.error(e, "NotificationManager: SecurityException - notification listener may not be enabled or instance is invalid") LogUtils.error(e, "NotificationManager: SecurityException - notification listener may not be enabled or instance is invalid")
// 清除缓存的实例,下次尝试重新获取 // 清除缓存的实例,下次尝试重新获取

Loading…
Cancel
Save