使用 Android 日历提供商创建全天活动
Creating All-Day Events Using Android Calendar Provider
我希望我的应用程序能够将全天活动插入到日历中。我从 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.
。什么是正确的价值观?只是随意如上或could/should这实际上是用有意义的信息完成的吗?
DTEND
不是多余的,因为它指定了事件的结束。 all-day 并不意味着只有一天。它可以跨越任意天数。 全天 表示事件的开始和结束没有时间部分。特别是,活动总是在一天开始时开始,无论您当时实际位于哪个时区。一个常见的例子是你的生日。您通常会在特定的日历日庆祝它,无论您身在何处。
请注意,在 Android 的日历数据库中,DTSTART
和 DTEND
应表示 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
.
将CalendarContract.Events.DTEND替换为CalendarContract.Events.DURATION
第二个参数格式见RFC5545
values.put(CalendarContract.Events.DURATION, "PT1D");
不要在使用DURATION的时候使用DTEND,否则会抛出异常:不能在一个事件中同时拥有DTEND和DURATION
我希望我的应用程序能够将全天活动插入到日历中。我从 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.
。什么是正确的价值观?只是随意如上或could/should这实际上是用有意义的信息完成的吗?
DTEND
不是多余的,因为它指定了事件的结束。 all-day 并不意味着只有一天。它可以跨越任意天数。 全天 表示事件的开始和结束没有时间部分。特别是,活动总是在一天开始时开始,无论您当时实际位于哪个时区。一个常见的例子是你的生日。您通常会在特定的日历日庆祝它,无论您身在何处。
请注意,在 Android 的日历数据库中,DTSTART
和 DTEND
应表示 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
.
将CalendarContract.Events.DTEND替换为CalendarContract.Events.DURATION
第二个参数格式见RFC5545
values.put(CalendarContract.Events.DURATION, "PT1D");
不要在使用DURATION的时候使用DTEND,否则会抛出异常:不能在一个事件中同时拥有DTEND和DURATION