Создание календаря с поставщиком контента Android 4.0 (ICS) - PullRequest
4 голосов
/ 18 февраля 2012

Я пытаюсь создать календарь с помощью нового поставщика контента ICS для календарей. Поскольку создание календаря может быть выполнено только в SyncAdapter, я создал его:

public class CalendarSyncAdapter extends AbstractThreadedSyncAdapter 
{

    public CalendarSyncAdapter(Context context, boolean autoInitialize)
    {
        super(context, autoInitialize);
    }

    @Override
    public void onPerformSync(Account account, Bundle extras, String authority, ContentProviderClient provider, SyncResult syncResult)
    {
        Log.i( Debug.TAG, "onPerformSync()" );
    }

    public void doCreateCalendar( Account account )
    {
            ContentResolver cr = getContext().getContentResolver();

            ContentValues values = new ContentValues();
            values.put(Calendars.ACCOUNT_NAME, account.name);
            values.put(Calendars.ACCOUNT_TYPE, account.type);
            values.put(Calendars.NAME, "newesttest");
            values.put(Calendars.CALENDAR_DISPLAY_NAME, "newestTest");
            values.put(Calendars.CALENDAR_COLOR, 0xFFFFFFFF);
            values.put(Calendars.CALENDAR_ACCESS_LEVEL, Calendars.CAL_ACCESS_OWNER );
            values.put(Calendars.OWNER_ACCOUNT, account.name);

            values.put(Calendars.SYNC_EVENTS, 1);
            values.put(Calendars.VISIBLE, 1);

            Uri creationUri = asSyncAdapter( Calendars.CONTENT_URI, account.name, account.type );
            Uri created = cr.insert( creationUri, values );
            long id = Long.parseLong( created.getLastPathSegment() );

            Log.i( Debug.TAG, "Calendar created: " + id + " - " + created );
    }

    private Uri asSyncAdapter( Uri uri, String account, String accountType )
    {
        return uri.buildUpon()
        .appendQueryParameter(CalendarContract.CALLER_IS_SYNCADAPTER,"true")
        .appendQueryParameter(Calendars.ACCOUNT_NAME, account)
        .appendQueryParameter(Calendars.ACCOUNT_TYPE, accountType).build();
    }
}

Но он не запускается внутри Сервиса, как я вижу везде, так как все, что я хочу, - это использовать его для вставки нового Календаря. Запуск в службе не требуется, не так ли? Не похоже.

В любом случае, я создаю его экземпляр в своей Activity и вызываю мой метод:

public void createCalendar( View v )
{
    m_syncAdapter.doCreateCalendar( this, m_account );
}

Выполняется успешно, претензий нет, но возвращаемый URI всегда одинаков. Когда я анализирую его по идентификатору строки, его всегда 12. И когда я проверяю свои календари, ничего нового.

В моем манифесте у меня есть все настройки:

...

<application

...

    <activity android:name="Setup" android:label="@string/activity_title_setup">
        <intent-filter>
            <action android:name="android.content.SyncAdapter" />
        </intent-filter>
        <meta-data android:name="android.content.SyncAdapter" android:resource="@xml/calendar_sync_adapter" />
    </activity>

И calendar_sync_adapter.xml:

<?xml version="1.0" encoding="utf-8"?>
<sync-adapter xmlns:android="http://schemas.android.com/apk/res/android"
   android:contentAuthority="com.android.calendar"
   android:accountType="com.google"
   android:userVisible="true"
/>

Так что не уверен, что я здесь делаю не так. Но вот что я вижу в логах, когда выполняю:

02-17 16:43:07.783: I/ActivityManager(184): Start proc com.android.providers.calendar for content provider com.android.providers.calendar/.CalendarProvider2: pid=20132 uid=10008 gids={3003, 1015}
02-17 16:43:07.806: I/ActivityThread(20132): Pub com.android.calendar: com.android.providers.calendar.CalendarProvider2
02-17 16:43:07.869: I/ActivityManager(184): Start proc com.google.android.calendar for service com.google.android.calendar/com.google.android.syncadapters.calendar.CalendarSyncAdapterService: pid=20145 uid=10007 gids={3003}
02-17 16:43:07.900: I/ActivityThread(20145): Pub com.google.android.calendar.CalendarRecentSuggestionsProvider: com.android.calendar.CalendarRecentSuggestionsProvider

// This is my print of the returned URI
02-17 16:43:08.009: I/C3(19995): Calendar created: 12 - content://com.android.calendar/calendars/12?caller_is_syncadapter=true&account_name=xxx%40gmail.com&account_type=com.google

02-17 16:43:08.876: I/CalendarProvider2(20132): Sending notification intent: Intent { act=android.intent.action.PROVIDER_CHANGED dat=content://com.android.calendar }
02-17 16:43:08.876: W/ContentResolver(20132): Failed to get type for: content://com.android.calendar (Unknown URL content://com.android.calendar)

Ответы [ 3 ]

3 голосов
/ 18 февраля 2012

Непосредственный ответ: Адаптеры синхронизации должны быть связаны со службой. Служба создает экземпляр адаптера синхронизации в onCreate () и возвращает IBinder адаптеру синхронизации в onBind (). SyncManager вызывает Сервис, когда хочет запустить адаптер синхронизации.

Адаптеры синхронизации контролируются системой Android, в частности SyncManager, а не вашим приложением.

Пример приложения SampleSyncAdapter показывает, как написать адаптер и службу синхронизации. Если вы не хотите выполнять аутентификацию, вы можете удалить эту часть. Все, что вам нужно сделать, это реализовать класс, расширяющий AbstractThreadedSyncAdapter, и класс Service, который к нему привязан, а также файлы XML для адаптера синхронизации.

Лучший ответ: Адаптеры синхронизации помогают вам синхронизировать данные между сервером и устройством. Если все, что вам нужно, это загрузить данные календаря с сервера на ваше устройство, вы можете использовать приложение, которое удаляет данные с сервера и записывает их поставщику календаря. Это не синхронизация; вы не даете никаких гарантий, что вы будете делать больше загрузок или загрузок. Конечно, если вы do хотите синхронизировать два источника данных, адаптер синхронизации имеет следующие преимущества:

  • Система будет запускать его на регулярной основе без вмешательства пользователя.
  • Система гарантирует, что сеть доступна, прежде чем пытаться запустить синхронизацию. Тем не менее, обратите внимание, что система не может помешать вам делать глупости, такие как попытка аутентификации на сервере, когда ваши сетевые службы отключены.
  • Система гарантирует, что никакие другие синхронизации для того же сервера и провайдера контента не запускаются при запуске синхронизации.
  • Система предоставляет стандартное средство для отображения доступных адаптеров синхронизации, когда пользователь хочет добавить учетную запись.
2 голосов
/ 24 февраля 2012

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

0 голосов
/ 02 ноября 2013

Невозможно создать новый синхронизируемый календарь в существующей учетной записи Google (Gmail) программно с помощью API Календаря Android. Я положил более подробную информацию здесь: https://stackoverflow.com/a/19734278/237232

...