12

Sto provando a impostare la notifica per un periodo futuro. Ho il codice per creare una notifica ma non riesco a trovare un'opzione per programmarlo.Come programmare la notifica su Android

Come posso programmare le notifiche?

+1

Questo è ancora utile beca usare l'altra domanda era 3 anni prima di questa e alcuni comportamenti di base sono cambiati, quindi grazie! – AfzalivE

risposta

16

è necessario utilizzare PendingIntent e BroadCastReceiver per questo -

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

Inoltre, è necessario mostrare la notifica della tua classe ricevente -

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

Infine, chiamare scheduleNotification() con gli argomenti appropriati e sei buono per andare!

+0

Grazie mille, ha funzionato per me. – OmerN

+0

così ogni giorno alle 12PM per esempio ... quei codici vanno nell'attività principale? – Si8

+0

Questo allarme programmato per il codice verrà annullato quando l'app scorre nella "lista delle app recenti". Come evitare questo problema? – NghiaDao

24

NON PER USO IN OREO + (edit)

Le risposte di cui sopra sono buone - , ma non considerano il potenziale del all'utente di riavviare il dispositivo (che cancella PendingIntent del programma da AlarmManager).

È necessario creare un WakefulBroadcastReceiver, che conterrà un AlarmManager per pianificare la consegna di un PendingIntent. Quando WakefulBroadcastReceiver gestisce l'intento, pubblica la tua notifica e segnala il completamento di WakefulBroadcastReceiver.

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> 
+0

Questo è oro! Felice di trovarlo. –

+2

Ehi sul 'BootReceiver.class' non dovresti usare manualmente il tipo" android.intent.action.BOOT_COMPLETED "piuttosto usa" Intent.ACTION_BOOT_COMPLETED' – SARose

+1

buona cattura - Ho aggiornato questo! Grazie per aver contribuito. – apelsoczi

Problemi correlati