Задержка уведомления Android Kotlin

Я хочу установить уведомление на каждый день, в выбранные пользователем часы и минуты, но проблема в том, что иногда оно получает уведомление вовремя, а иногда задерживается с задержкой в ​​10, 20, 30, 40 секунд, а также проверьте, что сегодня время прошло или нет; если да, я не хочу показывать уведомление

Функция установки уведомлений

private fun scheduleNotification(context: Context, hour: Int, minute: Int) {
    val alarmManager = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager
    val intent = Intent(context, AlarmReceiver::class.java)
    val pendingIntent = PendingIntent.getBroadcast(
        context,
        0,
        intent,
        PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
    )

    val calendar = Calendar.getInstance().apply {
        timeInMillis = System.currentTimeMillis()
        set(Calendar.HOUR_OF_DAY, hour)
        set(Calendar.MINUTE, minute)
        set(Calendar.SECOND, 0)
        set(Calendar.MILLISECOND, 0)
        if (before(Calendar.getInstance())) {
            add(Calendar.DATE, 1)
        }
    }
    alarmManager.cancel(pendingIntent)

    alarmManager.setExact(
        AlarmManager.RTC_WAKEUP,
        calendar.timeInMillis,
        pendingIntent
    )

    alarmManager.setRepeating(
        AlarmManager.RTC_WAKEUP,
        calendar.timeInMillis,
        AlarmManager.INTERVAL_DAY,
        pendingIntent
    )
}

private fun createNotificationChannel(context: Context) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        val name = "Workout Reminder Channel"
        val descriptionText = "Channel for workout reminders"
        val importance = NotificationManager.IMPORTANCE_HIGH
        val channel = NotificationChannel(CHANNEL_ID, name, importance).apply {
            description = descriptionText
        }
        val notificationManager: NotificationManager =
            context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
        notificationManager.createNotificationChannel(channel)
    }
}

companion object {
    const val CHANNEL_ID = "workout_reminder_channel"
}

Широковещательный приемник

class AlarmReceiver : BroadcastReceiver() {
    override fun onReceive(context: Context, intent: Intent) {

        val today = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            LocalDate.now()
        } else {
            TODO("VERSION.SDK_INT < O")
        }

        val mainIntent = Intent(context, MainActivity::class.java)
        mainIntent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK


        val pendingIntent = PendingIntent.getActivity(
            context,
            0,
            mainIntent,
            PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
        )

        val notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
        val notification = NotificationCompat.Builder(context, ProfileViewModel.CHANNEL_ID)
            .setSmallIcon(R.drawable.img_fitness1)
            .setContentTitle("Workout Reminder")
            .setContentText("It's time for your workout! Time : ${formatDate(today)}")
            .setPriority(NotificationCompat.PRIORITY_HIGH)
            .setContentIntent(pendingIntent)
            .setAutoCancel(true)
            .build()

        notificationManager.notify(NOTIFICATION_ID, notification)
    }

    companion object {
        const val NOTIFICATION_ID = 1
    }
}
0
0
50
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Пожалуйста, ознакомьтесь с официальной документацией о планировании будильников.

В Android есть два типа будильников:

  • точные сигналы тревоги: они должны быть доставлены в указанное время.
  • неточные сигналы тревоги: они будут доставлены примерно в указанное время (~ в течение одного часа).

Если мы проверим документацию setRepeated, мы обнаружим следующую информацию:

Примечание. Начиная с API 19, все повторяющиеся сигналы тревоги являются неточными. Если вашему приложению необходимы точные сроки доставки, оно должно использовать одноразовые точные сигналы тревоги, каждый раз перепланируя, как описано выше. Устаревшие приложения, у которых targetSdkVersion старше API 19, по-прежнему будут считать все свои сигналы тревоги, включая повторяющиеся сигналы тревоги, точными.

Поэтому в зависимости от того, какие API-интерфейсы устройств вы хотите поддерживать, вам нужно будет использовать двухуровневый подход:

В вашем случае, если уведомление должно появиться в указанное пользователем время, вы можете использовать setAlarmClock. Однако затем вам необходимо запланировать каждый следующий сигнал тревоги в вашем коде.

См. также этот вопрос о stackoverflow для справки.

Другие вопросы по теме