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

main
mojo 1 month ago
parent 4e5054f6d3
commit 9934938dac

@ -107,13 +107,34 @@ object NotificationManger {
}
private fun getServiceInstance(context: Context): Any? {
// 优先使用已注册的服务实例MyService.instance
if (serviceInstance != null) {
// LogUtils.info("NotificationManager: using cached service instance")
return serviceInstance
// 优先使用已缓存的实例
if (serviceInstance != null && serviceInstance is NotificationListenerService) {
val service = serviceInstance as NotificationListenerService
// 验证服务是否仍然有效(通过检查 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)
if (serviceClass == null) {
LogUtils.info("NotificationManager: service class not found")
@ -121,13 +142,43 @@ object NotificationManger {
}
LogUtils.info("NotificationManager: found service class ${serviceClass.name}")
serviceInstance = getInstance(serviceClass)
if (serviceInstance == null) {
LogUtils.info("NotificationManager: failed to get service instance")
} else {
val instance = getInstance(serviceClass)
if (instance != null && instance is NotificationListenerService && isServiceValid(instance)) {
serviceInstance = instance
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 {
@ -192,42 +243,33 @@ object NotificationManger {
}
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 {
// 确保实例是 NotificationListenerService 类型
val service = instance as? NotificationListenerService
if (service != null) {
// 直接调用方法,避免反射调用导致的 SecurityException
val result = service.activeNotifications
return result?.toList() ?: emptyList()
// 尝试使用反射检查 isBound如果 API 可用)
val isBound = try {
val isBoundMethod = service.javaClass.getMethod("isBound")
isBoundMethod.invoke(service) as? Boolean ?: true
} catch (e: NoSuchMethodException) {
// isBound 方法不存在(旧版本 Android直接尝试调用
true
} catch (e: Exception) {
true
}
// 如果类型转换失败,使用反射(可能触发 SecurityException
val method: Method = instance.javaClass.getMethod("getActiveNotifications")
method.isAccessible = true
val result = method.invoke(instance)
if (result == null) {
LogUtils.info("NotificationManager: getActiveNotifications returned null")
if (!isBound) {
LogUtils.info("NotificationManager: service is not bound, clearing cache")
serviceInstance = null
return null
}
val notifications = when {
result is Array<*> -> {
result.filterIsInstance<StatusBarNotification>()
}
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
// 直接调用方法获取通知(这里会抛出 SecurityException 如果服务无效)
val result = service.activeNotifications
result?.toList() ?: emptyList()
} catch (e: SecurityException) {
LogUtils.error(e, "NotificationManager: SecurityException - notification listener may not be enabled or instance is invalid")
// 清除缓存的实例,下次尝试重新获取

Loading…
Cancel
Save