为什么CalendarProvider不允许写入ExtendedProperties?

时间:2014-12-04 12:04:58

标签: android calendar google-calendar-api android-calendar extended-properties

Google日历事件具有可用于将名称/值对附加到事件的扩展属性。

我们正在实施一个协作日历应用程序,该应用程序使用这些扩展属性将额外信息附加到事件中。根据Google的建议,我们使用Android CalendarProvider来阅读和创建新活动。当我们创建一个新事件时,我们需要为它添加一些扩展属性,但我们只是意识到日历提供程序不允许写CalendarContract.ExtendedProperties,如果我们尝试得到以下错误:

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

这些属性在CalendarProvider中是只读的似乎有点奇怪,因为它违背了它们的全部目的,它能够将一些额外的元数据附加到事件中。

是否有人知道此限制的解决方法?

1 个答案:

答案 0 :(得分:2)

你必须按照以下步骤进行:

  • 用于保存具有扩展功能的事件的类应该 扩展 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();
 }

创建一个扩展服务类的类,如下所示

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>
祝你好运!