AlarmManager с BroadcastReceiver не отправляет уведомления при перелистывании приложения (Android 13+, Jetpack Compose)Android

Форум для тех, кто программирует под Android
Ответить
Anonymous
 AlarmManager с BroadcastReceiver не отправляет уведомления при перелистывании приложения (Android 13+, Jetpack Compose)

Сообщение Anonymous »

Описание проблемы
Я создаю приложение для отслеживания питания, в котором пользователи должны получать напоминание в определенное время (например, 15:00 и 20:00), если они не записывали никаких данных за текущий день.
Проблема: Уведомления работают отлично, пока приложение находится на переднем плане или в фоновом режиме (свернуто). Однако, как только приложение удаляется (удаляется) из списка последних приложений, AlarmManager никогда не запускает BroadcastReceiver, или приемник закрывается до того, как сможет отобразить уведомление.

Среда
  • Целевой SDK: 35 (Android) 15)
  • Минимальный SDK: 24
  • UI Framework: Jetpack Compose
  • Внедрение зависимостей: Hilt
  • Тестовое устройство: Физическое устройство под управлением Android 14
Что у меня есть пробовал до сих пор:
  • WorkManager: Сначала пробовал OneTimeWorkRequest с setInitialDelay, но результат был слишком неточным (задержка на 10–30 минут).
  • AlarmManager (Exact): переключился на AlarmManager.setExactAndAllowWhileIdle, чтобы тревога сработала даже в спящем режиме.
  • goAsync() в приемнике: реализован goAsync() в BroadcastReceiver, чтобы позволить области Coroutine выполнять быструю проверку (локальные SharedPreferences) перед завершением процесса.
  • Локальный кеш: Вместо выполнения сетевого вызова (Supabase) в фоновом режиме я теперь сохраняю «last_tracked_date» в SharedPreferences всякий раз, когда пользователь регистрирует еду. Приемник проверяет только это локальное значение.
  • Разрешения: Добавлены POST_NOTIFICATIONS, SCHEDULE_EXACT_ALARM, USE_EXACT_ALARM и RECEIVE_BOOT_COMPLETED в манифест.
  • Оптимизация батареи: Оптимизация батареи отключена вручную для приложение во время тестирования.
Текущая реализация
1. Регистрация манифеста: 2. Логика планирования:

Код: Выделить всё

val intent = Intent(context, ReminderReceiver::class.java)
val pendingIntent = PendingIntent.getBroadcast(
context, requestCode, intent,
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
)

if (alarmManager.canScheduleExactAlarms()) {
alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, calendar.timeInMillis, pendingIntent)
}
3. Логика приемника:

Код: Выделить всё

class ReminderReceiver : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
val pendingResult = goAsync()
CoroutineScope(Dispatchers.IO).launch {
try {
// Check local SharedPreferences
val hasTracked = settingsManager.hasTrackedToday()
if (!hasTracked) {
showNotification(context)
}
} finally {
pendingResult.finish()
}
}
}
}
Как повторить
  • Откройте приложение и установите напоминание на 2 минуты в будущем через пользовательский интерфейс.
  • Не регистрируйте еду (поэтому напоминание должно сработать).
  • Принудительно закройте приложение или проведите пальцем по нему из списка недавних задач.
  • Подождите, пока пройдет время -> Результат: уведомление не появляется.
  • Если приложение остается открытым, уведомление появляется точно вовремя.
Вопрос
Существует ли какое-либо современное ограничение Android (особенно на устройствах Samsung/Pixel), которое не позволяет AlarmManager запускать BroadcastReceiver, если пользователь вручную закрыл приложение? Поскольку это приложение связано со здоровьем, точное время имеет решающее значение. Есть ли лучшие альтернативы goAsync() для проверки в течение 1 секунды после срабатывания сигнализации?

Инструкции для пользователя:
  • Скопируйте содержимое выше.
  • Перейдите к переполнению стека.
  • Отметьте его тегами: android, kotlin, android-alarmmanager, Broadcastreceiver, jetpack-compose.


Подробнее здесь: https://stackoverflow.com/questions/798 ... -is-swiped
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Android»