Reminder notifications are not showing

32 Views Asked by At

I wrote an application that aims to create a notification about the content entered by the user. It should be displayed on the device screen at the previously specified date and time. The alert should also be displayed when the application is not turned on. Unfortunately, despite setting a reminder, the message window never appears.

MainActivity.kt

package com.example.kalendarz_2

import android.app.AlarmManager
import android.app.DatePickerDialog
import android.app.NotificationChannel
import android.app.NotificationManager
import android.app.PendingIntent
import android.app.TimePickerDialog
import android.content.Context
import android.content.Intent
import android.os.Build
import android.os.Bundle
import android.view.View
import android.widget.Button
import android.widget.DatePicker
import android.widget.EditText
import android.widget.TimePicker
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import java.util.*

class MainActivity : AppCompatActivity() {

    private lateinit var btnSetReminder: Button
    private lateinit var etReminderText: EditText

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        btnSetReminder = findViewById(R.id.btnSetReminder)
        etReminderText = findViewById(R.id.etReminderText)
        
    }

    fun showDateTimePicker(view: View) {
        val calendar = Calendar.getInstance()
        val initialYear = calendar.get(Calendar.YEAR)
        val initialMonth = calendar.get(Calendar.MONTH)
        val initialDay = calendar.get(Calendar.DAY_OF_MONTH)
        val initialHour = calendar.get(Calendar.HOUR_OF_DAY)
        val initialMinute = calendar.get(Calendar.MINUTE)

        val datePickerDialog = DatePickerDialog(this, { _, year, month, day ->
            val timePickerDialog = TimePickerDialog(this, { _, hourOfDay, minute ->
                setReminder(year, month, day, hourOfDay, minute)
            }, initialHour, initialMinute, true)
            timePickerDialog.show()
        }, initialYear, initialMonth, initialDay)

        datePickerDialog.show()
    }

    private fun setReminder(year: Int, month: Int, day: Int, hourOfDay: Int, minute: Int) {
        val calendar = Calendar.getInstance()
        calendar.set(year, month, day, hourOfDay, minute)

        
        if (calendar.timeInMillis > System.currentTimeMillis()) {
            val alarmManager = getSystemService(Context.ALARM_SERVICE) as AlarmManager
            val intent = Intent(this, ReminderReceiver::class.java)
            intent.putExtra("REMINDER_TEXT", etReminderText.text.toString())
            intent.putExtra("REMINDER_TIME", calendar.timeInMillis)

            
            val pendingIntent = PendingIntent.getService(
                this, 0, intent,
                PendingIntent.FLAG_IMMUTABLE
            )

            
            alarmManager.set(AlarmManager.RTC_WAKEUP, calendar.timeInMillis, pendingIntent)
            Toast.makeText(this, "Alert sets at: ${calendar.time}", Toast.LENGTH_SHORT).show()
        } else {
            Toast.makeText(this, "Enter date and time from future", Toast.LENGTH_SHORT).show()
        }
    }
}

ReminderService.kt

package com.example.kalendarz_2

import android.app.*
import android.content.Intent
import android.os.Build
import android.os.IBinder
import android.util.Log
import androidx.annotation.RequiresApi
import java.util.*

class ReminderService : Service() {

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

    @RequiresApi(Build.VERSION_CODES.O)
    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        Log.d("ReminderService", "Reminder service started")
        showReminderNotification(intent?.getStringExtra("REMINDER_TEXT") ?: "no reminder content")

        
        return START_STICKY
    }

    @RequiresApi(Build.VERSION_CODES.O)
    private fun showReminderNotification(reminderText: String) {
        
        val notificationManager =
            getSystemService(NotificationManager::class.java)

        
        val notificationChannelId = "channel_id"
        val notificationBuilder = Notification.Builder(this, notificationChannelId)
            .setContentTitle("Notification")
                .setContentText("Content notification: $reminderText")
            .setSmallIcon(R.mipmap.ic_launcher)
            .setAutoCancel(true)

        
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
            val notificationChannelId = "channel_id"
            val notificationChannel = NotificationChannel(
                notificationChannelId,
                "Notifications",
                NotificationManager.IMPORTANCE_HIGH
            )
            notificationManager?.createNotificationChannel(notificationChannel)
            notificationBuilder.setChannelId(notificationChannelId)
        }

        
        notificationManager?.notify(1, notificationBuilder.build())
    }
}

ReminderReceiver.kt

package com.example.kalendarz_2

import android.app.AlertDialog
import android.content.BroadcastReceiver
import android.content.Context
import android.content.DialogInterface
import android.content.Intent
import android.os.Build
import android.util.Log
import android.widget.Toast

