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> 

祝你好運!