12

我試圖在將來爲某個時間設置通知。 我有創建通知的代碼,但我找不到安排它的選項。如何在Android中安排通知

我該如何安排通知?

+1

這仍然是有用的貝科使用另一個問題是在此之前3年,一些潛在的行爲已經改變,所以謝謝! – AfzalivE

回答

16

您需要使用PendingIntentBroadCastReceiver此 -

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

此外,你需要證明你的接收機類的通知 -

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

最後,調用scheduleNotification()用適當的參數和你很好去!

+0

非常感謝,它爲我工作。 – OmerN

+0

所以每天12點例如...那些代碼是在主要活動? – Si8

+0

此應用在「近期應用列表」中刷卡時,此代碼預定鬧鐘將被取消。如何避免這個問題? – NghiaDao

24

NOT FOR USE IN奧利奧+(編輯)

以上的回答都不錯 - 但不考慮用戶重啓設備(它清除的PendingIntent的由AlarmManager計劃)的潛力。

您需要創建一個WakefulBroadcastReceiver,它將包含一個AlarmManager來計劃傳遞一個PendingIntent。當WakefulBroadcastReceiver處理該意圖時 - 發佈您的通知併發信號通知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

這是黃金!很高興找到它。 –

+2

嘿在'BootReceiver.class'你不應該使用手動類型「android.intent.action.BOOT_COMPLETED」而是使用'Intent.ACTION_BOOT_COMPLETED' – SARose

+1

好抓 - 我已經更新了!感謝您的貢獻。 – apelsoczi