警报管理器 - 计划多个非重复事件

时间:2011-07-11 11:27:20

标签: android android-alarms

在Android Alarm Manager中,我们如何安排多个不重复且没有固定间隔重复的警报?我无法使用'setRepeating'功能,因为警报没有任何重复模式。

我将警报时间存储在Sqlite数据库表中,活动应该从该表中选择日期和时间并设置警报。

如果我们在循环中设置不同的警报,那么它只保留最后一个警报。 我从帖子中读到:How can create more than one alarm?

它告诉您将唯一ID附加到意图,然后设置单个警报事件。但它对我不起作用。

我们是否需要在Manifest文件中添加一些内容来处理这个唯一ID?

活动'RegularSchedule'中的代码是,它只创建一个警报事件:

        while (notifCursor.moveToNext()) {
            Intent intent = new Intent(RegularSchedule.this,
                    RepeatingAlarm.class);

            // The cursor returns first column as unique ID             
            intent.setData(Uri.parse("timer:" + notifCursor.getInt(0)));

            PendingIntent sender = PendingIntent.getBroadcast(
                    RegularSchedule.this, 0, intent, 0);

            // Setting time in milliseconds taken from database table 
            cal.setTimeInMillis(notifCursor.getLong(1));

            AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE);
            am.set(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), sender);
        }

如果需要进一步的详细信息或代码段,请与我们联系。

清单文件(此处为RepeatingAlarm扩展BroadcastReceiver):

    <receiver android:name=".user_alerts.RepeatingAlarm" android:process=":remote" />

    <activity android:name=".user_alerts.RegularSchedule"
        android:label="@string/reg_schedule_title" android:theme="@android:style/Theme.Light">
    </activity>

RepeatingAlarm:

public class RepeatingAlarm extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
    NotificationManager mNotificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
.......
    // The PendingIntent to launch our activity if the user selects this notification
    Intent notificationIntent = new Intent (context, DisplayReminder.class);
    PendingIntent contentIntent = PendingIntent.getActivity(context, 0, notificationIntent, 0);

    // Set the info for the views that show in the notification panel.
    notification.setLatestEventInfo(context, contentTitle, contentText, contentIntent);
    notification.defaults |= Notification.DEFAULT_SOUND;
    notification.defaults |= Notification.DEFAULT_VIBRATE;
    notification.defaults |= Notification.DEFAULT_LIGHTS;

    mNotificationManager.notify(2425, notification);

2 个答案:

答案 0 :(得分:28)

这对我有用。我正在分享解决方案,以便其他人可以受益并找到解决此问题的快速解决方案。

我欢迎任何其他意见,以更多地了解解决方案的技术性,以及为什么某些事情有效,而其他事情则不然:)

(1)首先,清单文件: 确保您的班级有接收器具有BroadcastReceiver。

    <receiver android:name=".RepeatingAlarm" android:process=":remote">
        <intent-filter>
            <data android:scheme="timer:" />
        </intent-filter>
    </receiver>

请注意,该课程是主要课程的一部分。如果是在某个子包中,请转到主包。主要包是您在'manifest'标签中定义的。

'intent-filter'用于定义'action'和'data'。您可以将Activity类放在此处,该类将从您的待定意图中调用。但我发现如果你在manifest中定义'action',它就不会在activity上显示动态值。它只显示静态值。很奇怪。如果遇到同样的问题,请不要在清单中放入“action”,而应将其作为待处理意图的一部分放入BroadcastReceiver类中。

'data'标签是您在使用AlarmManager调度不同警报时将唯一意图的动态URI置于其中。有关更多详细信息,请参阅后续步骤。

