телефон постоянно убивает фоновые службы
телефон постоянно останавливает фоновые службы допустим
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)
}
}
как можно это обойти, особенно это прям заметно на редми, если вырубить экран, спустя какое то время приложение постепенно останавливает все фоновые службы, в