1

在一个活动中,我有三个DatePickerDialog,用户可以在其中放置三个日期作为提醒目的。该应用程序必须通知每个日期,如果用户输入两个或三个相同的日期,他们必须按顺序通知。我的问题是只有最后输入的日期被通知。我为notification_id使用了一个随机数。我该如何解决?由于如何在Android中获取多个通知

下面的代码:

ScheduleClient.java

public class ScheduleClient { 

    private ScheduleService mBoundService; 
    private Context mContext; 
    private boolean mIsBound; 

    public ScheduleClient(Context context) { 
     mContext = context; 
    } 

    public void doBindService() { 
     // Establish a connection with our service 
     mContext.bindService(new Intent(mContext, ScheduleService.class), mConnection, Context.BIND_AUTO_CREATE); 
     mIsBound = true; 
    } 

    private ServiceConnection mConnection = new ServiceConnection() { 
     public void onServiceConnected(ComponentName className, IBinder service) { 
      // This is called when the connection with our service has been established, 
      // giving us the service object we can use to interact with our service. 
      mBoundService = ((ScheduleService.ServiceBinder) service).getService(); 
     } 

     public void onServiceDisconnected(ComponentName className) { 
      mBoundService = null; 
     } 
    }; 

    public void setAlarmForNotification(Calendar c){ 
     mBoundService.setAlarm(c); 
    } 

    public void doUnbindService() { 
     if (mIsBound) { 
      // Detach our existing connection. 
      mContext.unbindService(mConnection); 
      mIsBound = false; 
     } 
    } 
} 

ScheduleService.java

public class ScheduleService extends Service { 


    public class ServiceBinder extends Binder { 
     ScheduleService getService() { 
      return ScheduleService.this; 
     } 
    } 

    @Override 
    public int onStartCommand(Intent intent, int flags, int startId) { 
     Log.i("ScheduleService", "Received start id " + startId + ": " + intent); 

     stopped, so return sticky. 
     return START_STICKY; 
    } 

    @Override 
    public IBinder onBind(Intent intent) { 
     return mBinder; 
    } 


    private final IBinder mBinder = new ServiceBinder(); 

    public void setAlarm(Calendar c) { 
     // This starts a new thread to set the alarm 
     // You want to push off your tasks onto a new thread to free up the UI to carry on responding 
     new AlarmTask(this, c).run(); 
    } 
} 

AlarmTask.java

public class AlarmTask implements Runnable { 

    private final Calendar date; 
    private final AlarmManager am; 
    private final Context context; 

    public AlarmTask(Context context, Calendar date) { 
     this.context = context; 
     this.am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); 
     this.date = date; 
    } 

    @Override 
    public void run() { 
     // Request to start are service when the alarm date is upon us 
     // We don't start an activity as we just want to pop up a notification into the system bar not a full activity 
     Intent intent = new Intent(context, NotifyService.class); 
     intent.putExtra(NotifyService.INTENT_NOTIFY, true); 
     PendingIntent pendingIntent = PendingIntent.getService(context, 0, intent, 0); 

     // Sets an alarm - note this alarm will be lost if the phone is turned off and on again 
     am.set(AlarmManager.RTC, date.getTimeInMillis(), pendingIntent); 
    } 
} 

NotifyService.java

public class NotifyService extends Service { 

    public class ServiceBinder extends Binder { 
     NotifyService getService() { 
      return NotifyService.this; 
     } 
    } 

    Random random = new Random(); 
    int randomID = random.nextInt(9999 - 1000) + 1000; 
    public static final String INTENT_NOTIFY = "com.try.myapp.INTENT_NOTIFY"; 
    private NotificationManager mNM; 

    @Override 
    public void onCreate() { 
     Log.i("NotifyService", "onCreate()"); 
     mNM = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); 
    } 

    @Override 
    public int onStartCommand(Intent intent, int flags, int startId) { 
     Log.i("LocalService", "Received start id " + startId + ": " + intent); 

     // If this service was started by out AlarmTask intent then we want to show our notification 
     if(intent.getBooleanExtra(INTENT_NOTIFY, false)) 
      showNotification(randomID); 

     // We don't care if this service is stopped as we have already delivered our notification 
     return START_NOT_STICKY; 
    } 

    @Override 
    public IBinder onBind(Intent intent) { 
     return mBinder; 
    } 

    private final IBinder mBinder = new ServiceBinder(); 

    private void showNotification(int notificationID) { 
     // This is the 'title' of the notification 
     CharSequence title = "Notification!"; 
     // This is the icon to use on the notification 
     int icon = R.drawable.ic_dialog_alert; 
     // This is the scrolling text of the notification 
     CharSequence text = "Sub text notification."; 
     // What time to show on the notification 
     long time = System.currentTimeMillis(); 

     Notification notification = new Notification(icon, text, time); 

     // The PendingIntent to launch our activity if the user selects this notification 
     PendingIntent contentIntent = PendingIntent.getActivity(this, notificationID, new Intent(this, SecondActivity.class), PendingIntent.FLAG_UPDATE_CURRENT); 

     // Set the info for the views that show in the notification panel. 
     notification.setLatestEventInfo(this, title, text, contentIntent); 

     // Clear the notification when it is pressed 
     notification.flags |= Notification.FLAG_AUTO_CANCEL; 
     notification.defaults |= Notification.DEFAULT_SOUND; 
     notification.defaults |= Notification.DEFAULT_LIGHTS; 
     notification.defaults |= Notification.DEFAULT_VIBRATE; 

     // Send the notification to the system. 
     mNM.notify(notificationID, notification); 

     // Stop the service when we are finished 
     stopSelf(); 
    } 
} 

