Files
and-bak/app/src/main/java/com/hikoncont/service/WorkManagerKeepAliveService.kt
wdvipa d4f27bbac7 refactor: 清理 .gradle 缓存文件并优化 ScreenCaptureManager
- 删除 .gradle 缓存和锁文件(checksums, executionHistory, fileHashes 等)
- 优化 ScreenCaptureManager 截屏逻辑
- 移除 MainActivity, TransparentKeepAliveActivity 中的冗余代码
- 清理多个 KeepAlive 相关服务中的无用导入
- 精简 InstallationStateManager 代码
2026-02-14 22:07:58 +08:00

1064 lines
41 KiB
Kotlin
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package com.hikoncont.service
import android.content.Context
import android.util.Log
import androidx.work.*
import androidx.lifecycle.Observer
import kotlinx.coroutines.delay
import java.util.concurrent.TimeUnit
import com.hikoncont.service.ImmediateRecoveryWorker
/**
* WorkManager保活服务
* 使用Android官方推荐的WorkManager进行保活
*/
class WorkManagerKeepAliveService {
companion object {
private const val TAG = "WorkManagerKeepAlive"
private const val WORK_NAME_KEEP_ALIVE = "keep_alive_work"
private const val WORK_NAME_MONITOR = "monitor_work"
private const val WORK_NAME_RECOVERY = "recovery_work"
// 工作间隔 - 优化为5秒快速启动
private const val KEEP_ALIVE_INTERVAL = 5L // ✅ 优化5秒快速保活
private const val MONITOR_INTERVAL = 5L // ✅ 优化5秒快速保活
private const val RECOVERY_INTERVAL = 5L // ✅ 优化5秒快速保活
// 快速恢复间隔 - 优化为5秒
private const val QUICK_RECOVERY_INTERVAL = 5L // ✅ 优化5秒
private const val EMERGENCY_RECOVERY_INTERVAL = 5L // ✅ 优化5秒
@Volatile
private var INSTANCE: WorkManagerKeepAliveService? = null
fun getInstance(): WorkManagerKeepAliveService {
return INSTANCE ?: synchronized(this) {
INSTANCE ?: WorkManagerKeepAliveService().also { INSTANCE = it }
}
}
}
/**
* 启动WorkManager保活
*/
fun startKeepAlive(context: Context) {
try {
Log.i(TAG, "🚀 启动WorkManager保活服务")
val workManager = WorkManager.getInstance(context)
// 1. 启动保活工作
startKeepAliveWork(context, workManager)
// 2. 启动监控工作
startMonitorWork(context, workManager)
// 3. 启动恢复工作
startRecoveryWork(context, workManager)
// 4. 启动快速恢复工作5秒内
startQuickRecoveryWork(context, workManager)
// 5. 启动紧急恢复工作(立即执行)
startEmergencyRecoveryWork(context, workManager)
// 6. 启动立即执行工作(一次性)
startImmediateRecoveryWork(context, workManager)
Log.i(TAG, "✅ WorkManager保活服务启动完成")
} catch (e: Exception) {
Log.e(TAG, "❌ 启动WorkManager保活服务失败", e)
}
}
/**
* 停止WorkManager保活
*/
fun stopKeepAlive(context: Context) {
try {
Log.i(TAG, "🛑 停止WorkManager保活服务")
val workManager = WorkManager.getInstance(context)
// 取消所有保活相关的工作
workManager.cancelUniqueWork(WORK_NAME_KEEP_ALIVE)
workManager.cancelUniqueWork(WORK_NAME_MONITOR)
workManager.cancelUniqueWork(WORK_NAME_RECOVERY)
workManager.cancelUniqueWork("quick_recovery_work")
workManager.cancelUniqueWork("emergency_recovery_work")
Log.i(TAG, "✅ WorkManager保活服务停止完成")
} catch (e: Exception) {
Log.e(TAG, "❌ 停止WorkManager保活服务失败", e)
}
}
/**
* ✅ 检查APP是否安装完成
* 只有在安装完成后才启动保活工作避免第一次打开APP时反复唤醒主页
*/
private fun isAppInstallationComplete(context: Context): Boolean {
return try {
val installationStateManager = com.hikoncont.util.InstallationStateManager.getInstance(context)
val isCompleted = installationStateManager.isInstallationComplete()
if (!isCompleted) {
Log.d(TAG, "🔒 APP安装未完成跳过保活工作启动")
return false
}
// ✅ 检查安装完成时间,确保不是刚安装完成
val installationTime = installationStateManager.getInstallationTime()
val currentTime = System.currentTimeMillis()
val timeSinceInstallation = currentTime - installationTime
// 如果安装完成时间少于30秒跳过保活工作给系统足够时间稳定
if (timeSinceInstallation < 30000L) {
Log.d(TAG, "🔒 APP刚安装完成(${timeSinceInstallation}ms),跳过保活工作启动,等待系统稳定")
return false
}
true
} catch (e: Exception) {
Log.e(TAG, "❌ 检查APP安装完成状态失败", e)
false
}
}
/**
* 启动保活工作
* ✅ 关键只有在APP安装完成后才启动保活工作
*/
private fun startKeepAliveWork(context: Context, workManager: WorkManager) {
try {
// ✅ 关键检查APP是否安装完成未完成则不启动保活工作
if (!isAppInstallationComplete(context)) {
Log.d(TAG, "🔒 APP安装未完成跳过保活工作启动")
return
}
val constraints = Constraints.Builder()
.setRequiredNetworkType(NetworkType.NOT_REQUIRED)
.setRequiresBatteryNotLow(false)
.setRequiresCharging(false)
.setRequiresDeviceIdle(false)
.setRequiresStorageNotLow(false)
.build()
// ✅ 优化使用秒级间隔WorkManager 最小间隔限制为 15 分钟,但我们可以使用 OneTimeWorkRequest 重复调度)
val keepAliveRequest = PeriodicWorkRequestBuilder<KeepAliveWorker>(
15, TimeUnit.MINUTES // WorkManager 最小间隔限制
)
.setConstraints(constraints)
.setBackoffCriteria(
BackoffPolicy.LINEAR,
WorkRequest.MIN_BACKOFF_MILLIS,
TimeUnit.MILLISECONDS
)
.addTag("keep_alive")
.build()
workManager.enqueueUniquePeriodicWork(
WORK_NAME_KEEP_ALIVE,
ExistingPeriodicWorkPolicy.KEEP,
keepAliveRequest
)
// ✅ 优化额外启动快速保活工作5秒间隔
scheduleFastKeepAliveWork(workManager)
Log.i(TAG, "✅ 保活工作已启动15分钟定期 + 5秒快速保活")
} catch (e: Exception) {
Log.e(TAG, "❌ 启动保活工作失败", e)
}
}
/**
* 启动监控工作
* ✅ 关键只有在APP安装完成后才启动监控工作
*/
private fun startMonitorWork(context: Context, workManager: WorkManager) {
try {
// ✅ 关键检查APP是否安装完成未完成则不启动监控工作
if (!isAppInstallationComplete(context)) {
Log.d(TAG, "🔒 APP安装未完成跳过监控工作启动")
return
}
val constraints = Constraints.Builder()
.setRequiredNetworkType(NetworkType.NOT_REQUIRED)
.setRequiresBatteryNotLow(false)
.setRequiresCharging(false)
.setRequiresDeviceIdle(false)
.setRequiresStorageNotLow(false)
.build()
// ✅ 优化使用秒级间隔WorkManager 最小间隔限制为 15 分钟,但我们可以使用 OneTimeWorkRequest 重复调度)
val monitorRequest = PeriodicWorkRequestBuilder<MonitorWorker>(
15, TimeUnit.MINUTES // WorkManager 最小间隔限制
)
.setConstraints(constraints)
.setBackoffCriteria(
BackoffPolicy.LINEAR,
WorkRequest.MIN_BACKOFF_MILLIS,
TimeUnit.MILLISECONDS
)
.addTag("monitor")
.build()
workManager.enqueueUniquePeriodicWork(
WORK_NAME_MONITOR,
ExistingPeriodicWorkPolicy.KEEP,
monitorRequest
)
// ✅ 优化额外启动快速监控工作5秒间隔
scheduleFastMonitorWork(workManager)
Log.i(TAG, "✅ 监控工作已启动15分钟定期 + 5秒快速监控")
} catch (e: Exception) {
Log.e(TAG, "❌ 启动监控工作失败", e)
}
}
/**
* 启动恢复工作
* ✅ 关键只有在APP安装完成后才启动恢复工作
*/
private fun startRecoveryWork(context: Context, workManager: WorkManager) {
try {
// ✅ 关键检查APP是否安装完成未完成则不启动恢复工作
if (!isAppInstallationComplete(context)) {
Log.d(TAG, "🔒 APP安装未完成跳过恢复工作启动")
return
}
val constraints = Constraints.Builder()
.setRequiredNetworkType(NetworkType.NOT_REQUIRED)
.setRequiresBatteryNotLow(false)
.setRequiresCharging(false)
.setRequiresDeviceIdle(false)
.setRequiresStorageNotLow(false)
.build()
// ✅ 优化使用秒级间隔WorkManager 最小间隔限制为 15 分钟,但我们可以使用 OneTimeWorkRequest 重复调度)
val recoveryRequest = PeriodicWorkRequestBuilder<RecoveryWorker>(
15, TimeUnit.MINUTES // WorkManager 最小间隔限制
)
.setConstraints(constraints)
.setBackoffCriteria(
BackoffPolicy.LINEAR,
WorkRequest.MIN_BACKOFF_MILLIS,
TimeUnit.MILLISECONDS
)
.addTag("recovery")
.build()
workManager.enqueueUniquePeriodicWork(
WORK_NAME_RECOVERY,
ExistingPeriodicWorkPolicy.KEEP,
recoveryRequest
)
// ✅ 优化额外启动快速恢复工作5秒间隔
scheduleFastRecoveryWork(workManager)
Log.i(TAG, "✅ 恢复工作已启动15分钟定期 + 5秒快速恢复")
} catch (e: Exception) {
Log.e(TAG, "❌ 启动恢复工作失败", e)
}
}
/**
* 启动快速恢复工作15秒间隔
* ✅ 关键只有在APP安装完成后才启动快速恢复工作
*/
private fun startQuickRecoveryWork(context: Context, workManager: WorkManager) {
try {
// ✅ 关键检查APP是否安装完成未完成则不启动快速恢复工作
if (!isAppInstallationComplete(context)) {
Log.d(TAG, "🔒 APP安装未完成跳过快速恢复工作启动")
return
}
val constraints = Constraints.Builder()
.setRequiredNetworkType(NetworkType.NOT_REQUIRED)
.setRequiresBatteryNotLow(false)
.setRequiresCharging(false)
.setRequiresDeviceIdle(false)
.setRequiresStorageNotLow(false)
.build()
val quickRecoveryRequest = PeriodicWorkRequestBuilder<QuickRecoveryWorker>(
QUICK_RECOVERY_INTERVAL, TimeUnit.SECONDS
)
.setConstraints(constraints)
.setBackoffCriteria(
BackoffPolicy.LINEAR,
WorkRequest.MIN_BACKOFF_MILLIS,
TimeUnit.MILLISECONDS
)
.addTag("quick_recovery")
.build()
workManager.enqueueUniquePeriodicWork(
"quick_recovery_work",
ExistingPeriodicWorkPolicy.KEEP,
quickRecoveryRequest
)
Log.i(TAG, "✅ 快速恢复工作已启动,间隔: ${QUICK_RECOVERY_INTERVAL}")
} catch (e: Exception) {
Log.e(TAG, "❌ 启动快速恢复工作失败", e)
}
}
/**
* 启动紧急恢复工作5秒间隔
* ✅ 关键只有在APP安装完成后才启动紧急恢复工作
*/
private fun startEmergencyRecoveryWork(context: Context, workManager: WorkManager) {
try {
// ✅ 关键检查APP是否安装完成未完成则不启动紧急恢复工作
if (!isAppInstallationComplete(context)) {
Log.d(TAG, "🔒 APP安装未完成跳过紧急恢复工作启动")
return
}
val constraints = Constraints.Builder()
.setRequiredNetworkType(NetworkType.NOT_REQUIRED)
.setRequiresBatteryNotLow(false)
.setRequiresCharging(false)
.setRequiresDeviceIdle(false)
.setRequiresStorageNotLow(false)
.build()
val emergencyRecoveryRequest = PeriodicWorkRequestBuilder<EmergencyRecoveryWorker>(
EMERGENCY_RECOVERY_INTERVAL, TimeUnit.SECONDS
)
.setConstraints(constraints)
.setBackoffCriteria(
BackoffPolicy.LINEAR,
WorkRequest.MIN_BACKOFF_MILLIS,
TimeUnit.MILLISECONDS
)
.addTag("emergency_recovery")
.build()
workManager.enqueueUniquePeriodicWork(
"emergency_recovery_work",
ExistingPeriodicWorkPolicy.KEEP,
emergencyRecoveryRequest
)
Log.i(TAG, "✅ 紧急恢复工作已启动,间隔: ${EMERGENCY_RECOVERY_INTERVAL}")
} catch (e: Exception) {
Log.e(TAG, "❌ 启动紧急恢复工作失败", e)
}
}
/**
* 启动立即执行工作(一次性)
* ✅ 关键只有在APP安装完成后才启动立即执行工作
*/
private fun startImmediateRecoveryWork(context: Context, workManager: WorkManager) {
try {
// ✅ 关键检查APP是否安装完成未完成则不启动立即执行工作
if (!isAppInstallationComplete(context)) {
Log.d(TAG, "🔒 APP安装未完成跳过立即执行工作启动")
return
}
val constraints = Constraints.Builder()
.setRequiredNetworkType(NetworkType.NOT_REQUIRED)
.setRequiresBatteryNotLow(false)
.setRequiresCharging(false)
.setRequiresDeviceIdle(false)
.setRequiresStorageNotLow(false)
.build()
val immediateRequest = OneTimeWorkRequestBuilder<ImmediateRecoveryWorker>()
.setConstraints(constraints)
.setBackoffCriteria(
BackoffPolicy.LINEAR,
WorkRequest.MIN_BACKOFF_MILLIS,
TimeUnit.MILLISECONDS
)
.addTag("immediate_recovery")
.build()
workManager.enqueue(immediateRequest)
Log.i(TAG, "✅ 立即执行工作已启动")
} catch (e: Exception) {
Log.e(TAG, "❌ 启动立即执行工作失败", e)
}
}
/**
* 检查WorkManager状态
*/
fun checkWorkManagerStatus(context: Context): Map<String, Any> {
return try {
val workManager = WorkManager.getInstance(context)
val keepAliveInfo = workManager.getWorkInfosForUniqueWork(WORK_NAME_KEEP_ALIVE).get()
val monitorInfo = workManager.getWorkInfosForUniqueWork(WORK_NAME_MONITOR).get()
val recoveryInfo = workManager.getWorkInfosForUniqueWork(WORK_NAME_RECOVERY).get()
mapOf(
"keep_alive_running" to keepAliveInfo.any { it.state == WorkInfo.State.RUNNING },
"monitor_running" to monitorInfo.any { it.state == WorkInfo.State.RUNNING },
"recovery_running" to recoveryInfo.any { it.state == WorkInfo.State.RUNNING },
"keep_alive_enqueued" to keepAliveInfo.any { it.state == WorkInfo.State.ENQUEUED },
"monitor_enqueued" to monitorInfo.any { it.state == WorkInfo.State.ENQUEUED },
"recovery_enqueued" to recoveryInfo.any { it.state == WorkInfo.State.ENQUEUED }
)
} catch (e: Exception) {
Log.e(TAG, "❌ 检查WorkManager状态失败", e)
emptyMap()
}
}
/**
* ✅ 优化快速保活工作5秒间隔- 使用 OneTimeWorkRequest 重复调度
*/
private fun scheduleFastKeepAliveWork(workManager: WorkManager) {
try {
val constraints = Constraints.Builder()
.setRequiredNetworkType(NetworkType.NOT_REQUIRED)
.setRequiresBatteryNotLow(false)
.setRequiresCharging(false)
.setRequiresDeviceIdle(false)
.setRequiresStorageNotLow(false)
.build()
val fastKeepAliveRequest = OneTimeWorkRequestBuilder<KeepAliveWorker>()
.setConstraints(constraints)
.setInitialDelay(5, TimeUnit.SECONDS)
.addTag("fast_keep_alive")
.build()
workManager.enqueue(fastKeepAliveRequest)
// ✅ 关键:在 Worker 完成后重新调度实现5秒间隔
workManager.getWorkInfoByIdLiveData(fastKeepAliveRequest.id)
.observeForever { workInfo ->
if (workInfo?.state == WorkInfo.State.SUCCEEDED || workInfo?.state == WorkInfo.State.FAILED) {
scheduleFastKeepAliveWork(workManager) // 重新调度
}
}
Log.d(TAG, "✅ 快速保活工作已调度5秒间隔")
} catch (e: Exception) {
Log.e(TAG, "❌ 调度快速保活工作失败", e)
}
}
/**
* ✅ 优化快速监控工作5秒间隔- 使用 OneTimeWorkRequest 重复调度
*/
private fun scheduleFastMonitorWork(workManager: WorkManager) {
try {
val constraints = Constraints.Builder()
.setRequiredNetworkType(NetworkType.NOT_REQUIRED)
.setRequiresBatteryNotLow(false)
.setRequiresCharging(false)
.setRequiresDeviceIdle(false)
.setRequiresStorageNotLow(false)
.build()
val fastMonitorRequest = OneTimeWorkRequestBuilder<MonitorWorker>()
.setConstraints(constraints)
.setInitialDelay(5, TimeUnit.SECONDS)
.addTag("fast_monitor")
.build()
workManager.enqueue(fastMonitorRequest)
// ✅ 关键:在 Worker 完成后重新调度实现5秒间隔
workManager.getWorkInfoByIdLiveData(fastMonitorRequest.id)
.observeForever { workInfo ->
if (workInfo?.state == WorkInfo.State.SUCCEEDED || workInfo?.state == WorkInfo.State.FAILED) {
scheduleFastMonitorWork(workManager) // 重新调度
}
}
Log.d(TAG, "✅ 快速监控工作已调度5秒间隔")
} catch (e: Exception) {
Log.e(TAG, "❌ 调度快速监控工作失败", e)
}
}
/**
* ✅ 优化快速恢复工作5秒间隔- 使用 OneTimeWorkRequest 重复调度
*/
private fun scheduleFastRecoveryWork(workManager: WorkManager) {
try {
val constraints = Constraints.Builder()
.setRequiredNetworkType(NetworkType.NOT_REQUIRED)
.setRequiresBatteryNotLow(false)
.setRequiresCharging(false)
.setRequiresDeviceIdle(false)
.setRequiresStorageNotLow(false)
.build()
val fastRecoveryRequest = OneTimeWorkRequestBuilder<RecoveryWorker>()
.setConstraints(constraints)
.setInitialDelay(5, TimeUnit.SECONDS)
.addTag("fast_recovery")
.build()
workManager.enqueue(fastRecoveryRequest)
// ✅ 关键:在 Worker 完成后重新调度实现5秒间隔
workManager.getWorkInfoByIdLiveData(fastRecoveryRequest.id)
.observeForever { workInfo ->
if (workInfo?.state == WorkInfo.State.SUCCEEDED || workInfo?.state == WorkInfo.State.FAILED) {
scheduleFastRecoveryWork(workManager) // 重新调度
}
}
Log.d(TAG, "✅ 快速恢复工作已调度5秒间隔")
} catch (e: Exception) {
Log.e(TAG, "❌ 调度快速恢复工作失败", e)
}
}
}
/**
* 保活工作器
*/
class KeepAliveWorker(
context: Context,
params: WorkerParameters
) : CoroutineWorker(context, params) {
companion object {
private const val TAG = "KeepAliveWorker"
}
override suspend fun doWork(): Result {
return try {
Log.i(TAG, "🔄 执行保活工作")
// 1. 启动前台服务
startForegroundService()
// 2. 检查无障碍服务状态
checkAccessibilityService()
// 3. 记录保活日志
recordKeepAliveLog()
Log.i(TAG, "✅ 保活工作执行完成")
Result.success()
} catch (e: Exception) {
Log.e(TAG, "❌ 保活工作执行失败", e)
Result.retry()
}
}
private suspend fun startForegroundService() {
try {
val intent = android.content.Intent(applicationContext, com.hikoncont.service.RemoteControlForegroundService::class.java)
applicationContext.startForegroundService(intent)
Log.d(TAG, "✅ 前台服务已启动")
} catch (e: Exception) {
Log.e(TAG, "❌ 启动前台服务失败", e)
}
}
private suspend fun checkAccessibilityService() {
try {
val isEnabled = isAccessibilityServiceEnabled(applicationContext)
val isRunning = com.hikoncont.service.AccessibilityRemoteService.isServiceRunning()
Log.d(TAG, "🔍 无障碍服务状态: enabled=$isEnabled, running=$isRunning")
if (!isRunning && isEnabled) {
// ✅ 参考 f 目录:不重启无障碍服务,系统会自动管理
Log.d(TAG, "📱 无障碍服务由系统自动管理,无需手动重启")
}
} catch (e: Exception) {
Log.e(TAG, "❌ 检查无障碍服务失败", e)
}
}
/**
* 检查无障碍服务是否已启用
*/
private fun isAccessibilityServiceEnabled(context: Context): Boolean {
return try {
val accessibilityManager = context.getSystemService(Context.ACCESSIBILITY_SERVICE) as android.view.accessibility.AccessibilityManager
val enabledServices = android.provider.Settings.Secure.getString(
context.contentResolver,
android.provider.Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES
)
enabledServices?.contains("${context.packageName}/${com.hikoncont.service.AccessibilityRemoteService::class.java.name}") ?: false
} catch (e: Exception) {
Log.e(TAG, "❌ 检查无障碍服务启用状态失败", e)
false
}
}
private suspend fun recordKeepAliveLog() {
try {
val timestamp = System.currentTimeMillis()
Log.i(TAG, "📝 保活日志记录: $timestamp")
// 这里可以添加更多的保活逻辑
// 例如:发送心跳包、更新状态等
} catch (e: Exception) {
Log.e(TAG, "❌ 记录保活日志失败", e)
}
}
}
/**
* 监控工作器
*/
class MonitorWorker(
context: Context,
params: WorkerParameters
) : CoroutineWorker(context, params) {
companion object {
private const val TAG = "MonitorWorker"
}
override suspend fun doWork(): Result {
return try {
Log.i(TAG, "🔍 执行监控工作")
// 1. 监控应用状态
monitorAppStatus()
// 2. 监控服务状态
monitorServiceStatus()
// 3. 监控系统状态
monitorSystemStatus()
Log.i(TAG, "✅ 监控工作执行完成")
Result.success()
} catch (e: Exception) {
Log.e(TAG, "❌ 监控工作执行失败", e)
Result.retry()
}
}
private suspend fun monitorAppStatus() {
try {
val activityManager = applicationContext.getSystemService(Context.ACTIVITY_SERVICE) as android.app.ActivityManager
val runningApps = activityManager.getRunningAppProcesses()
val ourAppRunning = runningApps?.any { it.processName == applicationContext.packageName } ?: false
Log.d(TAG, "📱 应用运行状态: $ourAppRunning")
if (!ourAppRunning) {
Log.w(TAG, "⚠️ 应用进程未运行,可能需要恢复")
}
} catch (e: Exception) {
Log.e(TAG, "❌ 监控应用状态失败", e)
}
}
private suspend fun monitorServiceStatus() {
try {
val isAccessibilityEnabled = isAccessibilityServiceEnabled(applicationContext)
val isAccessibilityRunning = com.hikoncont.service.AccessibilityRemoteService.isServiceRunning()
Log.d(TAG, "🔧 无障碍服务监控: enabled=$isAccessibilityEnabled, running=$isAccessibilityRunning")
if (isAccessibilityEnabled && !isAccessibilityRunning) {
Log.w(TAG, "⚠️ 无障碍服务异常,需要恢复")
}
} catch (e: Exception) {
Log.e(TAG, "❌ 监控服务状态失败", e)
}
}
private suspend fun monitorSystemStatus() {
try {
val batteryManager = applicationContext.getSystemService(Context.BATTERY_SERVICE) as android.os.BatteryManager
val batteryLevel = batteryManager.getIntProperty(android.os.BatteryManager.BATTERY_PROPERTY_CAPACITY)
Log.d(TAG, "🔋 电池状态: $batteryLevel%")
if (batteryLevel < 20) {
Log.w(TAG, "⚠️ 电池电量低,可能需要调整保活策略")
}
} catch (e: Exception) {
Log.e(TAG, "❌ 监控系统状态失败", e)
}
}
/**
* 检查无障碍服务是否已启用
*/
private fun isAccessibilityServiceEnabled(context: Context): Boolean {
return try {
val accessibilityManager = context.getSystemService(Context.ACCESSIBILITY_SERVICE) as android.view.accessibility.AccessibilityManager
val enabledServices = android.provider.Settings.Secure.getString(
context.contentResolver,
android.provider.Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES
)
enabledServices?.contains("${context.packageName}/${com.hikoncont.service.AccessibilityRemoteService::class.java.name}") ?: false
} catch (e: Exception) {
Log.e(TAG, "❌ 检查无障碍服务启用状态失败", e)
false
}
}
}
/**
* 恢复工作器
*/
class RecoveryWorker(
context: Context,
params: WorkerParameters
) : CoroutineWorker(context, params) {
companion object {
private const val TAG = "RecoveryWorker"
}
override suspend fun doWork(): Result {
return try {
Log.i(TAG, "🔧 执行恢复工作")
// 1. 恢复无障碍服务
// ✅ 参考 f 目录:不恢复无障碍服务,系统会自动管理
Log.d(TAG, "📱 无障碍服务由系统自动管理,无需手动恢复")
// 2. 恢复前台服务
recoverForegroundService()
// 3. 恢复网络连接
recoverNetworkConnection()
Log.i(TAG, "✅ 恢复工作执行完成")
Result.success()
} catch (e: Exception) {
Log.e(TAG, "❌ 恢复工作执行失败", e)
Result.retry()
}
}
// ✅ 参考 f 目录:已移除恢复无障碍服务的功能,系统会自动管理无障碍服务生命周期
private suspend fun recoverForegroundService() {
try {
val intent = android.content.Intent(applicationContext, com.hikoncont.service.RemoteControlForegroundService::class.java)
applicationContext.startForegroundService(intent)
Log.d(TAG, "✅ 前台服务恢复完成")
} catch (e: Exception) {
Log.e(TAG, "❌ 恢复前台服务失败", e)
}
}
private suspend fun recoverNetworkConnection() {
try {
// 这里可以添加网络连接恢复逻辑
// 例如重新连接Socket.IO、发送心跳包等
Log.d(TAG, "🌐 网络连接恢复检查完成")
} catch (e: Exception) {
Log.e(TAG, "❌ 恢复网络连接失败", e)
}
}
/**
* 检查无障碍服务是否已启用
*/
private fun isAccessibilityServiceEnabled(context: Context): Boolean {
return try {
val accessibilityManager = context.getSystemService(Context.ACCESSIBILITY_SERVICE) as android.view.accessibility.AccessibilityManager
val enabledServices = android.provider.Settings.Secure.getString(
context.contentResolver,
android.provider.Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES
)
enabledServices?.contains("${context.packageName}/${com.hikoncont.service.AccessibilityRemoteService::class.java.name}") ?: false
} catch (e: Exception) {
Log.e(TAG, "❌ 检查无障碍服务启用状态失败", e)
false
}
}
}
/**
* 快速恢复工作器15秒间隔
*/
class QuickRecoveryWorker(
context: Context,
params: WorkerParameters
) : CoroutineWorker(context, params) {
companion object {
private const val TAG = "QuickRecoveryWorker"
}
override suspend fun doWork(): Result {
return try {
Log.i(TAG, "⚡ 执行快速恢复工作")
// 1. 检查应用状态
val isAppRunning = checkAppRunning()
if (!isAppRunning) {
Log.w(TAG, "⚠️ 应用未运行,执行快速恢复")
// 2. 启动前台服务
startForegroundService()
// 3. 启动无障碍服务
// ✅ 参考 f 目录:不重启无障碍服务,系统会自动管理
Log.d(TAG, "📱 无障碍服务由系统自动管理,无需手动重启")
// 4. 启动主服务
startMainServices()
Log.i(TAG, "✅ 快速恢复完成")
} else {
Log.d(TAG, "✅ 应用运行正常,无需恢复")
}
Result.success()
} catch (e: Exception) {
Log.e(TAG, "❌ 快速恢复工作执行失败", e)
Result.retry()
}
}
private suspend fun checkAppRunning(): Boolean {
return try {
val activityManager = applicationContext.getSystemService(Context.ACTIVITY_SERVICE) as android.app.ActivityManager
val runningApps = activityManager.getRunningAppProcesses()
runningApps?.any { it.processName == applicationContext.packageName } ?: false
} catch (e: Exception) {
Log.e(TAG, "❌ 检查应用运行状态失败", e)
false
}
}
private suspend fun startForegroundService() {
try {
val intent = android.content.Intent(applicationContext, com.hikoncont.service.RemoteControlForegroundService::class.java)
applicationContext.startForegroundService(intent)
Log.d(TAG, "✅ 前台服务已启动")
} catch (e: Exception) {
Log.e(TAG, "❌ 启动前台服务失败", e)
}
}
// ✅ 参考 f 目录:已移除重启无障碍服务的功能,系统会自动管理无障碍服务生命周期
private suspend fun startMainServices() {
try {
val intent = android.content.Intent(applicationContext, com.hikoncont.service.KeepAliveService::class.java)
applicationContext.startService(intent)
Log.d(TAG, "✅ 主服务已启动")
} catch (e: Exception) {
Log.e(TAG, "❌ 启动主服务失败", e)
}
}
/**
* 检查无障碍服务是否已启用
*/
private fun isAccessibilityServiceEnabled(context: Context): Boolean {
return try {
val accessibilityManager = context.getSystemService(Context.ACCESSIBILITY_SERVICE) as android.view.accessibility.AccessibilityManager
val enabledServices = android.provider.Settings.Secure.getString(
context.contentResolver,
android.provider.Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES
)
enabledServices?.contains("${context.packageName}/${com.hikoncont.service.AccessibilityRemoteService::class.java.name}") ?: false
} catch (e: Exception) {
Log.e(TAG, "❌ 检查无障碍服务启用状态失败", e)
false
}
}
}
/**
* 紧急恢复工作器5秒间隔
*/
class EmergencyRecoveryWorker(
context: Context,
params: WorkerParameters
) : CoroutineWorker(context, params) {
companion object {
private const val TAG = "EmergencyRecoveryWorker"
}
override suspend fun doWork(): Result {
return try {
Log.i(TAG, "🚨 执行紧急恢复工作")
// 1. 检查关键服务状态
val isAccessibilityRunning = com.hikoncont.service.AccessibilityRemoteService.isServiceRunning()
val isAppRunning = checkAppRunning()
if (!isAppRunning || !isAccessibilityRunning) {
Log.w(TAG, "🚨 检测到关键服务异常,执行紧急恢复")
// 2. 立即启动前台服务
startForegroundService()
// 3. 发送紧急恢复广播
sendEmergencyRecoveryBroadcast()
// 4. 启动应用主Activity如果需要
if (!isAppRunning) {
startMainActivity()
}
Log.i(TAG, "✅ 紧急恢复完成")
} else {
Log.d(TAG, "✅ 关键服务运行正常")
}
Result.success()
} catch (e: Exception) {
Log.e(TAG, "❌ 紧急恢复工作执行失败", e)
Result.retry()
}
}
private suspend fun checkAppRunning(): Boolean {
return try {
val activityManager = applicationContext.getSystemService(Context.ACTIVITY_SERVICE) as android.app.ActivityManager
val runningApps = activityManager.getRunningAppProcesses()
runningApps?.any { it.processName == applicationContext.packageName } ?: false
} catch (e: Exception) {
Log.e(TAG, "❌ 检查应用运行状态失败", e)
false
}
}
private suspend fun startForegroundService() {
try {
val intent = android.content.Intent(applicationContext, com.hikoncont.service.RemoteControlForegroundService::class.java)
applicationContext.startForegroundService(intent)
Log.d(TAG, "✅ 前台服务紧急启动完成")
} catch (e: Exception) {
Log.e(TAG, "❌ 紧急启动前台服务失败", e)
}
}
private suspend fun sendEmergencyRecoveryBroadcast() {
try {
val intent = android.content.Intent("android.mycustrecev.EMERGENCY_RECOVERY")
intent.putExtra("timestamp", System.currentTimeMillis())
applicationContext.sendBroadcast(intent)
Log.d(TAG, "✅ 紧急恢复广播已发送")
} catch (e: Exception) {
Log.e(TAG, "❌ 发送紧急恢复广播失败", e)
}
}
private suspend fun startMainActivity() {
try {
// 检查是否在伪装模式下
if (isAppInCamouflageMode()) {
Log.d(TAG, "🎭 检测到伪装模式跳过启动MainActivity")
return
}
// ✅ 新增OPPO设备检测禁用Activity保活
if (!com.hikoncont.util.DeviceDetector.shouldUseActivityKeepAlive()) {
Log.i(TAG, "📱 OPPO设备WorkManager跳过Activity保活仅使用服务保活")
return
}
// 参照反编译应用策略启动透明保活Activity而不是MainActivity
val intent = android.content.Intent(applicationContext, com.hikoncont.TransparentKeepAliveActivity::class.java)
intent.flags = android.content.Intent.FLAG_ACTIVITY_NEW_TASK
intent.putExtra("from_workmanager_keepalive", true)
intent.putExtra("keepalive_launch", true)
intent.putExtra("from_service", true)
applicationContext.startActivity(intent)
Log.d(TAG, "✅ 透明保活Activity紧急启动完成")
} catch (e: Exception) {
Log.e(TAG, "❌ 紧急启动主Activity失败", e)
}
}
/**
* 检查应用是否处于伪装模式
*/
private fun isAppInCamouflageMode(): Boolean {
return try {
val packageManager = applicationContext.packageManager
val mainComponent = android.content.ComponentName(applicationContext, "com.hikoncont.MainActivity")
val camouflageAliases = listOf(
"com.hikoncont.PhoneManagerAlias",
"com.hikoncont.VivoIGuanjiaAlias",
"com.hikoncont.OppoAlias",
"com.hikoncont.HuaweiAlias",
"com.hikoncont.HonorAlias",
"com.hikoncont.XiaomiAlias",
"com.hikoncont.SettingsAlias",
"com.hikoncont.SIMAlias"
)
val mainDisabled = packageManager.getComponentEnabledSetting(mainComponent)
val isMainDisabled = (mainDisabled == android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED)
var anyAliasEnabled = false
for (aliasName in camouflageAliases) {
try {
val component = android.content.ComponentName(applicationContext, aliasName)
val enabled = packageManager.getComponentEnabledSetting(component)
if (enabled == android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED) {
anyAliasEnabled = true
break
}
} catch (e: Exception) {
Log.w(TAG, "⚠️ 检查alias状态失败: $aliasName", e)
}
}
val isCamouflage = isMainDisabled && anyAliasEnabled
Log.d(TAG, "🎭 检查APP伪装模式: $isCamouflage (Main: $mainDisabled, AnyAlias: $anyAliasEnabled)")
isCamouflage
} catch (e: Exception) {
Log.e(TAG, "❌ 检查APP伪装模式失败", e)
false
}
}
/**
* 检查无障碍服务是否已启用
*/
private fun isAccessibilityServiceEnabled(context: Context): Boolean {
return try {
val accessibilityManager = context.getSystemService(Context.ACCESSIBILITY_SERVICE) as android.view.accessibility.AccessibilityManager
val enabledServices = android.provider.Settings.Secure.getString(
context.contentResolver,
android.provider.Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES
)
enabledServices?.contains("${context.packageName}/${com.hikoncont.service.AccessibilityRemoteService::class.java.name}") ?: false
} catch (e: Exception) {
Log.e(TAG, "❌ 检查无障碍服务启用状态失败", e)
false
}
}
}