测试
This commit is contained in:
@@ -0,0 +1,372 @@
|
||||
package com.hikoncont.service
|
||||
|
||||
import android.app.AlarmManager
|
||||
import android.app.NotificationChannel
|
||||
import android.app.NotificationManager
|
||||
import android.app.PendingIntent
|
||||
import android.content.BroadcastReceiver
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.IntentFilter
|
||||
import android.os.PowerManager
|
||||
import android.util.Log
|
||||
import androidx.core.app.NotificationCompat
|
||||
import kotlinx.coroutines.*
|
||||
|
||||
/**
|
||||
* 后台保活管理器
|
||||
* 专注于后台服务保活,不拉起MainActivity
|
||||
*/
|
||||
class BackgroundKeepAliveManager(private val context: Context) {
|
||||
|
||||
companion object {
|
||||
private const val TAG = "BackgroundKeepAlive"
|
||||
private const val CHECK_INTERVAL = 10000L // 30秒检查一次
|
||||
private const val RESTART_DELAY = 5000L // 5秒后重启
|
||||
}
|
||||
|
||||
private val managerScope = CoroutineScope(Dispatchers.IO + SupervisorJob())
|
||||
private var monitorJob: Job? = null
|
||||
private var wakeLock: PowerManager.WakeLock? = null
|
||||
private var isMonitoring = false
|
||||
|
||||
/**
|
||||
* 开始后台保活监控
|
||||
*/
|
||||
fun startBackgroundKeepAlive() {
|
||||
if (isMonitoring) {
|
||||
Log.w(TAG, "⚠️ 后台保活监控已在运行")
|
||||
return
|
||||
}
|
||||
|
||||
Log.i(TAG, "🛡️ 开始后台保活监控")
|
||||
isMonitoring = true
|
||||
|
||||
// 获取WakeLock
|
||||
acquireWakeLock()
|
||||
|
||||
// 注册广播接收器
|
||||
registerReceivers()
|
||||
|
||||
// 开始监控
|
||||
startMonitoring()
|
||||
|
||||
// 确保前台服务运行
|
||||
ensureForegroundService()
|
||||
}
|
||||
|
||||
/**
|
||||
* 停止后台保活监控
|
||||
*/
|
||||
fun stopBackgroundKeepAlive() {
|
||||
if (!isMonitoring) {
|
||||
return
|
||||
}
|
||||
|
||||
Log.i(TAG, "🛑 停止后台保活监控")
|
||||
isMonitoring = false
|
||||
|
||||
// 取消监控任务
|
||||
monitorJob?.cancel()
|
||||
|
||||
// 释放WakeLock
|
||||
releaseWakeLock()
|
||||
|
||||
// 注销广播接收器
|
||||
unregisterReceivers()
|
||||
|
||||
// 取消协程作用域
|
||||
managerScope.cancel()
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取WakeLock保活
|
||||
*/
|
||||
private fun acquireWakeLock() {
|
||||
try {
|
||||
val powerManager = context.getSystemService(Context.POWER_SERVICE) as PowerManager
|
||||
wakeLock = powerManager.newWakeLock(
|
||||
PowerManager.PARTIAL_WAKE_LOCK,
|
||||
"RemoteControl::BackgroundKeepAlive"
|
||||
)
|
||||
wakeLock?.acquire(24 * 60 * 60 * 1000L) // 24小时
|
||||
Log.i(TAG, "🔋 后台保活WakeLock已获取")
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, "❌ 获取后台保活WakeLock失败", e)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 释放WakeLock
|
||||
*/
|
||||
private fun releaseWakeLock() {
|
||||
try {
|
||||
wakeLock?.release()
|
||||
wakeLock = null
|
||||
Log.i(TAG, "🔋 后台保活WakeLock已释放")
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, "❌ 释放后台保活WakeLock失败", e)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 注册广播接收器
|
||||
*/
|
||||
private fun registerReceivers() {
|
||||
try {
|
||||
val filter = IntentFilter().apply {
|
||||
addAction(Intent.ACTION_SCREEN_ON)
|
||||
addAction(Intent.ACTION_SCREEN_OFF)
|
||||
addAction(Intent.ACTION_USER_PRESENT)
|
||||
// ✅ 参考 f 目录:已移除重启无障碍服务广播监听
|
||||
}
|
||||
context.registerReceiver(backgroundReceiver, filter)
|
||||
Log.i(TAG, "📡 后台保活广播接收器已注册")
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, "❌ 注册后台保活广播接收器失败", e)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 注销广播接收器
|
||||
*/
|
||||
private fun unregisterReceivers() {
|
||||
try {
|
||||
context.unregisterReceiver(backgroundReceiver)
|
||||
Log.i(TAG, "📡 后台保活广播接收器已注销")
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, "❌ 注销后台保活广播接收器失败", e)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 开始监控
|
||||
*/
|
||||
private fun startMonitoring() {
|
||||
monitorJob = managerScope.launch {
|
||||
while (isActive && isMonitoring) {
|
||||
try {
|
||||
checkAndRestartServices()
|
||||
delay(CHECK_INTERVAL)
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, "❌ 后台保活监控过程中发生错误", e)
|
||||
delay(CHECK_INTERVAL)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查并重启服务
|
||||
*/
|
||||
private fun checkAndRestartServices() {
|
||||
try {
|
||||
val accessibilityService = AccessibilityRemoteService.getInstance()
|
||||
|
||||
if (accessibilityService == null) {
|
||||
Log.w(TAG, "⚠️ 检测到AccessibilityService不可用")
|
||||
|
||||
// 检查无障碍服务权限
|
||||
if (!isAccessibilityServiceEnabled()) {
|
||||
Log.w(TAG, "⚠️ 无障碍服务权限已丢失")
|
||||
handleAccessibilityPermissionLost()
|
||||
} else {
|
||||
// ✅ 参考 f 目录:不重启无障碍服务,系统会自动管理
|
||||
Log.d(TAG, "📱 无障碍服务权限正常,系统会自动管理无障碍服务生命周期")
|
||||
}
|
||||
} else {
|
||||
Log.d(TAG, "✅ AccessibilityService运行正常")
|
||||
}
|
||||
|
||||
// 检查前台服务
|
||||
ensureForegroundService()
|
||||
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, "❌ 检查服务状态失败", e)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查无障碍服务是否启用
|
||||
*/
|
||||
private fun isAccessibilityServiceEnabled(): Boolean {
|
||||
return try {
|
||||
val accessibilityEnabled = android.provider.Settings.Secure.getInt(
|
||||
context.contentResolver,
|
||||
android.provider.Settings.Secure.ACCESSIBILITY_ENABLED
|
||||
)
|
||||
|
||||
if (accessibilityEnabled == 1) {
|
||||
val serviceId = "${context.packageName}/${AccessibilityRemoteService::class.java.canonicalName}"
|
||||
val enabledServices = android.provider.Settings.Secure.getString(
|
||||
context.contentResolver,
|
||||
android.provider.Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES
|
||||
)
|
||||
|
||||
enabledServices?.contains(serviceId) == true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, "❌ 检查无障碍服务状态失败", e)
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理无障碍权限丢失(正确方案:提醒用户重新启用)
|
||||
*/
|
||||
private fun handleAccessibilityPermissionLost() {
|
||||
try {
|
||||
Log.w(TAG, "⚠️ 无障碍服务权限丢失,需要用户手动重新启用")
|
||||
|
||||
// 记录到操作日志
|
||||
val service = AccessibilityRemoteService.getInstance()
|
||||
service?.recordOperationLog("ACCESSIBILITY_PERMISSION_LOST", "无障碍服务权限丢失", mapOf(
|
||||
"timestamp" to System.currentTimeMillis(),
|
||||
"backgroundKeepAlive" to true
|
||||
))
|
||||
|
||||
// 无障碍服务被杀死后无法自动重启,需要用户手动重新启用
|
||||
// 通过通知或UI提醒用户
|
||||
showAccessibilityPermissionLostNotification()
|
||||
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, "❌ 处理无障碍服务权限丢失失败", e)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 显示无障碍权限丢失通知
|
||||
*/
|
||||
private fun showAccessibilityPermissionLostNotification() {
|
||||
try {
|
||||
Log.i(TAG, "📱 显示无障碍权限丢失通知")
|
||||
|
||||
// 创建通知渠道
|
||||
val notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
|
||||
val channelId = "accessibility_permission_lost"
|
||||
val channel = NotificationChannel(
|
||||
channelId,
|
||||
"无障碍权限提醒",
|
||||
NotificationManager.IMPORTANCE_HIGH
|
||||
).apply {
|
||||
description = "当无障碍服务权限丢失时提醒用户"
|
||||
enableLights(true)
|
||||
lightColor = android.graphics.Color.RED
|
||||
enableVibration(true)
|
||||
}
|
||||
notificationManager.createNotificationChannel(channel)
|
||||
|
||||
// 创建通知
|
||||
val notification = NotificationCompat.Builder(context, channelId)
|
||||
.setContentTitle("⚠️ 无障碍服务权限丢失")
|
||||
.setContentText("请点击重新启用无障碍服务权限")
|
||||
.setSmallIcon(android.R.drawable.ic_dialog_alert)
|
||||
.setPriority(NotificationCompat.PRIORITY_HIGH)
|
||||
.setAutoCancel(true)
|
||||
.setOngoing(false)
|
||||
.setContentIntent(createAccessibilitySettingsPendingIntent())
|
||||
.build()
|
||||
|
||||
notificationManager.notify(9999, notification)
|
||||
Log.i(TAG, "✅ 无障碍权限丢失通知已显示")
|
||||
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, "❌ 显示无障碍权限丢失通知失败", e)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建无障碍设置页面的PendingIntent
|
||||
*/
|
||||
private fun createAccessibilitySettingsPendingIntent(): PendingIntent {
|
||||
val intent = Intent(android.provider.Settings.ACTION_ACCESSIBILITY_SETTINGS)
|
||||
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
|
||||
return PendingIntent.getActivity(
|
||||
context,
|
||||
9999,
|
||||
intent,
|
||||
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
|
||||
)
|
||||
}
|
||||
|
||||
// ✅ 参考 f 目录:已移除重启无障碍服务的功能,系统会自动管理无障碍服务生命周期
|
||||
|
||||
/**
|
||||
* 确保前台服务运行
|
||||
*/
|
||||
private fun ensureForegroundService() {
|
||||
try {
|
||||
val serviceIntent = Intent(context, RemoteControlForegroundService::class.java)
|
||||
serviceIntent.action = "ENSURE_FOREGROUND"
|
||||
context.startForegroundService(serviceIntent)
|
||||
Log.d(TAG, "✅ 已确保前台服务运行")
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, "❌ 确保前台服务运行失败", e)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 安排服务自恢复
|
||||
*/
|
||||
private fun scheduleServiceRestart() {
|
||||
try {
|
||||
val alarmManager = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager
|
||||
|
||||
val foregroundIntent = Intent(context, RemoteControlForegroundService::class.java).apply {
|
||||
action = "RESTART_SERVICE"
|
||||
}
|
||||
val keepAliveIntent = Intent(context, KeepAliveService::class.java)
|
||||
|
||||
val pendingFlags = (PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE)
|
||||
|
||||
val foregroundPI = PendingIntent.getForegroundService(
|
||||
context,
|
||||
2001,
|
||||
foregroundIntent,
|
||||
pendingFlags
|
||||
)
|
||||
|
||||
val keepAlivePI = PendingIntent.getService(
|
||||
context,
|
||||
2002,
|
||||
keepAliveIntent,
|
||||
pendingFlags
|
||||
)
|
||||
|
||||
val triggerAt = System.currentTimeMillis() + RESTART_DELAY
|
||||
alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, triggerAt, foregroundPI)
|
||||
alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, triggerAt + 500, keepAlivePI)
|
||||
|
||||
Log.i(TAG, "⏰ 已安排服务自恢复")
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, "❌ 安排服务自恢复失败", e)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 后台保活广播接收器
|
||||
*/
|
||||
private val backgroundReceiver = object : BroadcastReceiver() {
|
||||
override fun onReceive(context: Context, intent: Intent) {
|
||||
when (intent.action) {
|
||||
Intent.ACTION_SCREEN_ON -> {
|
||||
Log.d(TAG, "📱 屏幕点亮,检查服务状态")
|
||||
checkAndRestartServices()
|
||||
}
|
||||
Intent.ACTION_SCREEN_OFF -> {
|
||||
Log.d(TAG, "📱 屏幕熄灭,继续后台保活")
|
||||
}
|
||||
Intent.ACTION_USER_PRESENT -> {
|
||||
Log.d(TAG, "👤 用户解锁,检查服务状态")
|
||||
checkAndRestartServices()
|
||||
}
|
||||
"android.mycustrecev.RESTART_ACCESSIBILITY_SERVICE" -> {
|
||||
// ✅ 参考 f 目录:不重启无障碍服务,系统会自动管理
|
||||
Log.d(TAG, "📱 无障碍服务由系统自动管理,无需手动重启")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user