2026-02-11 16:59:49 +08:00
|
|
|
|
package com.hikoncont.service
|
|
|
|
|
|
|
|
|
|
|
|
import android.app.*
|
|
|
|
|
|
import android.content.Context
|
|
|
|
|
|
import android.content.Intent
|
|
|
|
|
|
import android.os.IBinder
|
|
|
|
|
|
import android.os.PowerManager
|
|
|
|
|
|
import android.util.Log
|
|
|
|
|
|
import androidx.core.app.NotificationCompat
|
|
|
|
|
|
import kotlinx.coroutines.*
|
|
|
|
|
|
import java.io.File
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 进程监控服务
|
|
|
|
|
|
* 监控主进程状态,在进程被杀死时立即启动恢复机制
|
|
|
|
|
|
*/
|
|
|
|
|
|
class ProcessMonitorService : Service() {
|
|
|
|
|
|
|
|
|
|
|
|
companion object {
|
|
|
|
|
|
private const val TAG = "ProcessMonitorService"
|
|
|
|
|
|
private const val CHECK_INTERVAL = 1000L // ✅ 激进:1秒检查一次进程状态
|
|
|
|
|
|
private const val NOTIFICATION_ID = 9999
|
|
|
|
|
|
private const val CHANNEL_ID = "process_monitor_channel"
|
|
|
|
|
|
|
|
|
|
|
|
// 进程状态文件路径
|
|
|
|
|
|
private const val PROCESS_STATUS_FILE = "process_status.txt"
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private val serviceScope = CoroutineScope(Dispatchers.IO + SupervisorJob())
|
|
|
|
|
|
private var monitorJob: Job? = null
|
|
|
|
|
|
private var wakeLock: PowerManager.WakeLock? = null
|
|
|
|
|
|
private var notificationManager: NotificationManager? = null
|
|
|
|
|
|
private var isMonitoring = false
|
|
|
|
|
|
|
|
|
|
|
|
override fun onCreate() {
|
|
|
|
|
|
super.onCreate()
|
|
|
|
|
|
Log.i(TAG, "🔍 进程监控服务创建")
|
|
|
|
|
|
|
|
|
|
|
|
// 初始化通知管理器
|
|
|
|
|
|
initNotificationManager()
|
|
|
|
|
|
|
|
|
|
|
|
// 获取WakeLock保活
|
|
|
|
|
|
acquireWakeLock()
|
|
|
|
|
|
|
|
|
|
|
|
// 启动前台服务
|
|
|
|
|
|
startForegroundService()
|
|
|
|
|
|
|
|
|
|
|
|
// 开始监控
|
|
|
|
|
|
startMonitoring()
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
|
|
|
|
|
|
Log.i(TAG, "🔍 进程监控服务启动命令")
|
|
|
|
|
|
return START_STICKY
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
override fun onBind(intent: Intent?): IBinder? {
|
|
|
|
|
|
return null
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
override fun onDestroy() {
|
|
|
|
|
|
Log.i(TAG, "🛑 进程监控服务销毁")
|
|
|
|
|
|
|
|
|
|
|
|
// 释放WakeLock
|
|
|
|
|
|
releaseWakeLock()
|
|
|
|
|
|
|
|
|
|
|
|
// 停止监控
|
|
|
|
|
|
stopMonitoring()
|
|
|
|
|
|
|
|
|
|
|
|
// 启动激进恢复机制
|
|
|
|
|
|
scheduleAggressiveRecovery()
|
|
|
|
|
|
|
|
|
|
|
|
serviceScope.cancel()
|
|
|
|
|
|
super.onDestroy()
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
override fun onTaskRemoved(rootIntent: Intent?) {
|
|
|
|
|
|
Log.w(TAG, "🧹 检测到任务被移除(onTaskRemoved),启动激进恢复")
|
|
|
|
|
|
scheduleAggressiveRecovery()
|
|
|
|
|
|
super.onTaskRemoved(rootIntent)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 初始化通知管理器
|
|
|
|
|
|
*/
|
|
|
|
|
|
private fun initNotificationManager() {
|
|
|
|
|
|
try {
|
|
|
|
|
|
notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
|
|
|
|
|
|
|
|
|
|
|
|
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
|
|
|
|
|
|
val channel = NotificationChannel(
|
|
|
|
|
|
CHANNEL_ID,
|
|
|
|
|
|
"进程监控服务",
|
|
|
|
|
|
NotificationManager.IMPORTANCE_LOW
|
|
|
|
|
|
).apply {
|
|
|
|
|
|
description = "监控主进程状态"
|
|
|
|
|
|
setShowBadge(false)
|
|
|
|
|
|
}
|
|
|
|
|
|
notificationManager?.createNotificationChannel(channel)
|
|
|
|
|
|
}
|
|
|
|
|
|
} catch (e: Exception) {
|
|
|
|
|
|
Log.e(TAG, "❌ 初始化通知管理器失败", e)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 启动前台服务
|
|
|
|
|
|
*/
|
|
|
|
|
|
private fun startForegroundService() {
|
|
|
|
|
|
try {
|
|
|
|
|
|
val notification = NotificationCompat.Builder(this, CHANNEL_ID)
|
|
|
|
|
|
.setContentTitle("进程监控服务")
|
|
|
|
|
|
.setContentText("正在监控主进程状态")
|
|
|
|
|
|
.setSmallIcon(android.R.drawable.ic_dialog_info)
|
|
|
|
|
|
.setOngoing(true)
|
|
|
|
|
|
.setPriority(NotificationCompat.PRIORITY_LOW)
|
|
|
|
|
|
.build()
|
|
|
|
|
|
|
|
|
|
|
|
startForeground(NOTIFICATION_ID, notification)
|
|
|
|
|
|
Log.i(TAG, "✅ 前台服务已启动")
|
|
|
|
|
|
} catch (e: Exception) {
|
|
|
|
|
|
Log.e(TAG, "❌ 启动前台服务失败", e)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 获取WakeLock保活
|
|
|
|
|
|
*/
|
|
|
|
|
|
private fun acquireWakeLock() {
|
|
|
|
|
|
try {
|
|
|
|
|
|
val powerManager = getSystemService(Context.POWER_SERVICE) as PowerManager
|
|
|
|
|
|
wakeLock = powerManager.newWakeLock(
|
|
|
|
|
|
PowerManager.PARTIAL_WAKE_LOCK,
|
|
|
|
|
|
"RemoteControl::ProcessMonitorService"
|
|
|
|
|
|
)
|
|
|
|
|
|
wakeLock?.acquire(24 * 60 * 60 * 1000L) // 24小时
|
|
|
|
|
|
Log.i(TAG, "🔋 ProcessMonitorService WakeLock已获取")
|
|
|
|
|
|
} catch (e: Exception) {
|
|
|
|
|
|
Log.e(TAG, "❌ 获取ProcessMonitorService WakeLock失败", e)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 释放WakeLock
|
|
|
|
|
|
*/
|
|
|
|
|
|
private fun releaseWakeLock() {
|
|
|
|
|
|
try {
|
|
|
|
|
|
wakeLock?.let {
|
|
|
|
|
|
if (it.isHeld) {
|
|
|
|
|
|
it.release()
|
|
|
|
|
|
Log.i(TAG, "🔋 ProcessMonitorService WakeLock已释放")
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
} catch (e: Exception) {
|
|
|
|
|
|
Log.e(TAG, "❌ 释放ProcessMonitorService WakeLock失败", e)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 开始监控
|
|
|
|
|
|
*/
|
|
|
|
|
|
private fun startMonitoring() {
|
|
|
|
|
|
if (isMonitoring) {
|
|
|
|
|
|
Log.w(TAG, "⚠️ 进程监控已在运行")
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
isMonitoring = true
|
|
|
|
|
|
Log.i(TAG, "🔍 开始进程状态监控")
|
|
|
|
|
|
|
|
|
|
|
|
monitorJob = serviceScope.launch {
|
|
|
|
|
|
while (isActive && isMonitoring) {
|
|
|
|
|
|
try {
|
|
|
|
|
|
// 更新进程状态文件
|
|
|
|
|
|
updateProcessStatus()
|
|
|
|
|
|
|
|
|
|
|
|
// 检查主进程是否存活
|
|
|
|
|
|
if (!isMainProcessAlive()) {
|
|
|
|
|
|
Log.w(TAG, "⚠️ 检测到主进程死亡,启动恢复机制")
|
|
|
|
|
|
scheduleAggressiveRecovery()
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
delay(CHECK_INTERVAL)
|
|
|
|
|
|
} catch (e: Exception) {
|
|
|
|
|
|
Log.e(TAG, "❌ 进程监控异常", e)
|
|
|
|
|
|
delay(CHECK_INTERVAL)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 停止监控
|
|
|
|
|
|
*/
|
|
|
|
|
|
private fun stopMonitoring() {
|
|
|
|
|
|
isMonitoring = false
|
|
|
|
|
|
monitorJob?.cancel()
|
|
|
|
|
|
Log.i(TAG, "🛑 进程监控已停止")
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 更新进程状态文件
|
|
|
|
|
|
*/
|
|
|
|
|
|
private fun updateProcessStatus() {
|
|
|
|
|
|
try {
|
|
|
|
|
|
val statusFile = File(filesDir, PROCESS_STATUS_FILE)
|
|
|
|
|
|
val currentTime = System.currentTimeMillis()
|
|
|
|
|
|
val pid = android.os.Process.myPid()
|
|
|
|
|
|
|
|
|
|
|
|
statusFile.writeText("$pid:$currentTime")
|
|
|
|
|
|
} catch (e: Exception) {
|
|
|
|
|
|
Log.e(TAG, "❌ 更新进程状态文件失败", e)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 检查主进程是否存活
|
|
|
|
|
|
*/
|
|
|
|
|
|
private fun isMainProcessAlive(): Boolean {
|
|
|
|
|
|
return try {
|
|
|
|
|
|
val statusFile = File(filesDir, PROCESS_STATUS_FILE)
|
|
|
|
|
|
if (!statusFile.exists()) {
|
|
|
|
|
|
return false
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
val content = statusFile.readText()
|
|
|
|
|
|
val parts = content.split(":")
|
|
|
|
|
|
if (parts.size != 2) {
|
|
|
|
|
|
return false
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
val timestamp = parts[1].toLongOrNull() ?: return false
|
|
|
|
|
|
val currentTime = System.currentTimeMillis()
|
|
|
|
|
|
|
|
|
|
|
|
// 如果状态文件超过5秒没有更新,认为进程死亡
|
|
|
|
|
|
(currentTime - timestamp) < 5000
|
|
|
|
|
|
} catch (e: Exception) {
|
|
|
|
|
|
Log.e(TAG, "❌ 检查主进程状态失败", e)
|
|
|
|
|
|
false
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 启动激进恢复机制
|
|
|
|
|
|
*/
|
|
|
|
|
|
private fun scheduleAggressiveRecovery() {
|
|
|
|
|
|
try {
|
|
|
|
|
|
Log.i(TAG, "🚀 启动激进恢复机制")
|
|
|
|
|
|
|
|
|
|
|
|
// 立即启动前台服务
|
|
|
|
|
|
val rcfsIntent = Intent(this, RemoteControlForegroundService::class.java).apply {
|
|
|
|
|
|
action = "RESTART_SERVICE"
|
|
|
|
|
|
}
|
|
|
|
|
|
startForegroundService(rcfsIntent)
|
|
|
|
|
|
|
|
|
|
|
|
// 立即启动保活服务
|
|
|
|
|
|
val keepAliveIntent = Intent(this, KeepAliveService::class.java)
|
|
|
|
|
|
startService(keepAliveIntent)
|
|
|
|
|
|
|
|
|
|
|
|
// 使用AlarmManager安排延迟恢复
|
|
|
|
|
|
val alarmManager = getSystemService(Context.ALARM_SERVICE) as AlarmManager
|
|
|
|
|
|
|
|
|
|
|
|
val rcfsPI = PendingIntent.getForegroundService(
|
|
|
|
|
|
this,
|
|
|
|
|
|
(System.currentTimeMillis() % 10000).toInt(),
|
|
|
|
|
|
rcfsIntent,
|
|
|
|
|
|
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
val keepAlivePI = PendingIntent.getService(
|
|
|
|
|
|
this,
|
|
|
|
|
|
(System.currentTimeMillis() % 10000).toInt() + 1,
|
|
|
|
|
|
keepAliveIntent,
|
|
|
|
|
|
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
val triggerAt = System.currentTimeMillis() + 50 // 50ms延迟
|
2026-03-03 22:16:30 +08:00
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
|
alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, triggerAt, rcfsPI)
|
|
|
|
|
|
} catch (security: SecurityException) {
|
|
|
|
|
|
Log.w(TAG, "Exact alarm denied for process monitor RCFS restart, fallback to inexact wake alarm", security)
|
|
|
|
|
|
alarmManager.setAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, triggerAt, rcfsPI)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
|
alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, triggerAt + 50, keepAlivePI)
|
|
|
|
|
|
} catch (security: SecurityException) {
|
|
|
|
|
|
Log.w(TAG, "Exact alarm denied for process monitor KeepAlive restart, fallback to inexact wake alarm", security)
|
|
|
|
|
|
alarmManager.setAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, triggerAt + 50, keepAlivePI)
|
|
|
|
|
|
}
|
2026-02-11 16:59:49 +08:00
|
|
|
|
|
|
|
|
|
|
Log.i(TAG, "✅ 激进恢复机制已启动")
|
|
|
|
|
|
} catch (e: Exception) {
|
|
|
|
|
|
Log.e(TAG, "❌ 启动激进恢复机制失败", e)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|