Android调度与广播接收器重复警报

时间:2017-05-29 05:18:59

标签: android notifications broadcastreceiver alarmmanager

我必须在一天中的不同时间发送3个不同的通知(不同的内容)。 按照官方文件https://developer.android.com/training/scheduling/alarms.html#type, 我能够在指定的时间发送通知,但在更改每个通知的内容时遇到一些麻烦。以下是设置通知的方法,并在MainActivity的onCreate()方法中调用。

public void setNotification() {
    Intent intent = new Intent(this, MyBroadcastReceiver.class);
    AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
    for (int id = 0; id < 3; id++) {
        Calendar calendar = Calendar.getInstance();
        // Defining different pendingIntent
        switch (id){
            case 0:
                calendar.set(Calendar.HOUR_OF_DAY, 9);
                break;
            case 1:
                calendar.set(Calendar.HOUR_OF_DAY, 14);
                break;
            case 2:
                calendar.set(Calendar.HOUR_OF_DAY, 20);
                break;
        }
        if(calendar.getTimeInMillis() < System.currentTimeMillis()){
            calendar.add(Calendar.DATE, 1);
        }
        PendingIntent pendingIntent = PendingIntent.getBroadcast(this, id, intent, 0);
        // setRepeating() schedules an alarm
        alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY, pendingIntent);
    }
}

我知道我可以使用Intent.putExtra()功能发送数据,这些数据可用于识别意图,但如果应用被杀死,这些数据将会丢失。 我希望这个工作即使应用程序没有运行或应用程序被杀或设备启动。经过一些阅读后,我发现我可以使用BOOT_COMPLETE监听器在设备启动后设置警报。由于在onCreate()方法中设置通知,每次运行应用程序时都会显示通知,即使我尝试使用以下代码解决此问题

if(calendar.getTimeInMillis() < System.currentTimeMillis()){
            calendar.add(Calendar.DATE, 1);
        }

目前onReceive方法看起来像这样

public void onReceive(Context context, Intent intent) {

    NotificationCompat.Builder mBuilder =
            new NotificationCompat.Builder(context)
                    .setSmallIcon(R.mipmap.app_icon)
                    .setContentTitle("Title")
                    .setContentText("Message");
    Intent resultIntent = new Intent(context, MainActivity.class);
    TaskStackBuilder stackBuilder = TaskStackBuilder.create(context);
    stackBuilder.addParentStack(MainActivity.class);
    stackBuilder.addNextIntent(resultIntent);
    PendingIntent resultPendingIntent = stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
    mBuilder.setContentIntent(resultPendingIntent);
    NotificationManager mNotificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
    mNotificationManager.notify(0, mBuilder.build());
}

我需要帮助决定在哪里放置setNotification()方法,以便它一次注册所有警报以及如何识别即将发生的意图,以便采取适当的措施。一种方法是使用意图过滤器定义3个不同的broadcastReceiver,并在创建它们时设置意图URI。这是正确的方法还是有其他简单的解决方案?

2 个答案:

答案 0 :(得分:1)

  每次运行应用程序时都会出现

通知

使用SharedPreference进行检查,如果没有完成,只设置一次。

也是你的代码

if(calendar.getTimeInMillis() < System.currentTimeMillis()){
    calendar.add(Calendar.DATE, 1);
}

应该有点像这样

Calendar calendar = Calendar.getInstance();
// Get the current time in millis
long currentTime = calendar.getTimeInMillis();
// Set the reminder times
switch(id) {
    ..
    ..
}
//Get the reminder time in millis
long intendedTime = calendar.getTimeInMillis();

if (intendedTime < currentTime) {
    // Set from next day and to repeat once a day.
    // you might consider using calendar.add() for adding one day to the current day

    calendar.add(Calendar.DAY_OF_MONTH, 1);
    intendedTime = calendar.getTimeInMillis();

    alarmManager.setInexactRepeating(AlarmManager.RTC_WAKEUP,
            intendedTime, AlarmManager.INTERVAL_DAY, pendingIntent);
} else {
    // Set for today and to repeat once a day.
    alarmManager.setInexactRepeating(AlarmManager.RTC_WAKEUP, intendedTime,
            AlarmManager.INTERVAL_DAY, pendingIntent);
}

答案 1 :(得分:0)

  

如何确定即将发生的意图,以便采取适当的行动   被采取

您需要为Intent设置操作才能在BroadcastReceiver中接收数据

Intent intent = new Intent(this, MyBroadcastReceiver.class);
intent.setAction("THIS_IS_MY_ACTION");

BOOT_COMPLETE 的案例
取消Boot上的所有报警,并重置它们。取消闹钟使用cancel()设置闹钟时,使用您使用过的PendingIntent在AlarmManager上呼叫setRepeating()

在使用context时,请注意INTENT_FLAGSAlarmManager

在取消警报时使用getApplicationContext()作为上下文并保留request_code的记录,使用PendingIntent.FLAG_UPDATE_CURRENT

这可能会有所帮助: -

PendingIntent pendingIntent = PendingIntent.getBroadcast(getApplicationContext(), request_code, intent, PendingIntent.FLAG_UPDATE_CURRENT)