|
|
|
|
@ -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")
|
|
|
|
|
// 清除缓存的实例,下次尝试重新获取
|
|
|
|
|
|