Почему CalendarProvider не позволяет писать ExtendedProperties?

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

Мы реализуем приложение календаря для совместной работы, которое использует эти расширенные свойства для добавления дополнительной информации к событию. В соответствии с рекомендациями Google мы используем Android CalendarProvider для чтения и создания новых событий. Когда мы создаем новое событие, нам нужно добавить к нему некоторые расширенные свойства, но мы только что поняли, что поставщик календаря не позволяет писать CalendarContract.ExtendedProperties, если мы попытаемся, мы получим следующую ошибку:

Only sync adapters may write using content://com.android.calendar/extendedproperties

Кажется немного странным, что эти свойства доступны только для чтения в CalendarProvider, поскольку это сводит на нет всю их цель, состоящую в том, чтобы прикреплять к событию некоторые дополнительные метаданные.

Кто-нибудь знает обходной путь для этого ограничения?


person ivacf    schedule 04.12.2014    source источник


Ответы (1)


вы должны действовать, как показано ниже:

  • класс, который вы используете для сохранения событий с расширенными свойствами, должен расширять AbstractThreadedSyncAdapter , а затем реализовывать метод onPerfomSync(...)

    public void onPerformSync(Account account, Bundle extras, String authority,
        ContentProviderClient provider, SyncResult syncResult) {
    System.out.println("Sync......");
    saveEvent();//your saving events method... 
    

    }

добавьте метод ниже в тот же класс:

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

создайте класс, который расширяет класс Service, как показано ниже.

public class SyncService extends Service {
private static final String TAG = "SyncService";

private static final Object sSyncAdapterLock = new Object();
private static EditEventHelper sSyncAdapter = null;

/**
 * Thread-safe constructor, creates static {@link SyncAdapter} instance.
 */
@Override
public void onCreate() {
    super.onCreate();
    Log.i(TAG, "Service created");
    synchronized (sSyncAdapterLock) {
        if (sSyncAdapter == null) {
            sSyncAdapter = new EditEventHelper(getApplicationContext());

        }
    }
}

@Override
/**
 * Logging-only destructor.
 */
public void onDestroy() {
    super.onDestroy();
    Log.i(TAG, "Service destroyed");
}

/**
 * Return Binder handle for IPC communication with {@link SyncAdapter}.
 *
 * <p>New sync requests will be sent directly to the SyncAdapter using this channel.
 *
 * @param intent Calling intent
 * @return Binder handle for {@link SyncAdapter}
 */
@Override
public IBinder onBind(Intent intent) {
    return sSyncAdapter.getSyncAdapterBinder();
}

}

В пути res создайте XML-файл syncadpater.xml с содержимым:

<sync-adapter xmlns:android="http://schemas.android.com/apk/res/android"
          android:contentAuthority="com.android.calendar"
          android:accountType="com.android.google"
          android:userVisible="true"
          android:supportsUploading="false"
          android:allowParallelSyncs="false"
          android:isAlwaysSyncable="false"
    />

Код, используемый для добавления к вам события Extendedproperties, будет таким:

ContentValues customerContentValues_1 = new ContentValues(); 
        customerContentValues_1.put(ExtendedProperties.EVENT_ID, model.mId);
        customerContentValues_1.put(ExtendedProperties.NAME, "name");
        customerContentValues_1.put(ExtendedProperties.VALUE, value);
activity.getContentResolver().insert(asSyncAdapter(ExtendedProperties.CONTENT_URI, mOwnerAccount, ACCOUNT_TYPE), customerContentValues_1);

В файле AndroidManifest.xml добавьте следующие разрешения:

    <uses-permission android:name="android.permission.READ_SYNC_STATS" />
<!-- Required to enable our SyncAdapter after it's created. -->
<uses-permission android:name="android.permission.WRITE_SYNC_SETTINGS" />
<!-- Required because we're manually creating a new account. -->
<uses-permission android:name="android.permission.AUTHENTICATE_ACCOUNTS" />

Затем объявите созданную вами службу в файле манифеста, связанном с файлом syncadapter.xml:

        <service
        android:name="com.android.calendar.iselection.event.SyncService"
        android:exported="true" >

        <!--
        This intent filter is required. It allows the system to launch our sync service
        as needed.
        -->
        <intent-filter>
            <action android:name="android.content.SyncAdapter" />
        </intent-filter>
        <!-- This points to a required XML file which describes our SyncAdapter. -->
        <meta-data
            android:name="android.content.SyncAdapter"
            android:resource="@xml/syncadapter" />
    </service>

Удачи!

person Omzo25    schedule 20.04.2015