(2)Activity类,您将在其中使用AlarmManager来安排警报: 我正在使用数据库来存储我的闹钟时间值,然后使用这些值进行调度。我的光标从表中获取唯一的_ID和闹钟时间(自1970年1月1日以来的秒数)。请注意此处放置的URI与清单文件中的URI相同。

    Calendar cal = Calendar.getInstance();
    int notifIterator = 0;

    if (notifCursor.getCount() > 0) {
        while (notifCursor.moveToNext()) {
            Intent intent = new Intent(MySchedule.this,
                    RepeatingAlarm.class);

            // As the same intent cancels the previously set alarm having
            // same intent
            // changing the intent for every alarm event so that every alarm
            // gets
            // scheduled properly.
            intent.setData(Uri.parse("timer:" + notifCursor.getInt(0)));

            PendingIntent sender = PendingIntent.getBroadcast(
                    MySchedule.this, 0, intent,
                    Intent.FLAG_GRANT_READ_URI_PERMISSION);

            cal.setTimeInMillis(notifCursor.getLong(1) * 1000);

            AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE);
            am.set(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), sender);

            notifIterator++;

            Toast mToast = Toast.makeText(
                    RegularSchedule.this,
                    "Reminders added to the calendar successfully for "
                            + android.text.format.DateFormat.format(
                                    "MM/dd/yy h:mmaa",
                                    cal.getTimeInMillis()),
                    Toast.LENGTH_LONG);
            mToast.show();
        }
    }

如果您在执行此操作后仍未看到警报,则检查时区模拟器所需的时间。有时,我们会安排本地时区,但会为GMT时区安排模拟器时间表。如果你看看吐司留言,那将有助于你找出这个问题。

(3)最后一个是BroadcastReceiver类。请注意,要打开数据库,您需要使用“上下文”:

public void onReceive(Context context, Intent intent) {

    // Update the status in the notification database table
    int notificationId = Integer.parseInt(intent.getData().getSchemeSpecificPart());

    db = context.openOrCreateDatabase(DATABASE_NAME,
            SQLiteDatabase.CREATE_IF_NECESSARY, null);

    <<<< Do DB stuff like fetching or updating something>>>>

    // Raise the notification so that user can check the details
    NotificationManager mNotificationManager = (NotificationManager) context
            .getSystemService(Context.NOTIFICATION_SERVICE);

    int icon = R.drawable.icon;
    CharSequence tickerText = "your text";
    long when = System.currentTimeMillis();

    Notification notification = new Notification(icon, tickerText, when);

    // Count of number of notifications
    notification.number = notifCount;

    CharSequence contentTitle = "your title ";
    CharSequence contentText = "your notification text";

    // The PendingIntent to launch our activity if the user selects this
    // notification
    Intent notificationIntent = new Intent(context, DisplayReminder.class);
    PendingIntent contentIntent = PendingIntent.getActivity(context, 0,
            notificationIntent, 0);


    // Set the info for the views that show in the notification panel.
    notification.setLatestEventInfo(context, contentTitle, contentText,
            contentIntent);
    notification.defaults |= Notification.DEFAULT_SOUND;
    notification.defaults |= Notification.DEFAULT_VIBRATE;
    notification.defaults |= Notification.DEFAULT_LIGHTS;

    // Instead of 1234 or any other number, use below expression to have unique notifications
    // Integer.parseInt(intent.getData().getSchemeSpecificPart())
    mNotificationManager.notify(1234, notification);
}

请注意,如果要创建单独的通知,请在调用notify()时将请求ID作为唯一方式传递。

最后,您可以创建在用户点击通知时要调用的DisplayReminder类。

答案 1 :(得分:1)

正如@Jonathon Horsman建议的那样,确保您创建的意图是独一无二的。

如果您要设置10个警报,例如:

for(int i=; i<10; i++) {
   Intent intent = new Intent(YourActivity.this,
                YourAlarm.class);
   intent.setData(Uri.parse("timer:" + i);
   PendingIntent sender = PendingIntent.getBroadcast(
                YourActivity.this, 0, intent,
                Intent.FLAG_GRANT_READ_URI_PERMISSION);
   AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE);
   am.set(AlarmManager.RTC_WAKEUP, yourTimeInMillis, sender);
}

对我来说很好。