【问题标题】:Creating All-Day Events Using Android Calendar Provider使用 Android 日历提供程序创建全天事件
【发布时间】:2016-05-26 20:55:16
【问题描述】:

我希望我的应用程序将全天事件插入日历。我从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.。什么是正确的价值观?只是像上面那样随意,还是可以/应该用有意义的信息来完成?

【问题讨论】:

    标签: java android android-contentprovider android-calendar


    【解决方案1】:

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

    请注意,在 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

    【讨论】:

    • 优秀的答案。谢谢。
    【解决方案2】:

    将 CalendarContract.Events.DTEND 替换为 CalendarContract.Events.DURATION

    第二个参数格式见RFC5545

    values.put(CalendarContract.Events.DURATION,  "PT1D");
    

    在使用 DURATION 时不要使用 DTEND,否则会抛出异常:不能在一个事件中同时拥有 DTEND 和 DURATION

    【讨论】:

    • 谢谢。有用的附加信息,但不能真正回答问题。
    猜你喜欢
    • 2020-12-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多