class ReminderReceiver : BroadcastReceiver() {
    override fun onReceive(context: Context?, intent: Intent?) {
        Log.d("ReminderReceiver", "Received reminder broadcast")
        val reminderText = intent?.getStringExtra("REMINDER_TEXT") ?: "no reminder content"
        val reminderTime = intent?.getLongExtra("REMINDER_TIME", 0) ?: 0

        
        val currentTime = System.currentTimeMillis()

        if (reminderTime > currentTime) {
            
            val serviceIntent = Intent(context, ReminderService::class.java)
            serviceIntent.putExtra("REMINDER_TEXT", reminderText)
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                context?.startForegroundService(serviceIntent)
            } else {
                context?.startService(serviceIntent)
            }
        } else {
            Toast.makeText(context, "Notification: $reminderText", Toast.LENGTH_LONG).show()
        }
    }
}

activity_main.xml

<!-- res/layout/activity_main.xml -->
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingLeft="16dp"
    android:paddingTop="16dp"
    android:paddingRight="16dp"
    android:paddingBottom="16dp"
    tools:context=".MainActivity">

    <Button
        android:id="@+id/btnSetReminder"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Ustaw Przypomnienie"
        android:layout_centerInParent="true"
        android:onClick="showDateTimePicker" />

    <EditText
        android:id="@+id/etReminderText"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@id/btnSetReminder"
        android:layout_marginTop="16dp"
        android:hint="Treść przypomnienia"
        android:padding="16dp"
    />
</RelativeLayout>

I remembered the appropriate lines in the file AndroidManifest.xml:

<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />

I was looking for information on various websites, I also consulted the gpt chat

AFTER EDIT:

    private fun setReminder(year: Int, month: Int, day: Int, hourOfDay: Int, minute: Int) {
        val calendar = Calendar.getInstance()
        calendar.set(year, month, day, hourOfDay, minute)

        
        if (calendar.timeInMillis > System.currentTimeMillis()) {
            val alarmManager = getSystemService(Context.ALARM_SERVICE) as AlarmManager
            val intent = Intent(this, ReminderReceiver::class.java)
            intent.putExtra("REMINDER_TEXT", etReminderText.text.toString())
            intent.putExtra("REMINDER_TIME", calendar.timeInMillis)

            
            val pendingIntent = PendingIntent.getBroadcast(
                this, 0, intent,
                PendingIntent.FLAG_IMMUTABLE
            )

            alarmManager.set(AlarmManager.RTC_WAKEUP, calendar.timeInMillis, pendingIntent)
            Toast.makeText(this, "notification set an: ${calendar.time}", Toast.LENGTH_SHORT).show()
        } else {
            Toast.makeText(this, "entre date from the future", Toast.LENGTH_SHORT).show()
        }
    }

in ReminderReceiver.kt:

class ReminderReceiver : BroadcastReceiver() {
    override fun onReceive(context: Context?, intent: Intent?) {
        Log.d("ReminderReceiver", "Received reminder broadcast")
        val reminderText = intent?.getStringExtra("REMINDER_TEXT") ?: "No contet notification"
        val reminderTime = intent?.getLongExtra("REMINDER_TIME", 0) ?: 0

        val currentTime = System.currentTimeMillis()

        if (reminderTime > currentTime) {
            showReminderNotification(context, reminderText)
        } else {
            Toast.makeText(context, "PNotification: $reminderText", Toast.LENGTH_LONG).show()
        }
    }

    private fun showReminderNotification(context: Context?, reminderText: String) {
        val notificationManager =
            context?.getSystemService(NotificationManager::class.java)

        val notificationChannelId = "channel_id"
        val notificationBuilder = NotificationCompat.Builder(context!!, notificationChannelId)
            .setContentTitle("Notification")
            .setContentText("Content of notification: $reminderText")
            .setSmallIcon(R.mipmap.ic_launcher)
            .setAutoCancel(true)
            .setDefaults(Notification.DEFAULT_SOUND) 

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            val notificationChannel = NotificationChannel(
                notificationChannelId,
                "Notifications",
                NotificationManager.IMPORTANCE_HIGH
            )
            notificationManager?.createNotificationChannel(notificationChannel)
            notificationBuilder.setChannelId(notificationChannelId)
        }
        
        notificationManager?.notify(1, notificationBuilder.build())
    }
}
1

There are 1 best solutions below

1
CommonsWare On
val intent = Intent(this, ReminderReceiver::class.java)

This Intent points to a subclass of BroadcastReceiver.

val pendingIntent = PendingIntent.getService(
                this, 0, intent,
                PendingIntent.FLAG_IMMUTABLE
            )

This code needs an Intent that points to a subclass of Service, as you are calling getService().

So, either you need to use an Intent that points to a Service, or you need to use getBroadcast(). The method call and the Intent need to match.

In this case, it is unclear what the value is in the service, so I would switch to getBroadcast() and have ReminderReceiver display your Notification.