Search code examples
javaandroidpush-notificationnotifications

Why doesn't a scheduled notification appear at the fixed time, and instead of that, the application goes back to the main activity in Android Java?


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.


Solution

  • 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 correctly declared in your AndroidManifest.xml.


    Update 1:

    1. AppointmentNotificationReceiver is registered in the AndroidManifest.xml file:

    <receiver android:name=".AppointmentNotificationReceiver"
              android:exported="true">
    </receiver>
    

    2. Ensure you have the request the 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" />
    

    3. Handle PendingIntent properly in scheduleNotification function

    PendingIntent pendingIntent = PendingIntent.getBroadcast(
        getBaseContext(), 
        0, 
        intent, 
        PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE
    );
    

    4. Check AlarmManager is set up correctly for starting notification at correct time

    alarmManager.setExact(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent);
    

    5. Check the Device's Battery Optimization Settings

    Go to Settings > Battery > Battery Optimization and exclude your app.

    Notes :
    • Check Device Logs use adb logcat to monitor logs from the device
    • Ensure you test your application on a physical device

    Reference links to read