警报管理器 - 调度多个非重复事件 [英] Alarm Manager - Scheduling multiple Non-repeating events

查看:19
本文介绍了警报管理器 - 调度多个非重复事件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在 Android 闹钟管理器中,我们如何安排多个不重复且没有固定间隔重复的闹钟?我无法使用setRepeating"功能,因为警报没有任何重复模式.

In Android Alarm Manager, how can we schedule multiple alarms which are non-repeating and do not have fixed intervals to repeat? I cannot use 'setRepeating' function as the alarms don't have any repeating pattern.

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

I have the alarm times stored in Sqlite database table and the activity should pick the date and time from this table and set the alarms.

如果我们在一个循环中设置不同的闹钟,那么它只会保留最后一个.我从帖子中读到:如何创建多个警报?

If we setup different alarms in a loop, then it retains only the last one. I read from the post: How can create more than one alarm?

它告诉将唯一的 Id 附加到意图,然后设置单独的警报事件.但它对我不起作用.

It tells to attach the unique Id to the intent and then setting up individual alarm events. But it didn't work for me.

我们需要在 Manifest 文件中添加一些东西来处理这个唯一的 id 吗?

Is there something we need to add in Manifest file to take care of this unique id?

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

The code in the activity 'RegularSchedule' is and it creates only one alarm event:

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

如果需要更多详细信息或代码片段,请告诉我.

Please let me know if further details or code snippets are required.

清单文件(这里 RepeatingAlarm 扩展了 BroadcastReceiver):

Manifest file (here RepeatingAlarm extends 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>

重复报警:

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

推荐答案

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

This is what worked for me. I'm sharing the solution so that others can benefit and find quick solution to this problem.

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

I welcome any other inputs to throw more light on the technicality of the solution and why certain things work and others don't :)

(1) 首先,Manifest 文件:确保你的班级有接收器,有 BroadcastReceiver.

(1) First of all, Manifest file: Make sure that you have receiver for your class having BroadcastReceiver.

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

请注意,该类是主包的一部分.如果它在某个子包中,请移到主包中.主包是你在'manifest'标签中定义的.

Please note that the class is part of main package. If it is in some sub-package, please move to the main package. The main package is what you define in 'manifest' tag.

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

'intent-filter' is used to define 'action' and 'data'. You can put the Activity class here which is going to be called from your pending intent. But I found that if you define 'action' in manifest, it doesn't display dynamic values on the activity. It just shows static values. Quite strange. If you get in same issue, don't put 'action' in manifest, rather put it in BroadcastReceiver class as part of pending intent.

'data' 标签是您将在使用 AlarmManager 安排不同警报时放置唯一意图的动态 URI 的内容.有关详细信息,请参阅后续步骤.

'data' tag is what you are going to put dynamic URI of unique intents while scheduling different alarms using AlarmManager. Please refer next steps for more details.

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

(2) Activity Class in which you are going to use AlarmManager to schedule alarms: I'm using the database to store my alarm time values and then scheduling using those values. My cursor fetches the unique _ID from the table and alarm time (in seconds since 1/1/1970). See that the URI put here is same as what you have in manifest file.

    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 时区.如果您查看 toast 消息,这将帮助您解决这个问题.

If you don't see alarms even after doing this, check the timezone which emulator takes. Sometimes, we schedule for Local Timezone, but emulator schedules for GMT timezone. If you look at toast message, that will help you figure out this problem.

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

(3) Last one is BroadcastReceiver class. Please note that to open database, you will require to use the 'context':

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 作为唯一传递.

Note that if you want to create separate notification, the request id can be passed as unique when calling notify().

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

Finally, you can create DisplayReminder class which you want to call when user clicks on notification.

这篇关于警报管理器 - 调度多个非重复事件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