Как открыть приложение Календарь в определенном календаре

Я хочу открыть приложение "Календарь" из приложения Android, но с конкретным calendarId.

Мой код:

final Intent calIntent = new Intent(Intent.ACTION_EDIT);
calIntent.setType("vnd.android.cursor.item/event");

startActivityForResult(calIntent, RESULT_CODE_OPEN);

Но намерение открыто с использованием последнего Календаря. Я хочу открыть конкретный с его идентификатором календаря.

Как я могу это сделать?

Ответ 1

Немного истории: Заглядывая в источники приложения Calendar, я нашел этот раздел манифеста, который указывает, что класс обрабатывает Intent.ACTION_EDIT, EditEventActivity.java. Затем я нашел эту строку; calendarId получается из дополнительных данных. так что...

Откройте EditEvent - (ответ на исходный вопрос)

Положите лишний длинный на Intent ключ CalendarContract.Events.CALENDAR_ID и соответствующий calendarId как этот образец:

long calendarId = 1234; // here goes your calendar Id

final Intent calIntent = new Intent(Intent.ACTION_EDIT)
       .setType("vnd.android.cursor.item/event")
       .putExtra(CalendarContract.Events.CALENDAR_ID, calendarId);

startActivityForResult(calIntent, RESULT_CODE_OPEN);

Откройте приложение "Календарь" с недельным просмотром month в конкретном календаре - (ответ на вопрос о голосе - ЧАСТЬ 1)

Этот подход немного отличается. Перед открытием приложения Calendar вы должны сделать невидимыми все календари, но не выбранные. Итак, я создал вспомогательную функцию, чтобы сделать именно это.

private void makeAllCalendarsInvisibleExcept(long calendarId) {
    ContentValues updateValues = new ContentValues();
    updateValues.put(CalendarContract.Calendars.VISIBLE, 0);

    // make all invisible
    getContentResolver().update(CalendarContract.Calendars.CONTENT_URI,
            updateValues, null, null);

    updateValues.clear();
    updateValues.put(CalendarContract.Calendars.VISIBLE, 1);


    // make calendarId visible
    getContentResolver().update(CalendarContract.Calendars.CONTENT_URI,
            updateValues, where, null);
}

А вот как его настроить:

makeAllCalendarsInvisibleExcept(calendarId);
Intent calIntent = new Intent();
// for google calendar, first parameter should be "com.google.android.calendar"
// this is intended for android calendar.
ComponentName cn = new ComponentName("com.android.calendar", "com.android.calendar.LaunchActivity");
calIntent.setComponent(cn);
startActivityForResult(calIntent, 4567);

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

В DemoApp я создал два дополнительных вспомогательных метода для нажатия и восстановления состояния видимости календарей. Посмотрите вокруг pushCalendarVisibility и restoreCalendarVisibility и onActivityResult

Примечание. Я тестировал приложение с установленным календарем Google и без него. AFAIK в Календаре Google отображается только в режиме просмотра DAY, а не в WEEK ни один месяц.

Во всех случаях отображаются только события в выбранном календаре.

Получить calendarId и Account Name - (ответ на вопрос о голосе - ЧАСТЬ 2)

calendarId abd Account Name можно получить с помощью CalendarContract.Calendars, например:

// since API14 
Uri uri = CalendarContract.Calendars.CONTENT_URI;

String[] projection = new String[] {
        CalendarContract.Calendars._ID,
        CalendarContract.Calendars.VISIBLE,
        CalendarContract.Calendars.CALENDAR_ACCESS_LEVEL,
        CalendarContract.Calendars.CALENDAR_DISPLAY_NAME,
        CalendarContract.Calendars.ACCOUNT_NAME,
};

Cursor calendarCursor = getContentResolver().query(uri, projection, null, null, null);
while (calendarCursor.moveToNext()) {

    // calendarId
    long calendarId = calendarCursor.getLong(0);

    // get visibility, warning: if calendar is not visible Intent.ACTION_EDIT doesn't work.
    boolean calendarVisible = calendarCursor.getInt(1) == 1;

    // get if it owned, warning: if calendar is not owned Intent.ACTION_EDIT doesn't work.
    boolean calendarOwned = calendarCursor.getInt(2) == CalendarContract.Calendars.CAL_ACCESS_OWNER;

    // get calendar display name
    String calendarName = calendarCursor.getString(3);

    // get account name
    String accountName = calendarCursor.getString(4);

    // do something

}

Примечание. Существуют более доступные параметры для прогноза календаря, рекомендации, прочитанные CalendarContract.Calendars

Ограничения

Эти функции доступны с API уровня 14, Android 4.0 (ICE_CREAM_SANDWICH)

Демо-приложение

Заполните пример в этот репозиторий GitHub. (Проект Android Studio 1.0.0) Требуется, чтобы календари синхронизировались и должны принадлежать учетной записи и должны быть видимыми. UPDATE: пример обновлен

Протестировано на Android 4.1.1 и Android 5.0 Lollipop Preview