我希望我的应用将全天活动插入日历。我从https://developer.android.com/guide/topics/providers/calendar-provider.html给出的示例开始。为了全天候工作,我添加了ALL_DAY内容值,并将时区设置为UTC。我最终得到以下代码:

long calID = 3;
long startMillis = 0;
long endMillis = 0;
Calendar beginTime = Calendar.getInstance();
beginTime.set(2012, 9, 14, 7, 30);
startMillis = beginTime.getTimeInMillis();
Calendar endTime = Calendar.getInstance();
endTime.set(2012, 9, 14, 8, 45);
endMillis = endTime.getTimeInMillis();

ContentResolver cr = getContentResolver();
values.put(Events.ALL_DAY, 1)
ContentValues values = new ContentValues();
values.put(Events.DTSTART, startMillis);
values.put(Events.DTEND, endMillis);
values.put(Events.TITLE, "Jazzercise");
values.put(Events.DESCRIPTION, "Group workout");
values.put(Events.CALENDAR_ID, calID);
values.put(Events.EVENT_TIMEZONE, "UTC");
Uri uri = cr.insert(Events.CONTENT_URI, values);


现在,这确实可以完成工作,但是DTEND时间似乎是多余的,并且当实际上只需要日期时,设置开始和结束时间毫无意义。删除DTEND值时,出现异常java.lang.IllegalArgumentException: DTEND and DURATION cannot both be null for an event.。正确的值是多少?如上所述只是武断,还是可以/应该用有意义的信息来完成?

最佳答案

DTEND不是多余的,因为它指定事件的结束。一整天并不意味着只有一天的时间。它可以跨越任何天数。全天意味着事件的开始和结束没有时间成分。特别是,事件总是在一天开始时开始,无论您当时实际位于哪个时区。一个常见的例子是你的生日。无论您身在何处,通常都会在特定的日历日庆祝它。

请注意,在Android的日历数据库中,DTSTARTDTEND应该代表UTC中该特定日期的午夜。

因此,得出开始日期和结束日期的更好方法是:

TimeZone utc = TimeZone.getTimeZone("UTC");
Calendar beginTime = Calendar.getInstance(utc);
// set all values to 0
beginTime.clear();
beginTime.set(2012, 9, 14);
startMillis = beginTime.getTimeInMillis();

Calendar endTime = Calendar.getInstance(utc);
// the event ends right before the next day begins
endTime.clear();
endTime.set(2012, 9, 15);
endMillis = endTime.getTimeInMillis();


另请注意,DTEND是非包含性的(指向事件之后的第一刻)。对于一天的全天活动,这表示DTEND是第二天的开始。

确定事件结束的另一种方法是将事件的持续时间添加到DTSTART中,如下所示:

// Add the duration of 1 day to startMillis to get the end
endMillis = startMillis + TimeUnit.DAYS.toMillis(1);


结果与上面相同。

请注意,这是创建非重复事件的方法。如果创建重复事件,则不能将DTEND设置为DURATION

07-26 02:51