I want to push a notification in my Android application at a fixed time one day before a specific date. I have already created a channel in the main activity.
Here is the code of the method responsible for scheduling notifications in the third activity:
private void scheduleNotification(LocalDate date, String doctorName) {
try {
if (date != null) {
LocalDate notificationDate = date.minusDays(1);
Calendar calendar = Calendar.getInstance();
calendar.set(notificationDate.getYear(), notificationDate.getMonthValue() - 1, notificationDate.getDayOfMonth(), 2, 2, 0);
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(getBaseContext(), AppointmentNotificationReceiver.class);
intent.putExtra("doctor_name", doctorName);
PendingIntent pendingIntent = PendingIntent.getBroadcast(getBaseContext(), 0, intent, PendingIntent.FLAG_IMMUTABLE);
alarmManager.setExact(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent);
Toast.makeText(getBaseContext(), "Notification scheduled for " + notificationDate.format(DateTimeFormatter.ofPattern("dd.MM.yyyy")) + " at 13:00.", Toast.LENGTH_LONG).show();
}
} catch (Exception e) {
Toast.makeText(getBaseContext(), "Error scheduling notification: " + e.getMessage() + ".", Toast.LENGTH_LONG).show();
}
}
And this is the code of the notification receiver class.
public class AppointmentNotificationReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
String doctorName = intent.getStringExtra("doctor_name");
NotificationCompat.Builder builder = new NotificationCompat.Builder(context, "ID12345678FFRREE")
.setContentTitle("Remainder")
.setContentText("Tomorrow.")
.setPriority(NotificationCompat.PRIORITY_DEFAULT);
NotificationManagerCompat notificationManager = NotificationManagerCompat.from(context);
if (ActivityCompat.checkSelfPermission(context, android.Manifest.permission.POST_NOTIFICATIONS) != PackageManager.PERMISSION_GRANTED) {
// TODO: Consider calling // ActivityCompat#requestPermissions // here to request the missing permissions, and then overriding // public void onRequestPermissionsResult(int requestCode, String[] permissions, // int[] grantResults) // to handle the case where the user grants the permission. See the documentation // for ActivityCompat#requestPermissions for more details.
return;
}
notificationManager.notify(200, builder.build());
}
}
Here is the part of code in the main activity for creating a channel:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel channel = new NotificationChannel("ID12345678FFRREE", "Channel", NotificationManager.IMPORTANCE_DEFAULT);
channel.setDescription("desc");
NotificationManager notificationManager = getSystemService(NotificationManager.class);
notificationManager.createNotificationChannel(channel);
}
Everything is okay, but the notification does not appear at all. Instead, at the fixed time of the notification, the application goes back to the first activity (main activity) if I am currently at a different activity.
Do it like this then it will work :
public class AppointmentNotificationReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
String doctorName = intent.getStringExtra("doctor_name");
// Create Notification Channel
NotificationManager notificationManager = context.getSystemService(NotificationManager.class);
NotificationChannel channel = new NotificationChannel("ID12345678FFRREE", "Channel", NotificationManager.IMPORTANCE_DEFAULT);
channel.setDescription("desc");
notificationManager.createNotificationChannel(channel); //Notification channel should be created before you build the notification
// Build the Notification
NotificationCompat.Builder builder = new NotificationCompat.Builder(context, "ID12345678FFRREE")
.setContentTitle("Reminder")
.setContentText("Tomorrow")
.setPriority(NotificationCompat.PRIORITY_DEFAULT)
.setSmallIcon(R.drawable.ic_notification); // Make sure to set an icon
// Check for Android 13 and later
if (ActivityCompat.checkSelfPermission(context, android.Manifest.permission.POST_NOTIFICATIONS) != PackageManager.PERMISSION_GRANTED) {
// TODO: Request POST_NOTIFICATIONS permission
return;
}
// Notify the user
notificationManager.notify(200, builder.build());
}
}
Receiver Declaration in Manifest :
AppointmentNotificationReceiver
is registered in the AndroidManifest.xml
file:<receiver android:name=".AppointmentNotificationReceiver"
android:exported="true">
</receiver>
POST_NOTIFICATIONS
permission at runtime also declared in the AndroidManifest.xml
file<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
same for
<uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM" />
PendingIntent
properly in scheduleNotification
functionPendingIntent pendingIntent = PendingIntent.getBroadcast(
getBaseContext(),
0,
intent,
PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE
);
AlarmManager
is set up correctly for starting notification at correct timealarmManager.setExact(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent);
Go to Settings > Battery > Battery Optimization and exclude your app.
Reference links to read