3

Google日历事件具有可用于将名称/值对附加到事件的扩展属性。为什么CalendarProvider不允许写入ExtendedProperties?

我们正在实施协作日历应用程序,该应用程序使用这些扩展属性将附加信息附加到事件中。按照Google的建议,我们使用Android CalendarProvider来阅读和创建新事件。当我们创建一个新的事件,我们需要一些扩展属性添加到它,但我们刚刚意识到日历提供商不允许书面方式CalendarContract.ExtendedProperties,如果我们尝试,我们得到以下错误:

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

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

有没有人知道这种限制的解决方法?

回答

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

}

水库一类路径创建一个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> 

祝你好运!