2012-02-17 4 views
4

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

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

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

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

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

Он успешно, никаких жалоб выполняет, но URI возвращает всегда то же самое. Когда я разбираю его для Row ID, это всегда 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

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

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

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

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

  • Система будет работать на регулярной основе, без вмешательства пользователя.
  • Система гарантирует, что сеть доступна, прежде чем пытаться запустить синхронизацию. Обратите внимание, однако, что система не может помешать вам делать немые вещи, например, пытаться аутентифицироваться на сервере, когда ваши сетевые службы находятся в автономном режиме.
  • Система гарантирует, что никакая другая синхронизация для того же сервера и поставщика содержимого не будет запущена при запуске синхронизации.
  • Система предоставляет стандартное средство для отображения доступных адаптеров синхронизации, когда пользователь хочет добавить учетную запись.
+0

Спасибо за ответ! Я, что я пытался сделать, это создать новый календарь в Календаре Google. Который НЕ является адаптером синхронизации, поскольку вы указываете: P К сожалению, это действие не поддерживается новым Поставщиком Календаря Google. Насколько я могу судить, довольно часто приходится делать это через настольную версию веб-сайта. – Adam

+1

@Adam как 2014, даже официальное приложение Google Calendar не имеет этой возможности. Вы должны использовать веб-приложение для создания календаря. Эта ситуация подтверждает то, что подразумевает Джо: адаптеры синхронизации предназначены для выполнения задач синхронизации и не более того, в этом случае создание календаря, похоже, является функцией, которой они не нашли лучшего места в API для ввода ... –

2

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

0

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

Смежные вопросы