diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index e495bb6..c48d569 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -27,11 +27,6 @@
-
-
-
-
-
@@ -79,11 +74,6 @@
android:resource="@xml/file_paths" />
-
-
-
-
diff --git a/app/src/main/java/com/xiaoqu/watch/app/BootReceiver.kt b/app/src/main/java/com/xiaoqu/watch/app/BootReceiver.kt
index 40e0a74..9a72564 100644
--- a/app/src/main/java/com/xiaoqu/watch/app/BootReceiver.kt
+++ b/app/src/main/java/com/xiaoqu/watch/app/BootReceiver.kt
@@ -3,27 +3,17 @@ package com.xiaoqu.watch.app
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
-import com.xiaoqu.watch.service.MqttAlarmReceiver
-import com.xiaoqu.watch.service.MqttService
import timber.log.Timber
/**
* 开机自启广播接收器
- * 收到 BOOT_COMPLETED 后启动 MQTT 服务 + MainActivity
+ * 收到 BOOT_COMPLETED 后启动 MainActivity(MQTT 在 SplashFragment 中连接)
*/
class BootReceiver : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
if (intent.action == Intent.ACTION_BOOT_COMPLETED) {
- Timber.d("Boot completed, starting MqttService + MainActivity")
-
- // 先启动 MQTT 前台服务(尽早恢复连接)
- MqttService.start(context)
-
- // 启动连接健康检查定时器
- MqttAlarmReceiver.schedule(context)
-
- // 启动主界面
+ Timber.d("Boot completed, launching MainActivity")
val launchIntent = Intent(context, MainActivity::class.java).apply {
addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
}
diff --git a/app/src/main/java/com/xiaoqu/watch/app/MainActivity.kt b/app/src/main/java/com/xiaoqu/watch/app/MainActivity.kt
index 1058729..c5c042b 100644
--- a/app/src/main/java/com/xiaoqu/watch/app/MainActivity.kt
+++ b/app/src/main/java/com/xiaoqu/watch/app/MainActivity.kt
@@ -1,12 +1,7 @@
package com.xiaoqu.watch.app
-import android.content.Intent
import android.content.pm.ActivityInfo
-import android.net.Uri
-import android.os.Build
import android.os.Bundle
-import android.os.PowerManager
-import android.provider.Settings
import android.view.MotionEvent
import android.view.View
import androidx.navigation.findNavController
@@ -98,9 +93,6 @@ class MainActivity : AppCompatActivity() {
// 监听 MQTT type=1 → 处理通知 + 显示横幅
observeMqttMessages()
- // 请求电池优化白名单(绕过 Doze 模式限制)
- requestBatteryWhitelist()
-
Timber.d("MainActivity created")
}
@@ -235,31 +227,6 @@ class MainActivity : AppCompatActivity() {
}
}
- // ===== 电池优化白名单 =====
-
- /**
- * 请求加入电池优化白名单(Doze 模式下允许后台网络访问)
- * 已在白名单中则跳过,避免重复弹窗
- */
- private fun requestBatteryWhitelist() {
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
- val pm = getSystemService(PowerManager::class.java)
- if (!pm.isIgnoringBatteryOptimizations(packageName)) {
- try {
- val intent = Intent(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS).apply {
- data = Uri.parse("package:$packageName")
- }
- startActivity(intent)
- Timber.d("电池白名单: 已请求")
- } catch (e: Exception) {
- Timber.w(e, "电池白名单: 请求失败")
- }
- } else {
- Timber.d("电池白名单: 已在白名单中")
- }
- }
- }
-
// ===== OTA 更新 =====
/** 设置更新弹窗按钮回调 */
diff --git a/app/src/main/java/com/xiaoqu/watch/service/MqttAlarmReceiver.kt b/app/src/main/java/com/xiaoqu/watch/service/MqttAlarmReceiver.kt
deleted file mode 100644
index d2b24f4..0000000
--- a/app/src/main/java/com/xiaoqu/watch/service/MqttAlarmReceiver.kt
+++ /dev/null
@@ -1,76 +0,0 @@
-package com.xiaoqu.watch.service
-
-import android.app.AlarmManager
-import android.app.PendingIntent
-import android.content.BroadcastReceiver
-import android.content.Context
-import android.content.Intent
-import android.os.SystemClock
-import com.xiaoqu.watch.service.manager.MqttManager
-import dagger.hilt.android.AndroidEntryPoint
-import timber.log.Timber
-import javax.inject.Inject
-
-/**
- * MQTT 连接健康检查广播接收器
- *
- * 通过 AlarmManager 定期触发(不强制唤醒,等系统维护窗口),
- * 检查 MQTT 连接状态,断连则重连。
- * 同时确保 MqttService 前台服务存活。
- */
-@AndroidEntryPoint
-class MqttAlarmReceiver : BroadcastReceiver() {
-
- companion object {
- /** 检查间隔:15 分钟(减少唤醒频率,前台服务+电池白名单已足够保活) */
- private const val CHECK_INTERVAL_MS = 15 * 60 * 1000L
-
- /** 启动定时健康检查 */
- fun schedule(context: Context) {
- val alarmManager = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager
- val intent = Intent(context, MqttAlarmReceiver::class.java)
- val pendingIntent = PendingIntent.getBroadcast(
- context, 0, intent,
- PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
- )
-
- // 不唤醒设备,等系统下次维护窗口时执行(省电)
- alarmManager.set(
- AlarmManager.ELAPSED_REALTIME, // 不强制唤醒
- SystemClock.elapsedRealtime() + CHECK_INTERVAL_MS,
- pendingIntent
- )
- Timber.d("MqttAlarm: 已设置 ${CHECK_INTERVAL_MS / 1000}s 后检查")
- }
-
- /** 取消定时检查 */
- fun cancel(context: Context) {
- val alarmManager = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager
- val intent = Intent(context, MqttAlarmReceiver::class.java)
- val pendingIntent = PendingIntent.getBroadcast(
- context, 0, intent,
- PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
- )
- alarmManager.cancel(pendingIntent)
- Timber.d("MqttAlarm: 已取消定时检查")
- }
- }
-
- @Inject lateinit var mqttManager: MqttManager
-
- override fun onReceive(context: Context, intent: Intent) {
- Timber.d("MqttAlarm: 健康检查触发, isConnected=${mqttManager.isConnected}")
-
- // 确保前台服务在运行
- MqttService.start(context)
-
- // MQTT 断连则重连
- if (!mqttManager.isConnected) {
- Timber.w("MqttAlarm: 连接已断开,触发重连")
- mqttManager.connect()
- }
-
- // 重新设置下一次闹钟(setExactAndAllowWhileIdle 是一次性的)
- schedule(context)
- }
-}
diff --git a/app/src/main/java/com/xiaoqu/watch/service/MqttService.kt b/app/src/main/java/com/xiaoqu/watch/service/MqttService.kt
deleted file mode 100644
index 82fd5f6..0000000
--- a/app/src/main/java/com/xiaoqu/watch/service/MqttService.kt
+++ /dev/null
@@ -1,119 +0,0 @@
-package com.xiaoqu.watch.service
-
-import android.app.Notification
-import android.app.NotificationChannel
-import android.app.NotificationManager
-import android.app.Service
-import android.content.Context
-import android.content.Intent
-import android.os.Build
-import android.os.IBinder
-import com.xiaoqu.watch.R
-import com.xiaoqu.watch.service.manager.MqttManager
-import dagger.hilt.android.AndroidEntryPoint
-import timber.log.Timber
-import javax.inject.Inject
-
-/**
- * MQTT 前台服务
- *
- * 保持 MQTT 连接在息屏/Doze 模式下不被系统杀死。
- * 通过 startForegroundService() 启动,显示常驻通知。
- * 不持有永久 WakeLock(省电),依赖:
- * - 前台服务:防止进程被杀
- * - 电池白名单:绕过 Doze 网络限制
- * - Paho 库内置心跳机制:自动维护连接
- * - AlarmManager 健康检查:兜底重连
- */
-@AndroidEntryPoint
-class MqttService : Service() {
-
- companion object {
- /** 通知渠道 ID */
- private const val CHANNEL_ID = "mqtt_service"
- /** 前台通知 ID */
- private const val NOTIFICATION_ID = 1
-
- /** 启动服务 */
- fun start(context: Context) {
- val intent = Intent(context, MqttService::class.java)
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
- context.startForegroundService(intent)
- } else {
- context.startService(intent)
- }
- }
-
- /** 停止服务 */
- fun stop(context: Context) {
- context.stopService(Intent(context, MqttService::class.java))
- }
- }
-
- @Inject lateinit var mqttManager: MqttManager
-
- override fun onCreate() {
- super.onCreate()
- Timber.d("MqttService: onCreate")
-
- // 创建通知渠道
- createNotificationChannel()
-
- // 启动前台服务(必须在 5 秒内调用,否则 ANR)
- startForeground(NOTIFICATION_ID, buildNotification())
-
- // 连接 MQTT(Paho 库内部会管理自己的心跳和重连)
- mqttManager.connect()
- }
-
- override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
- Timber.d("MqttService: onStartCommand")
- // 如果连接断了,重新连接
- if (!mqttManager.isConnected) {
- mqttManager.connect()
- }
- // 被杀后自动重启
- return START_STICKY
- }
-
- override fun onDestroy() {
- super.onDestroy()
- Timber.d("MqttService: onDestroy")
- mqttManager.disconnect()
- }
-
- override fun onBind(intent: Intent?): IBinder? = null
-
- /** 创建通知渠道(Android 8.0+) */
- private fun createNotificationChannel() {
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
- val channel = NotificationChannel(
- CHANNEL_ID,
- "消息连接",
- NotificationManager.IMPORTANCE_LOW // 低优先级,不发声不振动
- ).apply {
- description = "保持消息连接在线"
- setShowBadge(false)
- }
- val nm = getSystemService(NotificationManager::class.java)
- nm.createNotificationChannel(channel)
- }
- }
-
- /** 构建前台通知(常驻,低优先级) */
- private fun buildNotification(): Notification {
- val builder = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
- Notification.Builder(this, CHANNEL_ID)
- } else {
- @Suppress("DEPRECATION")
- Notification.Builder(this)
- }
- return builder
- .setSmallIcon(R.mipmap.ic_launcher)
- .setContentTitle("小趣智清洁")
- .setContentText("消息连接中")
- .setOngoing(true)
- .build()
- }
-
-}
diff --git a/app/src/main/java/com/xiaoqu/watch/ui/common/SplashFragment.kt b/app/src/main/java/com/xiaoqu/watch/ui/common/SplashFragment.kt
index ea82b15..130b84d 100644
--- a/app/src/main/java/com/xiaoqu/watch/ui/common/SplashFragment.kt
+++ b/app/src/main/java/com/xiaoqu/watch/ui/common/SplashFragment.kt
@@ -13,8 +13,6 @@ import com.xiaoqu.watch.data.prefs.UserPrefs
import com.xiaoqu.watch.network.ApiResult
import com.xiaoqu.watch.network.api.CommonApi
import com.xiaoqu.watch.network.safeApiCall
-import com.xiaoqu.watch.service.MqttAlarmReceiver
-import com.xiaoqu.watch.service.MqttService
import com.xiaoqu.watch.service.manager.MqttManager
import com.xiaoqu.watch.util.DeviceUtil
import dagger.hilt.android.AndroidEntryPoint
@@ -49,13 +47,10 @@ class SplashFragment : Fragment() {
// 1. 初始化设备信息(首次启动时写入 SP)
initDevicePrefs()
- // 2. 启动 MQTT 前台服务(保持息屏后连接存活)
- MqttService.start(requireContext())
+ // 2. 连接 MQTT(定制 ROM + Launcher 应用,系统不会杀进程)
+ mqttManager.connect()
- // 3. 启动连接健康检查定时器(Doze 模式下定期检查)
- MqttAlarmReceiver.schedule(requireContext())
-
- // 4. 检查绑定状态并导航
+ // 3. 检查绑定状态并导航
checkBindStatus()
}