仕事でCalendarProviderを使う機会があったのですが、表題の件でどないすりゃええねんってなりました。
背景
- AndroidのCalendar Provider APIを使ってGoogleカレンダーに予定を登録する必要があった。
- 予定を登録する際は以下のようにContentResolver経由でCalendarContract.Events.CONTENT_URIをURIに指定し、insert処理する必要があるがカラムCalendarContract.Events.CALENDAR_IDに対象のカレンダーのIDを指定しないといけない。(★マーク部分)
val calID: Long = 3
val startMillis: Long = Calendar.getInstance().run {
set(2012, 9, 14, 7, 30)
timeInMillis
}
val endMillis: Long = Calendar.getInstance().run {
set(2012, 9, 14, 8, 45)
timeInMillis
}
...
val values = ContentValues().apply {
put(CalendarContract.Events.DTSTART, startMillis)
put(CalendarContract.Events.DTEND, endMillis)
put(CalendarContract.Events.TITLE, "Jazzercise")
put(CalendarContract.Events.DESCRIPTION, "Group workout")
★ put(CalendarContract.Events.CALENDAR_ID, calID)
put(CalendarContract.Events.EVENT_TIMEZONE, "America/Los_Angeles")
}
val uri: Uri = contentResolver.insert(CalendarContract.Events.CONTENT_URI, values)
- カレンダーIdを取得するには予定登録同様にContentResolver経由で取得するが、レコードが複数取れるため、どのレコードのCalendarIdを指定すべきかが、わからない。。。。(以下)
val projection = arrayOf(
CalendarContract.Calendars._ID
)
val uri = CalendarContract.Calendars.CONTENT_URI
val resolver = context.contentResolver
val cursor = resolver.query(
uri,
projection,
null,
null,
null
) ?: returnwhile (cursor.moveToNext()) {
val index = cursor.getColumnIndex(CalendarContract.Calendars._ID)
val id = cursor.getLong(index)
// ★複数回ループが走っており、どのIdかわからん!!!
Log.d("hoge","id = $id")
}
cursor.close()
結果
queryを実行する際に以下のようにselection(where句)にIS_PRIMARYというカラムが1かどうかを指定すると予定登録すべきカレンダーのIdが取れました。(★マーク部分)
val uri = CalendarContract.Calendars.CONTENT_URI
val resolver = context.contentResolver
val cursor = resolver.query(
uri,
projection,
★ "${CalendarContract.Calendars.IS_PRIMARY} = 1",
null,
null
) ?: return
説明
リファレンスのIS_PRIMARYの説明を見ると以下のようになっています。
英語
Is this the primary calendar for this account. If this column is not explicitly set, the provider will return 1 if Calendars#ACCOUNT_NAME is equal to Calendars#OWNER_ACCOUNT.
日本語
これがこのアカウントのプライマリカレンダーです。この列が明示的に設定されていない場合、Calendars#ACCOUNT_NAMEがCalendars#OWNER_ACCOUNTと等しい場合、プロバイダーは1を返します。
ただし、API Level 17以上からこのカラムは使えるようなのでそれより下のバージョンをサポートする際は
Calendars#ACCOUNT_NAME = Calendars#OWNER_ACCOUNT
をselectionに指定すれば良さげです。
ネセセローン!!!!