2012-04-13 39 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);