CalDav および SyncML カレンダーをカレンダー プロバイダー データベースに追加するアプリケーションをプログラミングしています。追加することはできますが、再起動するとカレンダーが消えるため、問題が発生します。
カレンダーを追加するコードは次のとおりです
private final CalendarEnvironmentProjection calEP = new CalendarEnvironmentProjection();
public long addCal(ContentResolver cr, String userName, String url,
String accountType, String timeZone) {
Log.v(DEBUG_TAG, "Start addCal");
ContentValues values = new ContentValues();
String accountName = userName + "@" + url.split("/")[2];
Log.v(DEBUG_TAG, "Add values");
values.put(
this.calEP.eventProj(this.calEP.PROJECTION_SYNC_ACCOUNT_INDEX),
accountName);
values.put(this.calEP
.eventProj(this.calEP.PROJECTION_SYNC_ACCOUNT_TYPE_INDEX),
accountType);
values.put(this.calEP.eventProj(this.calEP.PROJECTION_SYNC_NAME_INDEX),
userName + " Calendar's");
values.put(
this.calEP.eventProj(this.calEP.PROJECTION_DISPLAY_NAME_INDEX),
userName + " Calendar's");
values.put(this.calEP.eventProj(this.calEP.PROJECTION_SYNC_ID_INDEX),
url);
values.put(
this.calEP.eventProj(this.calEP.PROJECTION_SYNC_DIRTY_INDEX), 1);
values.put(this.calEP.eventProj(this.calEP.PROJECTION_TIMEZONE_INDEX),
timeZone);
values.put(
this.calEP.eventProj(this.calEP.PROJECTION_OWNER_ACCOUNT_INDEX),
accountName);
values.put(this.calEP
.eventProj(this.calEP.PROJECTION_CALENDAR_ACCESS_LEVEL_INDEX),
700);
values.put(
this.calEP.eventProj(this.calEP.PROJECTION_SYNC_EVENTS_INDEX),
1);
values.put(this.calEP
.eventProj(this.calEP.PROJECTION_CALENDAR_COLOR_INDEX),
Color.CYAN);
Log.v(DEBUG_TAG, "Start insert");
Uri creationUri = asSyncAdapter(
Uri.parse("content://com.android.calendar/calendars"),
accountName, accountType);
Uri uri = cr.insert(creationUri, values);
Log.v(DEBUG_TAG, "fin insert");
long calID = Long.parseLong(uri.getLastPathSegment());
Log.i(this.DEBUG_TAG, "Calendar add: " + calID);
return calID;
}
syncAdapter として機能するコードは次のとおりです。
public CalendarDbAccessors(Context context, boolean autoInitialize) {
super(context, autoInitialize);
}
@Override
public void onPerformSync(Account account, Bundle extras, String authority,
ContentProviderClient provider, SyncResult syncResult) {
Log.i(this.DEBUG_TAG, "onPerformSync()");
}
private Uri asSyncAdapter(Uri uri, String account, String accountType) {
return uri
.buildUpon()
.appendQueryParameter("caller_is_syncadapter", "true")
.appendQueryParameter(
this.calEP
.eventProj(this.calEP.PROJECTION_SYNC_ACCOUNT_INDEX),
account)
.appendQueryParameter(
this.calEP
.eventProj(this.calEP.PROJECTION_SYNC_ACCOUNT_TYPE_INDEX),
accountType).build();
}
データベースに作用するために私が作ったプロジェクションの環境は次のとおりです。
public class CalendarEnvironmentProjection {
private String[] eventProj = null;
private final String DEBUG_TAG = "CalendarBD";
private static final String[] EVENT_PROJECTION_8 = new String[] {
"_id", // 0
"_sync_account", // 1
"_sync_account_type", // 2
"name", // 3
"displayName", // 4
"_sync_id", // 5
"_sync_dirty", // 6
"timezone", // 7
"ownerAccount", // 8
"access_level", // 9
"sync_events", // 10
"color" // 11
};
@SuppressLint("InlinedApi")
private static final String[] EVENT_PROJECTION_14 = new String[] {
Calendars._ID, // 0
Calendars.ACCOUNT_NAME, // 1
Calendars.ACCOUNT_TYPE, // 2
Calendars.NAME, // 3
Calendars.CALENDAR_DISPLAY_NAME, // 4
Calendars._SYNC_ID, // 5
Calendars.DIRTY, // 6
Calendars.CALENDAR_TIME_ZONE, // 7
Calendars.OWNER_ACCOUNT, // 8
Calendars.CALENDAR_ACCESS_LEVEL, // 9
Calendars.SYNC_EVENTS, // 10
Calendars.CALENDAR_COLOR // 11
};
// The indices for the projections arrays above.
protected final int PROJECTION_ID_INDEX = 0;
protected final int PROJECTION_SYNC_ACCOUNT_INDEX = 1;
protected final int PROJECTION_SYNC_ACCOUNT_TYPE_INDEX = 2;
protected final int PROJECTION_SYNC_NAME_INDEX = 3;
protected final int PROJECTION_DISPLAY_NAME_INDEX = 4;
protected final int PROJECTION_SYNC_ID_INDEX = 5;
protected final int PROJECTION_SYNC_DIRTY_INDEX = 6;
protected final int PROJECTION_TIMEZONE_INDEX = 7;
protected final int PROJECTION_OWNER_ACCOUNT_INDEX = 8;
protected final int PROJECTION_CALENDAR_ACCESS_LEVEL_INDEX = 9;
protected final int PROJECTION_SYNC_EVENTS_INDEX = 10;
protected final int PROJECTION_CALENDAR_COLOR_INDEX = 11;
public CalendarEnvironmentProjection() {
if (Build.VERSION.SDK_INT >= 8 && Build.VERSION.SDK_INT < 14) {
this.eventProj = EVENT_PROJECTION_8;
} else if (Build.VERSION.SDK_INT >= 14) {
this.eventProj = EVENT_PROJECTION_14;
} else {
Log.e(this.DEBUG_TAG, "Android version not supported !");
}
}
protected String[] eventProj() {
return this.eventProj;
}
protected String eventProj(int projectionIndex) {
return this.eventProj[projectionIndex];
}}
アクティビティに追加した行は次のとおりです。
<intent-filter>
<action android:name="android.content.SyncAdapter" />
</intent-filter>
<meta-data android:name="android.content.SyncAdapter" android:resource="@xml/calendar_sync_adapter" />
/res/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"
/>