Как показать уведомление в фоновом режиме в определенный будущий день с помощью AlarmManager - PullRequest
0 голосов
/ 23 апреля 2020

Я показываю DatePicker, чтобы пользователь выбрал дату в будущем, и я хочу уведомить пользователя за один день до выбранной даты. Например, если пользователь выбирает дату [26 апреля 2020 года], я хочу уведомить пользователя в [25 апреля 2020 года], даже если приложение не запущено. Тем не менее, в моем случае уведомление появляется только тогда, когда приложение работает, но когда приложение не запущено, уведомление не работает.

Это мой MainActivity

class MainActivity : AppCompatActivity() {
    private lateinit var dateFormat: SimpleDateFormat
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        dateFormat = SimpleDateFormat("MMM dd, yyyy", Locale.US)

        edit_text_date.setOnClickListener {
            showDatePicker()
        }
        notify_switch.setOnCheckedChangeListener { buttonView, isChecked ->
            if (isChecked) {
                val deadlineDate = dateFormat.parse(edit_text_date.text.toString())!!
                val c = Calendar.getInstance()
                c.time = deadlineDate
                c.add(Calendar.DATE, -1)
                val pastDay = dateFormat.format(c.time)
                val calender = Calendar.getInstance()
                val currentDate = dateFormat.format(calender.time)
                if (currentDate == pastDay) {
                    val alarmManager = getSystemService(Context.ALARM_SERVICE) as AlarmManager
                    val intent = Intent(this, AlarmReceiver::class.java)
                    val pendingIntent = PendingIntent.getBroadcast(this, 0, intent, 0)
                    alarmManager.set(
                        AlarmManager.RTC_WAKEUP,
                        c.timeInMillis,
                        pendingIntent
                    )
                }
            }
        }
    }

    private fun showDatePicker() {
        val c = Calendar.getInstance()
        DatePickerDialog(this,DatePickerDialog.OnDateSetListener { view, year, month, dayOfMonth ->
                val daySelected = Calendar.getInstance()
                daySelected.apply {
                    set(Calendar.YEAR, year)
                    set(Calendar.MONTH, month)
                    set(Calendar.DAY_OF_MONTH, dayOfMonth)
                }
                edit_text_date.setText(dateFormat.format(daySelected.time))
            },
            c.get(Calendar.YEAR),
            c.get(Calendar.MONTH),
            c.get(Calendar.DAY_OF_MONTH)
        ).show()
    }
}

Это класс AlarmReceiver

class AlarmReceiver : BroadcastReceiver() {
    override fun onReceive(context: Context, intent: Intent?) {
        showNotification(context,"title","notification message")

    }
    private fun showNotification(context: Context,title:String,body:String){
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O){
            val notificationChannel = NotificationChannel("CHANNEL_ID","My Channel",NotificationManager.IMPORTANCE_HIGH)
            val notificationManager = context.getSystemService(NotificationManager::class.java)!!
            notificationManager.createNotificationChannel(notificationChannel)
        }
        val notificationManagerCompat = NotificationManagerCompat.from(context)
        val notification = NotificationCompat.Builder(context,"CHANNEL_ID")
            .setSmallIcon(R.drawable.ic_launcher_background)
            .setContentTitle(title)
            .setContentText(body)
            .setPriority(NotificationCompat.PRIORITY_HIGH)
            .build()
        notificationManagerCompat.notify(0,notification)
    }
}

Я также регистрирую получателя в Manifest

1 Ответ

0 голосов
/ 23 апреля 2020

Для более эффективного планирования задач вы должны использовать недавно представленный класс WorkManager. Он обрабатывает все уровни API, и вам не нужно беспокоиться о Android версиях, с которыми будет работать ваше приложение.

Чтобы вызвать вашу функцию в установленное желаемое время,

OneTimeWorkRequest oneTimeWorkRequest = new OneTimeWorkRequest.Builder(WorkerClass.class)
                                                        .setConstraints(constraints)
                                                        .setInitialDelay(delayToPass, TimeUnit.MILLISECONDS)
                                                        .build();
WorkManager.getInstance(getApplicationContext())
    .enqueueUniqueWork(oneTimeWorkRequest);

За дополнительной информацией обращайтесь: https://developer.android.com/reference/androidx/work/WorkManager

"WorkerClass" - это класс, который будет обрабатывать желаемую работу внутри

public Result doWork() // method

. Обязательно прочитайте об этом. тоже.

...