Есть ли способ получить доступ к записям календаря без использования gdata-java-client? - PullRequest
3 голосов
/ 11 мая 2009

Можно ли получить записи календаря с телефона в автономном режиме? Кажется, единственный способ - использовать gdata-java-client .

Ответы [ 7 ]

9 голосов
/ 18 октября 2010

Решения Йозефа и Исаака для доступа к календарю работают только в Android 2.1 и более ранних версиях. Google изменил базовый URI контента в 2.2 с «content: // calendar» на «content: //com.android.calendar». Это изменение означает, что наилучшим подходом является попытка получить курсор, используя старый базовый URI, и, если возвращаемый курсор равен нулю, тогда попробуйте новый базовый URI.

Обратите внимание, что я получил этот подход из кода с открытым исходным кодом , который Шейн Кондер и Лорен Дарси предоставляют в статье Работа с календарем Android .

private final static String BASE_CALENDAR_URI_PRE_2_2 = "content://calendar";
private final static String BASE_CALENDAR_URI_2_2 = "content://com.android.calendar";
/*
 * Determines if we need to use a pre 2.2 calendar Uri, or a 2.2 calendar Uri, and returns the base Uri
 */
private String getCalendarUriBase() {
    Uri calendars = Uri.parse(BASE_CALENDAR_URI_PRE_2_2 + "/calendars");
    try {
        Cursor managedCursor = managedQuery(calendars, null, null, null, null);
        if (managedCursor != null) {
            return BASE_CALENDAR_URI_PRE_2_2;
        }
        else {
            calendars = Uri.parse(BASE_CALENDAR_URI_2_2 + "/calendars");
            managedCursor = managedQuery(calendars, null, null, null, null);

            if (managedCursor != null) {
                return BASE_CALENDAR_URI_2_2;
            }
        }
    } catch (Exception e) { /* eat any exceptions */ }

    return null; // No working calendar URI found
}
8 голосов
/ 28 февраля 2011

Эти ответы хороши, но все они связаны с жестким кодированием Calendar URI (которое я видел в трех разных воплощениях на разных устройствах Android).

Лучший способ получить это URI (который вместо этого жестко кодирует имя класса и поля) будет выглядеть примерно так:

Class<?> calendarProviderClass = Class.forName("android.provider.Calendar");
Field uriField = calendarProviderClass.getField("CONTENT_URI");
Uri calendarUri = (Uri) uriField.get(null);

Это не идеально (оно сломается, если они когда-либо удалят класс android.provider.Calendar или поле CONTENT_URI), но оно работает на большем количестве платформ, чем любой жесткий код URI.

Обратите внимание, что эти методы отражения будут генерировать exceptions, который должен быть перехвачен или переброшен вызывающим методом.

3 голосов
/ 20 мая 2009

В настоящее время это невозможно без использования частных API (см. Сообщение Йозефа). Есть поставщик Календаря, но он еще не открыт Это может измениться в любое время и сломать ваше приложение.
Хотя, вероятно, это не изменится (я не думаю, что они изменят его с «календаря»), так что вы можете использовать его. Но я рекомендую использовать отдельный класс, подобный этому:

public class CalendarProvider {
     public static final Uri CONTENT_URI = Uri.parse("content://calendar");
     public static final String TITLE = "title";
     public static final String ....

И используйте их вместо строк напрямую. Это позволит вам очень легко изменить его, если / когда API изменится или станет общедоступным.

3 голосов
/ 13 мая 2009

Вы можете использовать контент-провайдера календаря (com.android.providers.calendar.CalendarProvider). Пример:


ContentResolver contentResolver = context.getContentResolver();
Cursor cursor = contentResolver.query(Uri.parse("content://calendar/events"), null, null, null, null);

while(cursor.moveToNext()) {
    String eventTitle = cursor.getString(cursor.getColumnIndex("title"));
    Date eventStart = new Date(cursor.getLong(cursor.getColumnIndex("dtstart")));
    // etc.
}

edit : вы можете поместить это в оболочку (см. сообщение Исаака ), так как в настоящее время это частный API.

2 голосов
/ 03 февраля 2013

Вы можете использовать CalendarContract здесь: https://github.com/dschuermann/android-calendar-compatibility

Это тот же класс API, который доступен в Android 4, но предназначен для работы с Android> = 2.2.

1 голос
/ 13 марта 2011

Решение Ника включает в себя managedQuery, который не определен в классе Context. Много раз, когда вы запускаете вещи в фоновом режиме, вы захотите использовать объект контекста. Вот модифицированная версия:

public String getCalendarUriBase () {

return (android.os.Build.VERSION.SDK_INT> = 8)? "Содержание: //com.android.calendar": "Содержание: // календарь"; }

Улавливать для нуля здесь не следует, поскольку может быть больше исключений, даже если удалось выполнить управляемый запрос раньше.

1 голос
/ 10 июля 2010

Об API, который может меняться ... Весь подход ContentProvider не изменится так быстро, поэтому уже может решить множество проблем, только обновляя строки. Для этого создайте константы, которые вы повторно используете для всего проекта.

public static final String URI_CONTENT_CALENDAR_EVENTS = "content://calendar/events";

ContentResolver contentResolver = context.getContentResolver();
Cursor cursor = contentResolver.query(Uri.parse(URI_CONTENT_CALENDAR_EVENTS), null, null, null, null);
    //etc

Если вам нужен правильный частный API, вам нужно создать pojo и некоторые сервисы, подобные этому:

public class CalendarEvent {
    private long id;
    private long date;
    //etc...
}

public interface CalendarService {

    public Set<CalendarEvent> getAllCalendarEvents();

    public CalendarEvent findCalendarEventById(long id);

    public CalendarEvent findCalendarEventByDate(long date);

}

и так далее. Таким образом, вам нужно будет только обновить объект CalendarEvent и эту службу в случае изменения API.

...