How to Schedule Notification in Android

OmerN picture OmerN · Apr 28, 2016 · Viewed 48.3k times · Source

I'm trying to set notification for a time in the future. I have the code for creating a notification but I can't find an option to schedule it.

How can I schedule notifications?

Answer

apelsoczi picture apelsoczi · Apr 28, 2016

NOT FOR USE IN OREO+ (edit)

The answers above are good - but don't consider the user's potential to restart the device (which clears PendingIntent's scheduled by AlarmManager).

You need to create a WakefulBroadcastReceiver, which will contain an AlarmManager to schedule deliver a PendingIntent. When the WakefulBroadcastReceiver handles the intent - post your notification and signal the WakefulBroadcastReceiver to complete.

WakefulBroadcastReceiver

    /**
     * When the alarm fires, this WakefulBroadcastReceiver receives the broadcast Intent
     * and then posts the notification.
     */
    public class WakefulReceiver extends WakefulBroadcastReceiver {
        // provides access to the system alarm services.
        private AlarmManager mAlarmManager;

        public void onReceive(Context context, Intent intent) {
            //// TODO: post notification
            WakefulReceiver.completeWakefulIntent(intent);
        }

        /**
         * Sets the next alarm to run. When the alarm fires,
         * the app broadcasts an Intent to this WakefulBroadcastReceiver.
         * @param context the context of the app's Activity.
         */
        public void setAlarm(Context context) {
            mAlarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
            Intent intent = new Intent(context, WakefulReceiver.class);
            PendingIntent alarmIntent = PendingIntent.getBroadcast(context, 0, intent, 0);

            Calendar calendar = Calendar.getInstance();
            calendar.setTimeInMillis(System.currentTimeMillis());
            //// TODO: use calendar.add(Calendar.SECOND,MINUTE,HOUR, int);
            //calendar.add(Calendar.SECOND, 10);

            //ALWAYS recompute the calendar after using add, set, roll
            Date date = calendar.getTime();

            mAlarmManager.setExact(AlarmManager.RTC_WAKEUP, date.getTime(), alarmIntent);

            // Enable {@code BootReceiver} to automatically restart when the
            // device is rebooted.
            //// TODO: you may need to reference the context by ApplicationActivity.class
            ComponentName receiver = new ComponentName(context, BootReceiver.class);
            PackageManager pm = context.getPackageManager();
            pm.setComponentEnabledSetting(receiver, PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
                    PackageManager.DONT_KILL_APP);
        }

        /**
         * Cancels the next alarm from running. Removes any intents set by this
         * WakefulBroadcastReceiver.
         * @param context the context of the app's Activity
         */
        public void cancelAlarm(Context context) {
            Log.d("WakefulAlarmReceiver", "{cancelAlarm}");

            mAlarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
            Intent intent = new Intent(context, WakefulReceiver.class);
            PendingIntent alarmIntent = PendingIntent.getBroadcast(context, 0, intent, 0);

            mAlarmManager.cancel(alarmIntent);

            // Disable {@code BootReceiver} so that it doesn't automatically restart when the device is rebooted.
            //// TODO: you may need to reference the context by ApplicationActivity.class
            ComponentName receiver = new ComponentName(context, BootReceiver.class);
            PackageManager pm = context.getPackageManager();
            pm.setComponentEnabledSetting(receiver, PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
                    PackageManager.DONT_KILL_APP);
        }

BootReceiver

    public class BootReceiver extends BroadcastReceiver {

        @Override
        public void onReceive(Context context, Intent intent) {
            if (intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED)) {
            context = ApplicationActivity.class;
            AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
            Intent intent = new Intent(context, WakefulReceiver.class);
            PendingIntent alarmIntent = PendingIntent.getBroadcast(context, 0, intent, 0);

            Calendar calendar = Calendar.getInstance();
            calendar.setTimeInMillis(System.currentTimeMillis());
            //// TODO: use calendar.add(Calendar.SECOND,MINUTE,HOUR, int);
            //calendar.add(Calendar.SECOND, 10);

            //ALWAYS recompute the calendar after using add, set, roll
            Date date = calendar.getTime();

            alarmManager.setExact(AlarmManager.RTC_WAKEUP, date.getTime(), alarmIntent);
            }
        }
    }

AndroidManifest.xml

<receiver android:name=".WakefulReceiver"/>

<receiver android:name=".BootReceiver"
    android:enabled="false">
    <intent-filter>
        <action android:name="android.intent.action.BOOT_COMPLETED"/>
    </intent-filter>
</receiver>