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())
}
}
This
Intentpoints to a subclass ofBroadcastReceiver.This code needs an
Intentthat points to a subclass ofService, as you are callinggetService().So, either you need to use an
Intentthat points to aService, or you need to usegetBroadcast(). The method call and theIntentneed to match.In this case, it is unclear what the value is in the service, so I would switch to
getBroadcast()and haveReminderReceiverdisplay yourNotification.