From 9934938dac5afb5a1a690037c7ff5418f246351a Mon Sep 17 00:00:00 2001 From: mojo Date: Wed, 5 Nov 2025 10:45:43 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E6=94=B9=E8=BF=9B=20NotificationManager?= =?UTF-8?q?=20=E6=9C=8D=E5=8A=A1=E5=AE=9E=E4=BE=8B=E8=8E=B7=E5=8F=96?= =?UTF-8?q?=E5=92=8C=E9=AA=8C=E8=AF=81=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/example/pin/NotificationManager.kt | 122 ++++++++++++------ 1 file changed, 82 insertions(+), 40 deletions(-) diff --git a/lib/src/main/java/com/example/pin/NotificationManager.kt b/lib/src/main/java/com/example/pin/NotificationManager.kt index 1521b11..2dc126f 100644 --- a/lib/src/main/java/com/example/pin/NotificationManager.kt +++ b/lib/src/main/java/com/example/pin/NotificationManager.kt @@ -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? { + 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() - } - result is List<*> -> { - result.filterIsInstance() - } - 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") // 清除缓存的实例,下次尝试重新获取