1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174
| 保活的核心思路
Android 限制后台运行,但以下机制能最大限度保活:
启动一个前台服务(Foreground Service) 系统认为“前台服务 = 用户主动任务”,不会轻易杀。
应用被杀后,可通过 BOOT_COMPLETED 或 WORKMANAGER 自动重启
创建service /** * 前台保活服务 + 告警通知 */ class KeepAliveService : Service() {
override fun onCreate() { super.onCreate() startForegroundNotification() }
private fun startForegroundNotification() { val channelId = "keep_alive_channel" val channelName = "后台保活服务"
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { val channel = NotificationChannel( channelId, channelName, NotificationManager.IMPORTANCE_LOW ) getSystemService(NotificationManager::class.java)?.createNotificationChannel(channel) }
val notification = NotificationCompat.Builder(this, channelId) .setContentTitle("应用后台运行中") .setContentText("保持应用活动") .setSmallIcon(R.mipmap.logo) // 替换成你的图标 .setOngoing(true) .build()
startForeground(1001, notification) }
override fun onBind(intent: Intent?): IBinder? = null override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { // 保活策略 return START_STICKY } companion object { /** * 启动前台保活服务 */ fun start(context: Context) { val intent = Intent(context, KeepAliveService::class.java) if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { context.startForegroundService(intent) } else { context.startService(intent) } }
/** * 发送告警通知 */ fun showAlarmNotification(context: Context, title: String, content: String) { // Android 13+ 需要检查通知权限 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { if (ContextCompat.checkSelfPermission(context, Manifest.permission.POST_NOTIFICATIONS) != PackageManager.PERMISSION_GRANTED ) { // 没权限,直接返回 return } }
val channelId = "alarm_channel"
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { val channel = NotificationChannel( channelId, "告警通知", NotificationManager.IMPORTANCE_HIGH ) context.getSystemService(NotificationManager::class.java)?.createNotificationChannel(channel) }
// 创建点击通知跳转的 Intent val intent = Intent(context, NotificationActivity::class.java) // 替换为你要跳转的 Activity intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP val pendingIntent = PendingIntent.getActivity( context, 0, intent, if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) PendingIntent.FLAG_IMMUTABLE else 0 )
val notification = NotificationCompat.Builder(context, channelId) .setContentTitle(title) .setContentText(content) .setSmallIcon(R.mipmap.logo) .setAutoCancel(true) .setPriority(NotificationCompat.PRIORITY_HIGH) .setContentIntent(pendingIntent) .build()
NotificationManagerCompat.from(context).notify(System.currentTimeMillis().toInt(), notification) } } }
添加权限 <uses-permission android:name="android.permission.POST_NOTIFICATIONS" /> <uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
配置service <service android:name=".service.KeepAliveService" android:enabled="true" android:exported="false" android:foregroundServiceType="connectedDevice|dataSync" />
启动服务 // 启动前台保活服务 KeepAliveService.start(this) KeepAliveService.showAlarmNotification( this@CottonApplication, "", "" )
进阶保活方案
开机自启
<receiver android:name=".receiver.BootReceiver" android:enabled="true" android:exported="true"> <intent-filter> <action android:name="android.intent.action.BOOT_COMPLETED" /> </intent-filter> </receiver>
class BootReceiver : BroadcastReceiver() { override fun onReceive(context: Context, intent: Intent) { if (intent.action == Intent.ACTION_BOOT_COMPLETED) { val serviceIntent = Intent(context, MqttForegroundService::class.java) if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { context.startForegroundService(serviceIntent) } else { context.startService(serviceIntent) } } } }
自恢复(守护)
可以每隔一段时间用 WorkManager 检查服务是否存活。
若服务被杀死则自动重启。
应用白名单
提醒用户在系统设置中“电池优化”里将你的应用加入白名单。
例如华为/小米设备,可在首次启动时引导用户开启。
|