2012-04-13 84 views
9

我正在尝试使用Android的新日历API来阅读今日的所有日历活动。我无法在数据库查询上找到正确的选择来返回所有事件。似乎所有经常性事件和全天事件都被排除在选择之外。什么选择参数可以让我从日历api中获取当前所有的事件?使用CalendarContract阅读今日所有活动 - Android 4.0+

这里是我当前的尝试:

Cursor cur = null; 
    String selection = "((" + CalendarContract.Events.DTSTART 
      + " >= ?) AND (" + CalendarContract.Events.DTEND + " <= ?))"; 
    Time t = new Time(); 
    t.setToNow(); 
    String dtStart = Long.toString(t.toMillis(false)); 
    t.set(59, 59, 23, t.monthDay, t.month, t.year); 
    String dtEnd = Long.toString(t.toMillis(false)); 
    String[] selectionArgs = new String[] { dtStart, dtEnd }; 
    cur = c.getContentResolver().query(CalendarContract.Events.CONTENT_URI, 
      null, selection, selectionArgs, null); 

我不确定如何拓宽选择或增加它来获得经常性事件和全天事件。任何帮助,将不胜感激。

+1

你有没有想过呢?我遇到了同样的问题 – MobileMon 2012-10-25 19:13:31

+0

我找到了解决方案。我会立即张贴 – 2012-10-26 00:32:47

+0

@MobileMon我已经发布了答案。干杯! :D – 2012-10-26 01:14:07

回答

18

要获得所有活动今天,包括重复发生的事件,您需要使用实例表,即

Uri.Builder eventsUriBuilder = CalendarContract.Instances.CONTENT_URI 
      .buildUpon(); 
ContentUris.appendId(eventsUriBuilder, timeNow); 
ContentUris.appendId(eventsUriBuilder, endOfToday); 
Uri eventsUri = eventsUriBuilder.build(); 
Cursor cursor = null;  
cursor = mContext.getContentResolver().query(eventsUri, columns, null, null, CalendarContract.Instances.DTSTART + " ASC"); 

注意您必须将时间限制附加到事件uri上,您无法以其他方式排序。

为了包括全天活动,只需将搜索范围扩展到今晚晚上11:59 PM和今晚12:00 AM。

+0

我可以把什么“列”? – TamarG 2016-08-02 08:12:12

2

您应该可以将CalendarContract.Events.ALL_DAY添加到您的选择条件以过滤所有ALL_DAY事件。

+0

我还没有找到经常性事件,因为他们不是显示为当前日期的一部分。重复事件如何存储? – 2012-05-23 16:17:20

+1

@BananaNutTruffles重复发生的事件也在Instances表中镜像。这与仅包含定义“实例”序列的初始事件的Events表格形成对比。 – Moritz 2012-05-28 10:26:37

5

您的条件只会给你严格限制的事件。你应该检查在今天之前开始和结束之后(多天事件)。

对于重复性事件,我手动检查它们。我没有找到另一种方式。

我使用类似:

String selection = "((" + CalendarContract.Events.DTSTART + " <= ?) AND (" + CalendarContract.Events.DTEND + " >= ?)) OR (" + CalendarContract.Events.RRULE + " is not null)"; 

String[] selectionArgs = new String[] { dtEnd, dtStart}; 

问候,

+4

要包含周期性事件,您必须查询[CalendarContracts.Instance](http://developer.android.com/reference/android/provider/CalendarContract。Instances.html)类。 – 2013-03-03 18:48:13

2

我知道这有点晚,但我有一个非常类似的问题,并无法找到我正在寻找的答案。全天事件的强制UTC时区使事情变得棘手。这里是我的解决方案:

// "allDayStart" is an all-day event today, encoded in the default time zone 
    Time allDayStart = new Time(); 
    allDayStart.timezone=TimeZone.getDefault().toString(); 
    allDayStart.set(dayStart.monthDay, dayStart.month, dayStart.year); 

    // 2 time selections for the query: 
     // 1) Between day-start and day-end (not all-day); or 
     // 2) Equals today at 0:00:00 (all-day) in the default timezone 
    String calSelection = 
     "((" + Calendars.ACCOUNT_NAME + " = ?) " + 
      "AND (" + Calendars.OWNER_ACCOUNT + "= ?) " + 
      "AND (" + 
       "((" + Events.DTSTART + ">= ?) " + 
       "AND (" + Events.DTSTART + "<= ?) " + 
       "AND (" + Events.ALL_DAY + "= ?) " + 
       ") " + 
      "OR ((" + Events.DTSTART + "= ?) " + 
       "AND (" + Events.ALL_DAY + "= ?)" + 
       ")" + 
      ")" + 
     ")"; 

    String[] calSelectionArgs = new String[] { 
     accountName, ownerName, 
     dayStartInMillis.toString(), dayEndInMillis.toString(), "0", // during today, not all day 
     allDayStartInMillis.toString(), "1" // Started today at default start-time for all-day events (all-day), default time zone 
    }; 

的查询可以细化到不需要两个部分,但是这对我来说不够好。

万一有帮助,这里的地方一天开始和dayEnd来自何处:

Time dayStart = new Time(); 
    dayStart.setToNow(); 
    dayStart.hour=0; 
    dayStart.minute=0; 
    dayStart.second=0; 

    Time dayEnd = new Time(); 
    dayEnd.set(dayStart); 
    dayEnd.hour=dayStart.hour+23; 
    dayEnd.minute=dayStart.minute+59; 
    dayEnd.second=dayStart.second+59; 

    Long dayStartInMillis = dayStart.toMillis(false); 
    Long dayEndInMillis = dayEnd.toMillis(false) + 999; 
    Long allDayStartInMillis = allDayStart.toMillis(false);