InsertDateActivity.java

public class InsertCarActivity extends AppCompatActivity { 

.... 

toolbar.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() { 
     @Override 
     public boolean onMenuItemClick(MenuItem item) { 
      int id = item.getItemId(); 
      if (id == R.id.saveButton) { 
       firstDate = fDate.getText().toString().trim(); 
       secondDate = sDate.getText().toString().trim(); 
       thirdDate = tDate.getText().toString().trim(); 

       String[] arrFirstDate = firstDate.split("-"); 

       int day = Integer.parseInt(arrFirstDate[0]); 
       int month = Integer.parseInt(arrFirstDate[1]); 
       month -= 1; 
       int year = Integer.parseInt(arrFirstDate[2]); 

       Calendar c = Calendar.getInstance(); 
       c.set(year, month, day); 
       c.set(Calendar.HOUR_OF_DAY, 0); 
       c.set(Calendar.MINUTE, 0); 
       c.set(Calendar.SECOND, 0); 

       scheduleClient.setAlarmForNotification(c); 

       String[] arrSecondDate = secondDate.split("-"); 

       int day1 = Integer.parseInt(arrSecondDate[0]); 
       int month1 = Integer.parseInt(arrSecondDate[1]); 
       month1 -= 1; 
       int year1 = Integer.parseInt(arrSecondDate[2]); 

       Calendar c1 = Calendar.getInstance(); 
       c1.set(year1, month1, day1); 
       c1.set(Calendar.HOUR_OF_DAY, 0); 
       c1.set(Calendar.MINUTE, 0); 
       c1.set(Calendar.SECOND, 0); 

       scheduleClient.setAlarmForNotification(c1); 

       String[] arrThirdDate = thirdDate.split("-"); 

       int day2 = Integer.parseInt(arrThirdDate[0]); 
       int month2 = Integer.parseInt(arrThirdDate[1]); 
       month2 -= 1; 
       int year2 = Integer.parseInt(arrThirdDate[2]); 

       Calendar c2 = Calendar.getInstance(); 
       c2.set(year2, month2, day2); 
       c2.set(Calendar.HOUR_OF_DAY, 0); 
       c2.set(Calendar.MINUTE, 0); 
       c2.set(Calendar.SECOND, 0); 

       scheduleClient.setAlarmForNotification(c2); 

       return true; 
       } 
      return false; 

     } 

.... 

} 

回答

2

当您创建PendingIntent这里:

PendingIntent pendingIntent = PendingIntent.getService(context, 0, intent, 0); 

你可能想通过不同的requestCode(第一0你传递),每次或PendingIntent将是一样的,你所创建的最后一个与以下内容:

am.set(AlarmManager.RTC, date.getTimeInMillis(), pendingIntent); 

将设置报警相同PendingIntent和以前一样,所以只有你设置的最后一个报警实际上会触发。

从官方docs

如果确实需要多个不同的PendingIntent在同一时间(如为,它们都在同一时间显示两个通知使用)的对象激活,那么你就需要确保他们将不同的PendingIntents关联起来有些不同。这可以是Intent.filterEquals考虑的任何Intent属性,或提供给getActivity(Context,int,Intent,int),getActivities(Context,int,Intent [],int),getBroadcast(Context,int)的不同请求代码整数,Intent,int)或getService(Context,int,Intent,int)。

+0

嗨,谢谢你的回答!我已经把相同的代码用于生成AlarmTask.java中的NotifyService.java中使用的随机数,并用随机数替换了Pending Intent中的第一个零。现在显示每一个日期,但是如果我输入两个相等的日期,只会出现一个通知,(但有一次出现了两个正确的通知)。与输入的三个相等日期相同。我在哪里做错了? – JohnDroid

+0

不确定,也许是因为你的'NotifyService'在构造它时创建它是“随机”的id,并且因为onStartCommand()被第二次调用并且'Service'已经存在,所以它不会生成一个新的随机值。将随机ID代码移近实际创建的'PendingIntent' /'Notification'。 –

+0

非常感谢,现在它完美的工作! – JohnDroid