How to Schedule Notification in Android [duplicate]

匿名 (未验证) 提交于 2019-12-03 02:44:02

问题:

This question already has an answer here:

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?

回答1:

You need to use PendingIntent and BroadCastReceiver for this -

public void scheduleNotification(Context context, long delay, int notificationId) {//delay is after how much time(in millis) from current time you want to schedule the notification         NotificationCompat.Builder builder = new NotificationCompat.Builder(context)                 .setContentTitle(context.getString(R.string.title))                 .setContentText(context.getString(R.string.content))                 .setAutoCancel(true)                 .setSmallIcon(R.drawable.app_icon)                 .setLargeIcon(((BitmapDrawable) context.getResources().getDrawable(R.drawable.app_icon)).getBitmap())                 .setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION));          Intent intent = new Intent(context, YourActivity.class);         PendingIntent activity = PendingIntent.getActivity(context, notificationId, intent, PendingIntent.FLAG_CANCEL_CURRENT);         builder.setContentIntent(activity);          Notification notification = builder.build();          Intent notificationIntent = new Intent(context, MyNotificationPublisher.class);         notificationIntent.putExtra(NotificationPublisher.NOTIFICATION_ID, notificationId);         notificationIntent.putExtra(NotificationPublisher.NOTIFICATION, notification);         PendingIntent pendingIntent = PendingIntent.getBroadcast(context, notificationId, notificationIntent, PendingIntent.FLAG_CANCEL_CURRENT);          long futureInMillis = SystemClock.elapsedRealtime() + delay;         AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);         alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, futureInMillis, pendingIntent);     } 

Also, you need to show notification in your receiver class -

public class MyNotificationPublisher extends BroadcastReceiver {      public static String NOTIFICATION_ID = "notification_id";     public static String NOTIFICATION = "notification";      @Override     public void onReceive(final Context context, Intent intent) {          NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);          Notification notification = intent.getParcelableExtra(NOTIFICATION);         int notificationId = intent.getIntExtra(NOTIFICATION_ID, 0);         notificationManager.notify(notificationId, notification);     } } 

Finally , call scheduleNotification() with appropriate arguments and you are good to go !



回答2:

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> 


易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!