2012-04-13 27 views
9

Tôi đang cố gắng sử dụng API lịch mới của Android để đọc tất cả các sự kiện lịch của ngày hôm nay. Tôi gặp khó khăn khi tìm lựa chọn đúng trên truy vấn cơ sở dữ liệu để trả về tất cả các sự kiện. Có vẻ như tất cả các sự kiện lặp lại và cả ngày đều bị bỏ trống. Lựa chọn nào args sẽ cho phép tôi để có được tất cả các sự kiện của ngày hôm nay từ api lịch?Đọc tất cả các sự kiện của ngày hôm nay bằng cách sử dụng CalendarContract - Android 4.0+

Đây là nỗ lực hiện tại của tôi:

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); 

Tôi không chắc chắn làm thế nào để mở rộng sự lựa chọn hoặc thêm vào nó để có được những sự kiện định kỳ và tất cả các sự kiện trong ngày. Bất kỳ trợ giúp sẽ được đánh giá cao.

+1

Bạn đã tìm ra điều này chưa? Tôi đang mắc kẹt với cùng một vấn đề – MobileMon

+0

Tôi đã tìm ra giải pháp. Tôi sẽ đăng nó trong giây lát –

+0

@MobileMon Tôi đã đăng câu trả lời. Chúc mừng! : D –

Trả lời

18

Để có được tất cả các sự kiện ngày hôm nay, bao gồm các sự kiện định kỳ, bạn cần phải sử dụng bảng Instances, tức là

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"); 

Lưu ý rằng bạn phải nối thêm các ràng buộc thời gian vào các sự kiện uri, bạn không thể sắp xếp theo bất kỳ cách nào khác.

Để bao gồm tất cả các sự kiện trong ngày, chỉ cần mở rộng tìm kiếm đến 11:59 tối đêm trước và 12:00 tối nay.

+0

Tôi có thể đặt gì trên "cột"? – TamarG

2

bạn sẽ có thể thêm CalendarContract.Events.ALL_DAY vào điều kiện lựa chọn của mình để lọc cho tất cả các sự kiện ALL_DAY.

+0

Tôi chưa tìm thấy sự kiện lặp lại vì chúng không hiển thị là một phần của ngày hiện tại. Các sự kiện định kỳ được lưu trữ như thế nào? –

+1

@BananaNutTruffles sự kiện reoccuring cũng được nhân đôi trong bảng Instances. Điều đó trái ngược với bảng Sự kiện chỉ chứa sự kiện ban đầu xác định chuỗi "phiên bản". – Moritz

5

Điều kiện của bạn chỉ cung cấp cho bạn các sự kiện có giới hạn nghiêm ngặt trong ngày hôm nay. Bạn nên kiểm tra những cái bắt đầu trước ngày hôm nay và kết thúc sau (sự kiện nhiều ngày).

Đối với các sự kiện định kỳ, tôi kiểm tra chúng theo cách thủ công. Tôi không tìm thấy cách khác.

tôi sử dụng một cái gì đó như:

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

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

Kính trọng,

+4

Để bao gồm các sự kiện lặp lại, người ta phải truy vấn [CalendarContracts.Instance] (http://developer.android.com/reference/android/provider/CalendarContract.Instances.html) lớp. –

2

Tôi biết điều này hơi trễ một chút, nhưng tôi đã có một câu hỏi rất giống và gặp khó khăn khi tìm câu trả lời tôi đang tìm kiếm. Múi giờ bắt buộc-UTC cho các sự kiện cả ngày khiến mọi việc trở nên phức tạp. Đây là giải pháp của tôi:

// "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 
    }; 

Truy vấn có thể được tinh chỉnh để không cần 2 phần, nhưng điều này là đủ tốt đối với tôi.

Trong trường hợp nó giúp, đây là nơi dayStart và dayEnd đến từ:

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);