web-dev-qa-db-fra.com

Comment programmer une notification dans Android

J'essaie de configurer la notification pour un moment dans le futur. J'ai le code pour créer une notification mais je ne trouve pas d'option pour la planifier.

Comment puis-je planifier des notifications?

30
OmerN

Vous devez utiliser PendingIntent et BroadCastReceiver pour cela -

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(MyNotificationPublisher.NOTIFICATION_ID, notificationId);
        notificationIntent.putExtra(MyNotificationPublisher.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);
    }

En outre, vous devez afficher une notification dans votre classe de récepteur -

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);
    }
}

Enfin, appelez scheduleNotification() avec les arguments appropriés et vous voilà prêt à partir!

32
Shadab Ansari

NE PAS UTILISER DANS OREO + (edit)

Les réponses ci-dessus sont bonnes - mais ne considérez pas le potentiel de l'utilisateur à redémarrer le périphérique (ce qui efface les informations PendingIntent planifiées par AlarmManager).

Vous devez créer un récepteur WakefulBroadcast, qui contiendra un gestionnaire AlarmManager pour planifier la livraison d'un élément PendingIntent. Lorsque WakefulBroadcastReceiver traite l’intention - envoyez votre notification et signalez-lui que WakefulBroadcastReceiver est terminé.

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>
37
apelsoczi