android - 警报管理器 - 安排多个非重复事件

标签 android android-alarms

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

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

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

它告诉将唯一 ID 附加到 Intent ,然后设置单独的警报事件。但这对我不起作用。

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

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

如果需要更多详细信息或代码 fragment ,请告诉我。

list 文件(此处为 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>

重复警报:

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

最佳答案

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

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

(1) 首先,Manifest 文件: 确保您的类(class)拥有 BroadcastReceiver 的接收器。

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

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

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

'data' 标签是您在使用 AlarmManager 调度不同警报时要放置的唯一 Intent 的动态 URI。请参阅后续步骤了解更多详情。

(2) Activity 类,您将在其中使用 AlarmManager 来安排警报: 我正在使用数据库来存储我的闹钟时间值,然后使用这些值进行调度。我的光标从表中获取唯一的 _ID 和警报时间(自 1970 年 1 月 1 日以来的秒数)。看到放在这里的 URI 和你在 list 文件中的一样。

    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 消息,这将帮助您解决此问题。

(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 类。

关于android - 警报管理器 - 安排多个非重复事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6649402/

相关文章:

android - 如何获取所有单列值然后将其传递给 String[]?

android - 获取 GCM 时如何在锁定屏幕(如 Android 闹钟)上显示弹出对话框

android - 为一周中的特定日子重复闹钟android

android - AlarmManager 是否需要 WakefulBroadcastReceiver(或等效)

android - 在android中每周重复一次闹钟

android - 如何淡出 TextView 中最后一行的结尾?

java - Android SDK Extras/目录丢失

android - 我应该从 android studio 中的 sdk 管理器安装哪些软件包

android - 当其中一个模块使用 Multidex 时,在没有 Clean 的情况下在两个模块的运行配置之间切换

android - 使用 Android 跟踪多个警报