From 2f223d1d67bfc50169908dc0cd1fd3d907af7859 Mon Sep 17 00:00:00 2001 From: SuperMonster003 Date: Wed, 28 Jan 2026 18:11:45 +0800 Subject: [PATCH] =?UTF-8?q?6.7.0=20-=20Alpha18=20-=20=E8=AF=BB=E5=8F=96?= =?UTF-8?q?=E9=80=9A=E7=9F=A5=E6=9D=83=E9=99=90=E6=94=AF=E6=8C=81=E8=87=AA?= =?UTF-8?q?=E5=8A=A8=E9=87=8D=E8=BF=9E=E6=9C=BA=E5=88=B6=20(requestRebind)?= =?UTF-8?q?=20=E4=BB=A5=E5=A2=9E=E5=BC=BA=E9=80=9A=E7=9F=A5=E7=9B=91?= =?UTF-8?q?=E5=90=AC=E7=9B=B8=E5=85=B3=E5=8A=9F=E8=83=BD=E7=9A=84=E7=A8=B3?= =?UTF-8?q?=E5=AE=9A=E6=80=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .changelog/lang_zh-Hans.json | 3 +- .../NotificationListenerService.kt | 29 +++++++++++++- .../org/autojs/autojs/runtime/api/Events.java | 40 +++++++++++++++++++ .../autojs/service/NotificationService.kt | 2 +- version.properties | 4 +- 5 files changed, 73 insertions(+), 5 deletions(-) diff --git a/.changelog/lang_zh-Hans.json b/.changelog/lang_zh-Hans.json index d786ec46..7ba9a49f 100644 --- a/.changelog/lang_zh-Hans.json +++ b/.changelog/lang_zh-Hans.json @@ -1,7 +1,7 @@ { "$data": { "v6.7.0": { - "released_date": "2026/01/27", + "released_date": "2026/01/28", "feature": [ "插件中心功能, 支持插件的安装/卸载/更新等操作 (入口: 主页抽屉按钮/主页标签页)", "Paddle OCR (PP-OCRv5) 插件, 用于光学字符识别", @@ -138,6 +138,7 @@ "客户端模式连接时支持特殊用途 IPv4 地址 (回环/广播/多播/保留/...) 检测提示", "客户端模式连接时支持连接状态显示及管理 (修正地址/中止连接)", "服务端模式连接时支持显示已建立连接的客户端数量", + "读取通知权限支持自动重连机制 ([requestRebind](https://developer.android.com/reference/android/service/notification/NotificationListenerService#requestRebind(android.content.ComponentName))) 以增强通知监听相关功能的稳定性", "浮动按钮增强后台启动 Activity 的安全性以避免应用崩溃", "浮动按钮 \"更多\" 对话框使用异步加载数据方式提升显示流畅度", "浮动按钮 \"运行脚本\" 对话框增加 \"主页\" 菜单项", diff --git a/app/src/main/java/org/autojs/autojs/core/notification/NotificationListenerService.kt b/app/src/main/java/org/autojs/autojs/core/notification/NotificationListenerService.kt index 5b0ca90d..8f34cbde 100644 --- a/app/src/main/java/org/autojs/autojs/core/notification/NotificationListenerService.kt +++ b/app/src/main/java/org/autojs/autojs/core/notification/NotificationListenerService.kt @@ -1,13 +1,17 @@ package org.autojs.autojs.core.notification +import android.content.ComponentName +import android.content.Context +import android.provider.Settings import android.service.notification.StatusBarNotification import org.autojs.autojs.core.accessibility.NotificationListener import java.util.concurrent.CopyOnWriteArrayList +import android.service.notification.NotificationListenerService as AndroidNotificationListenerService /** * Created by Stardust on Oct 30, 2017. */ -class NotificationListenerService : android.service.notification.NotificationListenerService() { +class NotificationListenerService : AndroidNotificationListenerService() { private val mNotificationListeners = CopyOnWriteArrayList() @@ -44,8 +48,31 @@ class NotificationListenerService : android.service.notification.NotificationLis } companion object { + @JvmStatic var instance: NotificationListenerService? = null private set + + @JvmStatic + fun isNotificationListenerEnabled(context: Context): Boolean { + val enabled = Settings.Secure.getString( + context.contentResolver, + "enabled_notification_listeners", + ) ?: return false + val cn = ComponentName(context, NotificationListenerService::class.java).flattenToString() + return enabled.contains(cn) + } + + @JvmStatic + fun requestRebindIfPossible(context: Context): Boolean { + if (!isNotificationListenerEnabled(context)) return false + return runCatching { + val cn = ComponentName(context, NotificationListenerService::class.java) + requestRebind(cn) + true + }.isSuccess + } + } + } diff --git a/app/src/main/java/org/autojs/autojs/runtime/api/Events.java b/app/src/main/java/org/autojs/autojs/runtime/api/Events.java index ebbcb053..e2a521b8 100644 --- a/app/src/main/java/org/autojs/autojs/runtime/api/Events.java +++ b/app/src/main/java/org/autojs/autojs/runtime/api/Events.java @@ -40,6 +40,8 @@ import java.util.Set; /** * Created by Stardust on Jul 18, 2017. + * Modified by JetBrains AI Assistant (GPT-5.2) as of Jan 28, 2026. + * Modified by SuperMonster003 as of Jan 28, 2026. */ public class Events extends EventEmitter implements OnKeyListener, TouchObserver.OnTouchEventListener, NotificationListener, AccessibilityNotificationObserver.ToastListener, AccessibilityService.Companion.GestureListener { @@ -72,8 +74,14 @@ public class Events extends EventEmitter implements OnKeyListener, TouchObserver private boolean mListeningKey = false; private final Loopers mLoopers; private Handler mHandler; + private boolean mListeningNotification = false; private boolean mListeningToast = false; + + private int mNotificationBindRetryCount = 0; + private static final int NOTIFICATION_BIND_MAX_RETRY = 5; + private static final long NOTIFICATION_BIND_RETRY_DELAY_MS = 400L; + private final ScriptRuntime mScriptRuntime; private volatile boolean mInterceptsAllKey = false; private KeyInterceptor mKeyInterceptor; @@ -237,21 +245,53 @@ public class Events extends EventEmitter implements OnKeyListener, TouchObserver mListeningNotification = true; ensureHandler(); mLoopers.waitWhenIdle(true); + if (NotificationListenerService.getInstance() != null) { NotificationListenerService.getInstance().addListener(this); return; } + + // Permission enabled but service not bound (common on some ROMs): try to rebind automatically. + // zh-CN: 权限已启用但服务未绑定 (在某些 ROM 上常见): 尝试自动重新绑定. + if (NotificationListenerService.isNotificationListenerEnabled(mContext)) { + mNotificationBindRetryCount = 0; + NotificationListenerService.requestRebindIfPossible(mContext); + retryAttachNotificationListener(); + return; + } + + // Permission not enabled: guide user to settings page. + // zh-CN: 权限未启用: 引导用户前往设置页面. Intent intent = new Intent(Settings.ACTION_NOTIFICATION_LISTENER_SETTINGS); IntentUtils.startSafely(intent, mContext); throw new ScriptException(mContext.getString(R.string.text_notification_service_disabled)); } + private void retryAttachNotificationListener() { + if (!mListeningNotification) { + return; + } + if (NotificationListenerService.getInstance() != null) { + NotificationListenerService.getInstance().addListener(this); + return; + } + if (mNotificationBindRetryCount++ >= NOTIFICATION_BIND_MAX_RETRY) { + // Still not bound: last resort, open settings page to let user re-toggle. + // zh-CN: 仍未绑定: 最后的手段, 打开设置页面让用户重新切换. + Intent intent = new Intent(Settings.ACTION_NOTIFICATION_LISTENER_SETTINGS); + IntentUtils.startSafely(intent, mContext); + return; + } + mHandler.postDelayed(this::retryAttachNotificationListener, NOTIFICATION_BIND_RETRY_DELAY_MS); + } + public void removeNotificationObserver() { mAccessibilityBridge.getNotificationObserver().removeNotificationListener(this); if (NotificationListenerService.getInstance() != null) { NotificationListenerService.getInstance().removeListener(this); } mListeningNotification = false; + mNotificationBindRetryCount = 0; if (!mListeningToast) { mLoopers.waitWhenIdle(false); } diff --git a/app/src/main/java/org/autojs/autojs/service/NotificationService.kt b/app/src/main/java/org/autojs/autojs/service/NotificationService.kt index b960e82e..d5fcf816 100644 --- a/app/src/main/java/org/autojs/autojs/service/NotificationService.kt +++ b/app/src/main/java/org/autojs/autojs/service/NotificationService.kt @@ -10,7 +10,7 @@ import org.autojs.autojs.util.IntentUtils.startSafely class NotificationService(override val context: Context) : ServiceItemHelper { override val isRunning: Boolean - get() = NotificationListenerService.instance != null + get() = NotificationListenerService.isNotificationListenerEnabled(context) override fun start(): Boolean = false.also { config() } diff --git a/version.properties b/version.properties index faeb17df..fabc6e75 100644 --- a/version.properties +++ b/version.properties @@ -1,5 +1,5 @@ -#Wed Jan 28 17:23:27 CST 2026 -BUILD_TIME=1769592207672 +#Wed Jan 28 18:09:10 CST 2026 +BUILD_TIME=1769594950154 COMPILE_SDK_VERSION=36 IMAGE_QUANT_CMAKE_VERSION=3.22.1 IMAGE_QUANT_NDK_VERSION=26.1.10909125