Android 日历创建一种递归

Android calendar create kind of recursion

我在以编程方式向 Google 日历添加事件时遇到问题。

代码如下:

private void addToGoogleCalendar(long beginTime) {
    ContentValues event = new ContentValues();
    Observable.from(dataKeeper.getCalendarIds().keySet()).filter(key -> dataKeeper.getCalendarIds().get(key).equals(defaultCalendarName.getText().toString())).forEach(key ->
            event.put(CalendarContract.Reminders.CALENDAR_ID, Integer.parseInt(key))
    );

    event.put(CalendarContract.Reminders.TITLE, reminderName.getText().toString());

    if (!TextUtils.isEmpty(commentEdittext.getText().toString()))
        event.put(CalendarContract.Reminders.DESCRIPTION, commentEdittext.getText().toString());

    event.put(CalendarContract.Reminders.EVENT_TIMEZONE, TimeZone.getDefault().getID());
    event.put(CalendarContract.Reminders.DTSTART, beginTime);
    event.put(CalendarContract.Reminders.DTEND, dataKeeper.getEnd());
    event.put(CalendarContract.Reminders.EVENT_COLOR, getResources().getColor(R.color.primary));

    // http://tools.ietf.org/html/rfc2445
    if (dataKeeper.getPeriod() > 0 && dataKeeper.getPeriod() != 7)
        event.put(CalendarContract.Reminders.RRULE, String.format("FREQ=DAILY;INTERVAL=%d;UNTIL=%s", dataKeeper.getPeriod() - 1,
                new SimpleDateFormat("yyyyMMdd", Locale.getDefault()).format(dataKeeper.getEnd())));
    else if (dataKeeper.getPeriod() == 7)
        event.put(CalendarContract.Reminders.RRULE, String.format("FREQ=WEEKLY;INTERVAL=1;UNTIL=%s",
                new SimpleDateFormat("yyyyMMdd", Locale.getDefault()).format(dataKeeper.getEnd())));

    event.put(CalendarContract.Reminders.ALL_DAY, 1); // 0 for false, 1 for true
    event.put(CalendarContract.Reminders.STATUS, CalendarContract.Events.STATUS_CONFIRMED);

    String eventUriString = "content://com.android.calendar/events";
    getContentResolver().insert(Uri.parse(eventUriString), event);
}

中断 = 1

所以,当我添加事件时,它会根据需要添加,但在几秒钟后我看到该事件递归添加。第一天一次,第二天两次,依此类推

方法只调用了一个,所以我不知道 WTF 会发生什么。

您已将主实例的结尾设置为重复规则的结尾。

第一个实例的持续时间为 dataKeeper.getEnd() - beginTime。根据 RRULE 此实例每天重复出现,直到 dataKeeper.getEnd()

现在,如果 dataKeeper.getEnd()beginTime 几天后,尽管第一个实例在第二天仍在进行(因为它持续了多天),但另一个实例开始于那天。

第三天,前两个实例仍在进行中,规则说另一个应该开始。

因此在RRULEUNTIL日期之前添加了一个实例,之后实例的数量每天减少一个。

要修复它,请确保第一个实例只有一天的时间。替换

event.put(CalendarContract.Reminders.DTEND, dataKeeper.getEnd());

来自

event.put(CalendarContract.Events.DURATION, "P1D");

这会将每个实例的持续时间设置为 1 天。无论如何,您应该始终对重复事件使用 DURATION,请参阅 Events.

顺便说一句,您还应该使用 CalendarContract.Events 而不是 CalendarContract.Reminders。尽管 Reminders 也实现了 EventsColumns,但它是用于警报的。我猜它包含事件列,因为它有效地从两个表的连接中读取。