Чтение всех сегодняшних событий с помощью CalendarContract — Android 4.0+

Я пытаюсь использовать новый API календаря Android для чтения всех сегодняшних событий календаря. У меня возникли проблемы с поиском правильного выбора в запросе к базе данных, чтобы вернуть все события. Кажется, что все повторяющиеся события и события на весь день исключены из выбора. Какие аргументы выбора позволят мне получить все сегодняшние события из API календаря?

Вот моя текущая попытка:

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

Я не уверен, как расширить выбор или добавить к нему, чтобы получить повторяющиеся события и события на весь день. Любая помощь будет оценена по достоинству.


person Zaid Daghestani    schedule 13.04.2012    source источник
comment
Вы уже поняли это??? Я застрял с той же проблемой   -  person MobileMon    schedule 25.10.2012
comment
Я нашел решение. выложу моментально   -  person Zaid Daghestani    schedule 26.10.2012
comment
@MobileMon Я опубликовал ответ. Ваше здоровье! :D   -  person Zaid Daghestani    schedule 26.10.2012
comment
проверьте: stackoverflow.com/questions/26844770/   -  person Erdinc Ay    schedule 11.11.2014


Ответы (5)


Чтобы получить все события сегодня, включая повторяющиеся события, вам нужно использовать таблицу Instances, т.е.

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 событий, вы не можете сортировать каким-либо другим способом.

Чтобы включить события всего дня, просто расширьте поиск до 23:59 предыдущей ночи и 00:00 сегодня.

person Zaid Daghestani    schedule 26.10.2012
comment
что можно поставить на колонки? - person TamarG; 02.08.2016

Ваши условия дают вам только те события, которые находятся строго в сегодняшних пределах. Вы должны проверить те, которые начинаются до сегодняшнего дня и заканчиваются после (многодневное событие).

Повторяющиеся события я проверяю вручную. Я не нашел другого способа.

Я использую что-то вроде:

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

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

С уважением,

person SebastienS    schedule 09.09.2012
comment
Чтобы включить повторяющиеся события, необходимо запросить CalendarContracts.Instance. класс. - person Some Noob Student; 03.03.2013

вы должны иметь возможность добавить CalendarContract.Events.ALL_DAY к условию выбора для фильтрации всех событий ALL_DAY.

person Moritz    schedule 05.05.2012
comment
Мне еще предстоит найти повторяющиеся события, поскольку они не отображаются как часть текущей даты. Как сохраняются повторяющиеся события? - person Zaid Daghestani; 23.05.2012
comment
@BananaNutTruffles повторяющиеся события также отражаются в таблице экземпляров. В отличие от таблицы Events, которая содержит только начальное событие, определяющее последовательность экземпляров. - person Moritz; 28.05.2012

Я знаю, что это немного поздно, но у меня был очень похожий вопрос, и мне было трудно найти ответ, который я искал. Принудительный часовой пояс 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
    }; 

Запрос можно было бы уточнить, чтобы не нужно было 2 части, но мне этого было достаточно.

Если это поможет, вот откуда взялись dayStart и 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);
person brbaker    schedule 18.09.2013

Попробуйте использовать Instances.CONTENT_BY_DAY_URI. Проверьте этот ответ для примера - https://stackoverflow.com/a/36622111/1219241

person alcsan    schedule 18.04.2016