Calendar Provider は、ユーザーのカレンダーの予定のリポジトリです。「 Calendar Provider API を使用すると、クエリ、挿入、更新、削除を実行可能 操作に使用できます。
Calendar Provider API は、アプリケーションや同期アダプタで使用できます。「 ルールは、呼び出しを行っているプログラムのタイプによって異なります。このドキュメントでは主に、Calendar Provider API のアプリケーションとしての使用について説明します。対象 相違点については、 同期アダプター。
通常、カレンダー データを読み取ったり書き込んだりするためには、アプリケーションのマニフェストにユーザー パーミッションで説明している適切なパーミッションが含まれている必要があります。一般的な操作を簡単にするために、 カレンダーで説明されているように、プロバイダが一連のインテントを提供している インテントをご覧ください。これらのインテントはユーザーをカレンダー アプリケーションに誘導し、 予定の編集が可能です。ユーザーは、カレンダー アプリケーションを操作した後、元のアプリケーションに戻ります。そのため、アプリで権限をリクエストする必要はなく、 また、イベントを表示または作成するためのユーザー インターフェースを提供する必要もありません。
基本
コンテンツ プロバイダは、データを保存してアプリケーションからアクセスできるようにします。Android プラットフォームによって提供されるコンテンツ プロバイダ(カレンダー プロバイダを含む)は、一般にリレーショナル データベース モデルに基づくテーブルのセットとしてデータを公開します。このモデルにおいて、各行はレコード、各列は特定のタイプと意味のデータになっています。Calendar Provider API を使用すると データベース テーブルに対する読み取り/書き込みアクセス権を 関連付けることもできます。
各コンテンツ プロバイダは、コンテンツ プロバイダが公開している
Uri
そのデータセットを一意に識別するオブジェクト)を指定します。コンテンツ プロバイダが
複数のデータセット(複数のテーブル)がある場合は、データセットごとに個別の URI が公開されます。プロバイダの URI はすべて、文字列「content://」で始まります。これは、コンテンツ プロバイダによって管理されているデータであることを示します。カレンダー
provider は、そのクラス(テーブル)ごとに URI の定数を定義します。これらの
URI の形式は <class>.CONTENT_URI
です。対象
例: Events.CONTENT_URI
。
図 1 は、Calendar Provider データモデルの図を示しています。メイン テーブルとそれらを相互にリンクしているフィールドが示されています。
ユーザーは複数のカレンダーを持つことができ、さまざまなカレンダーをさまざまな種類のアカウント(Google カレンダー、Exchange など)に関連付けることができます。
CalendarContract
は、カレンダーとイベント関連の情報を定義します。このデータは、以下に示す複数のテーブルに保存されています。
テーブル(クラス) | 説明 |
---|---|
このテーブルは カレンダー固有の情報を表示します。各行には、名前、色、同期情報など、1 つのカレンダーに関する詳細が格納されます。 | |
CalendarContract.Events |
このテーブルは
イベント固有の情報を取得します。このテーブルの各行には、1 つの
イベント(例: 予定のタイトル、場所、開始時間、終了)
できます。この予定は 1 回のみ発生することも、複数回発生することもあります。参加者
リマインダー、拡張プロパティは別々のテーブルに保存されます。
これらのテーブルにはそれぞれ、Events テーブルの _ID を参照する EVENT_ID があります。 |
CalendarContract.Instances |
このテーブルは、イベントの発生ごとの開始時刻と終了時刻を保持します。各行は、イベントの発生 1 回を表します。単発イベントには、イベントのインスタンスが 1 対 1 で対応します。繰り返しのイベントには、そのイベントの複数回の発生それぞれに対応する複数の行が自動生成されます。 |
CalendarContract.Attendees |
このテーブルは イベントの参加者(ゲスト)の情報各行は、ゲストが 1 人いることを イベントです。ゲストの種類とゲストの出欠状況 指定します。 |
CalendarContract.Reminders |
このテーブルは
アラート/通知データです。各行は、1 つのイベントに対する 1 つのアラートを表します。「
イベントには複数のリマインダーを設定できます。1 件の予定で作成できるリマインダーの上限数は
指定
MAX_REMINDERS 、
同期アダプターによって設定され、
指定されたカレンダーのオーナーになります。リマインダーは、イベント開始前の分単位で指定され、ユーザーに注意喚起する手段を示す情報を保持します。 |
Calendar Provider API は、柔軟で効果的な設計になっています。料金の 優れたエンドユーザー エクスペリエンスを提供し、 カレンダーとそのデータの整合性を保護する。次に、そのために API の使用に際して留意すべきことを示します。
- カレンダーの予定を挿入、更新、表示する。カレンダー プロバイダからの予定を直接挿入、変更、読み取るには、適切な権限が必要です。ただし、作成しているのが本格的なカレンダー アプリケーションや同期アダプタではない場合は、そうしたパーミッションを要求する必要はありません。その代わりに、Android のカレンダー アプリケーションがサポートしているインテントを使用し、読み取りと書き込みの操作をそのアプリケーションに引き渡すことができます。インテントを使用すると、アプリケーションはユーザーをカレンダー アプリケーションに送り、目的の操作を実行できるようになります。 表示されるはずです完了すると、ユーザーはアプリに戻されます。カレンダーで一般的な操作を実行するようにアプリケーションを設計することで、 一貫性のある堅牢なユーザー インターフェースをユーザーに提供できます。これが 方法をおすすめします。詳しくは、カレンダー インテントをご覧ください。
- アダプターを同期する。同期アダプターがカレンダー データを同期させる
ユーザーのデバイス上のデータを
別のサーバーやデータソースと共有できます
CalendarContract.Calendars
、CalendarContract.Events
個のテーブル、 同期アダプター用に予約されている列があります。 プロバイダとアプリケーションは、これらの値を変更しないでください。実際には、同期アダプタとしてアクセスしない限り、それらの列は参照できません。詳細については、このモジュールの 同期アダプターをご覧ください。
ユーザー権限
カレンダー データを読み取るには、アプリのマニフェスト ファイルに READ_CALENDAR
権限を含める必要があります。これは、
WRITE_CALENDAR
権限を含む
カレンダーデータを削除、挿入、または更新するには:
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android"...> <uses-sdk android:minSdkVersion="14" /> <uses-permission android:name="android.permission.READ_CALENDAR" /> <uses-permission android:name="android.permission.WRITE_CALENDAR" /> ... </manifest>
Calendars テーブル
CalendarContract.Calendars
テーブルには詳細が含まれています。
作成することもできます。次に示す Calendars の列は、アプリケーションと同期アダプタのどちらからも書き込み可能です。サポートされているフィールドの一覧については、CalendarContract.Calendars
リファレンスをご覧ください。
定数 | 説明 |
---|---|
NAME |
カレンダーの名前。 |
CALENDAR_DISPLAY_NAME |
ユーザーに表示されるこのカレンダーの名前。 |
VISIBLE |
カレンダーが表示対象として選択されているかどうかを示すブール値。
値 0 は、このカレンダーに関連付けられた予定を
表示されます。値 1 は、このカレンダーに関連付けられているイベントを表示することを示します。この値は、CalendarContract.Instances テーブルの行の生成に影響を与えます。 |
SYNC_EVENTS |
カレンダーを同期してそのカレンダーを表示する必要があるかどうかを示すブール値 デバイスに保存されたイベントです。値 0 は、このカレンダーを同期しない、または そのイベントをデバイスに保存します。値が 1 の場合は、このカレンダーの予定が同期されます そのイベントをデバイスに保存します。 |
すべてのオペレーションにアカウント タイプを含める
Calendars.ACCOUNT_NAME
でクエリする場合は、
Calendars.ACCOUNT_TYPE
選択します。これは、指定されたアカウントは ACCOUNT_NAME
とその ACCOUNT_TYPE
がどちらも与えられることで一意とみなされるからです。ACCOUNT_TYPE
は
アカウントが
AccountManager
。特殊なタイプのアカウントもあり、
「ACCOUNT_TYPE_LOCAL
」という名前:
デバイス アカウントに関連付けられていないカレンダーを表示します。
ACCOUNT_TYPE_LOCAL
アカウントは同期されません。
カレンダーをクエリする
次の例は、特定の管理者によって所有されているカレンダーを取得する方法を示しています。
できます。簡潔にするため、この例のクエリ操作はユーザー インターフェース スレッド(「メインスレッド」)内に示されています。実際には、メインスレッドではなく非同期スレッドで実行してください。詳細については、ローダをご覧ください。セキュリティ担当者を
データの読み取りと変更については、AsyncQueryHandler
をご覧ください。
Kotlin
// Projection array. Creating indices for this array instead of doing // dynamic lookups improves performance. private val EVENT_PROJECTION: Array<String> = arrayOf( CalendarContract.Calendars._ID, // 0 CalendarContract.Calendars.ACCOUNT_NAME, // 1 CalendarContract.Calendars.CALENDAR_DISPLAY_NAME, // 2 CalendarContract.Calendars.OWNER_ACCOUNT // 3 ) // The indices for the projection array above. private const val PROJECTION_ID_INDEX: Int = 0 private const val PROJECTION_ACCOUNT_NAME_INDEX: Int = 1 private const val PROJECTION_DISPLAY_NAME_INDEX: Int = 2 private const val PROJECTION_OWNER_ACCOUNT_INDEX: Int = 3
Java
// Projection array. Creating indices for this array instead of doing // dynamic lookups improves performance. public static final String[] EVENT_PROJECTION = new String[] { Calendars._ID, // 0 Calendars.ACCOUNT_NAME, // 1 Calendars.CALENDAR_DISPLAY_NAME, // 2 Calendars.OWNER_ACCOUNT // 3 }; // The indices for the projection array above. private static final int PROJECTION_ID_INDEX = 0; private static final int PROJECTION_ACCOUNT_NAME_INDEX = 1; private static final int PROJECTION_DISPLAY_NAME_INDEX = 2; private static final int PROJECTION_OWNER_ACCOUNT_INDEX = 3;
例の次の部分では、クエリを作成します。クエリの条件は selection に指定します。この例のクエリは、ACCOUNT_NAME
「hera@example.com」、ACCOUNT_TYPE
「com.example」、OWNER_ACCOUNT
「hera@example.com」のカレンダーを検索します。あるユーザーが参加しているすべてのカレンダーを
ユーザーが所有するカレンダーだけでなく、OWNER_ACCOUNT
は省略します。
このクエリは、データベース クエリが返した結果セットをトラバースするために使用できる Cursor
オブジェクトを返します。コンテンツ プロバイダでのクエリの使用について詳しくは、コンテンツ プロバイダをご覧ください。
Kotlin
// Run query val uri: Uri = CalendarContract.Calendars.CONTENT_URI val selection: String = "((${CalendarContract.Calendars.ACCOUNT_NAME} = ?) AND (" + "${CalendarContract.Calendars.ACCOUNT_TYPE} = ?) AND (" + "${CalendarContract.Calendars.OWNER_ACCOUNT} = ?))" val selectionArgs: Array<String> = arrayOf("hera@example.com", "com.example", "hera@example.com") val cur: Cursor = contentResolver.query(uri, EVENT_PROJECTION, selection, selectionArgs, null)
Java
// Run query Cursor cur = null; ContentResolver cr = getContentResolver(); Uri uri = Calendars.CONTENT_URI; String selection = "((" + Calendars.ACCOUNT_NAME + " = ?) AND (" + Calendars.ACCOUNT_TYPE + " = ?) AND (" + Calendars.OWNER_ACCOUNT + " = ?))"; String[] selectionArgs = new String[] {"hera@example.com", "com.example", "hera@example.com"}; // Submit the query and get a Cursor object back. cur = cr.query(uri, EVENT_PROJECTION, selection, selectionArgs, null);
次のセクションでは、カーソルを使用して結果セットをステップ単位で移動します。これは、 値を返すためにサンプルの最初で設定した定数が 指定する必要があります
Kotlin
// Use the cursor to step through the returned records while (cur.moveToNext()) { // Get the field values val calID: Long = cur.getLong(PROJECTION_ID_INDEX) val displayName: String = cur.getString(PROJECTION_DISPLAY_NAME_INDEX) val accountName: String = cur.getString(PROJECTION_ACCOUNT_NAME_INDEX) val ownerName: String = cur.getString(PROJECTION_OWNER_ACCOUNT_INDEX) // Do something with the values... }
Java
// Use the cursor to step through the returned records while (cur.moveToNext()) { long calID = 0; String displayName = null; String accountName = null; String ownerName = null; // Get the field values calID = cur.getLong(PROJECTION_ID_INDEX); displayName = cur.getString(PROJECTION_DISPLAY_NAME_INDEX); accountName = cur.getString(PROJECTION_ACCOUNT_NAME_INDEX); ownerName = cur.getString(PROJECTION_OWNER_ACCOUNT_INDEX); // Do something with the values... ... }
カレンダーを変更する
カレンダーのアップデートを実行する場合は、カレンダーの _ID
を、URI(withAppendedId()
)の末尾に追加された ID として、または最初の selection 項目として指定できます。選択は "_id=?"
で始め、最初の selectionArg
はカレンダーの _ID
にする必要があります。URL に含まれる ID をエンコードすることでも、アップデートを実行できます。この例では、(withAppendedId()
)アプローチを使用してカレンダーの表示名を変更します。
Kotlin
const val DEBUG_TAG: String = "MyActivity" ... val calID: Long = 2 val values = ContentValues().apply { // The new display name for the calendar put(CalendarContract.Calendars.CALENDAR_DISPLAY_NAME, "Trevor's Calendar") } val updateUri: Uri = ContentUris.withAppendedId(CalendarContract.Calendars.CONTENT_URI, calID) val rows: Int = contentResolver.update(updateUri, values, null, null) Log.i(DEBUG_TAG, "Rows updated: $rows")
Java
private static final String DEBUG_TAG = "MyActivity"; ... long calID = 2; ContentValues values = new ContentValues(); // The new display name for the calendar values.put(Calendars.CALENDAR_DISPLAY_NAME, "Trevor's Calendar"); Uri updateUri = ContentUris.withAppendedId(Calendars.CONTENT_URI, calID); int rows = getContentResolver().update(updateUri, values, null, null); Log.i(DEBUG_TAG, "Rows updated: " + rows);
カレンダーを挿入する
カレンダーは主に同期アダプタで管理するように設計されているため、新しいカレンダーは必ず同期アダプタとして挿入してください。ほとんどの場合、アプリケーションはカレンダーに対し、表示名の変更のような表面的な変更しかできません。アプリケーションがローカル カレンダーを作成する必要がある場合は、ACCOUNT_TYPE_LOCAL
の ACCOUNT_TYPE
を使用して、カレンダーの挿入を同期アダプタとして実行します。ACCOUNT_TYPE_LOCAL
は、デバイス アカウントに関連付けられていないカレンダー用の特別なアカウント タイプです。このタイプのカレンダーはサーバーと同期されません。同期アダプターの詳細については、同期アダプターをご覧ください。
イベント テーブル
CalendarContract.Events
テーブルには、個々のイベントの詳細情報が格納されます。イベントを追加、更新、削除するには、アプリケーションで
WRITE_CALENDAR
権限を
マニフェスト ファイル。
次のイベント列は、アプリケーションと同期の両方から書き込み可能です。
アダプターを使用する。サポートされているフィールドの一覧については、CalendarContract.Events
リファレンスをご覧ください。
定数 | 説明 |
---|---|
CALENDAR_ID |
イベントが属するカレンダーの _ID 。 |
ORGANIZER |
予定の主催者(オーナー)のメールアドレス。 |
TITLE |
イベントのタイトル。 |
EVENT_LOCATION |
イベントが行われる場所。 |
DESCRIPTION |
イベントの説明。 |
DTSTART |
イベントの開始時間(エポックからの UTC ミリ秒)。 |
DTEND |
イベントの終了時刻(エポックからの UTC ミリ秒)。 |
EVENT_TIMEZONE |
イベントのタイムゾーン。 |
EVENT_END_TIMEZONE |
予定の終了時間のタイムゾーン。 |
DURATION |
イベントの期間(RFC5545 形式)。たとえば、値が "PT1H" の場合、イベントは 1 時間続くことを意味し、値が "P2W" の場合、期間は 2 週間であることを意味します。 |
ALL_DAY |
値が 1 の場合、このイベントが 1 日を通して発生していることを示します。 指定することもできます。値 0 は、1 日のどこかで始まって終わる定期のイベントであることを示します。 |
RRULE |
イベント形式の繰り返しルール。対象
例: "FREQ=WEEKLY;COUNT=10;WKST=SU" 。その他の例については、こちらをご覧ください。 |
RDATE |
イベントの繰り返し発生日。
通常、RDATE は RRULE と組み合わせて、繰り返し発生全体を定義するのに使用します。詳細については、RFC5545 の仕様をご覧ください。 |
AVAILABILITY |
この予定を混雑している時間と スケジュールされます |
GUESTS_CAN_MODIFY |
ゲストが予定を変更できるかどうか。 |
GUESTS_CAN_INVITE_OTHERS |
ゲストが他のゲストを招待できるかどうか。 |
GUESTS_CAN_SEE_GUESTS |
ゲストが他の参加者のリストを参照できるかどうか。 |
予定の追加
アプリケーションで新しいイベントを挿入するときは、
INSERT
インテント(インテントを使用してイベントを挿入するを参照)。ただし、必要に応じてイベントを直接挿入できます。このセクションでは、その方法について説明します。
新しいイベントを挿入するためのルールは次のとおりです。
CALENDAR_ID
とDTSTART
を含める必要があります。EVENT_TIMEZONE
を含める必要があります。システムにインストールされているタイムゾーン ID のリストを取得するには、getAvailableIDs()
を使用します。なお、このルールは、INSERT
インテントを使用してイベントを挿入する(インテントを使用してイベントを挿入するを参照)。 デフォルトのタイムゾーンが指定されています。- 繰り返されないイベントには、
DTEND
を含める必要があります。 - 定期的な予定の場合は、
RRULE
またはRDATE
に加えてDURATION
を含める必要があります。インテントを使用したイベントの挿入で説明しているように、INSERT
インテントを使用してイベントを挿入している場合、このルールは該当しません。その場合は、RRULE
をDTSTART
とDTEND
と組み合わせて使用でき、カレンダー アプリケーションはこれを自動で期間に変換します。
イベントの挿入の例を次に示します。簡潔にするため、この例は UI スレッドで実行されています。実際には、挿入やアップデートは非同期スレッドで実行して、アクションをバックグラウンド スレッドに移してください。詳細については、AsyncQueryHandler
をご覧ください。
Kotlin
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) // get the event ID that is the last element in the Uri val eventID: Long = uri.lastPathSegment.toLong() // // ... do something with event ID // //
Java
long calID = 3; long startMillis = 0; long endMillis = 0; Calendar beginTime = Calendar.getInstance(); beginTime.set(2012, 9, 14, 7, 30); startMillis = beginTime.getTimeInMillis(); Calendar endTime = Calendar.getInstance(); endTime.set(2012, 9, 14, 8, 45); endMillis = endTime.getTimeInMillis(); ... ContentResolver cr = getContentResolver(); ContentValues values = new ContentValues(); values.put(Events.DTSTART, startMillis); values.put(Events.DTEND, endMillis); values.put(Events.TITLE, "Jazzercise"); values.put(Events.DESCRIPTION, "Group workout"); values.put(Events.CALENDAR_ID, calID); values.put(Events.EVENT_TIMEZONE, "America/Los_Angeles"); Uri uri = cr.insert(Events.CONTENT_URI, values); // get the event ID that is the last element in the Uri long eventID = Long.parseLong(uri.getLastPathSegment()); // // ... do something with event ID // //
注: この例でイベントを取得する方法をご覧ください。 イベント作成後の ID。イベント ID を取得する最も簡単な方法です。他のカレンダー操作を実行するためにイベント ID が必要になることはよくあります。たとえば、イベントに対する参加者やリマインダーの追加などが該当します。
アップデート指標
アプリケーションでユーザーにイベントの編集を許可する場合は、
EDIT
インテントを使用します。
インテントを使用してイベントを編集するをご覧ください。
ただし、必要に応じて予定を直接編集することもできます。イベントの更新を実行するには、イベントの _ID
を、URI(withAppendedId()
)に追加された ID として、または最初の選択項目として指定します。選択範囲は "_id=?"
で始まり、最初の
selectionArg
は、イベントの _ID
である必要があります。Google Chat では
ID のない選択部分を使用して更新も行います。イベントの更新の例を次に示します。イベントのタイトルを変更し、
withAppendedId()
アプローチ:
Kotlin
val DEBUG_TAG = "MyActivity" ... val eventID: Long = 188 ... val values = ContentValues().apply { // The new title for the event put(CalendarContract.Events.TITLE, "Kickboxing") } val updateUri: Uri = ContentUris.withAppendedId(CalendarContract.Events.CONTENT_URI, eventID) val rows: Int = contentResolver.update(updateUri, values, null, null) Log.i(DEBUG_TAG, "Rows updated: $rows")
Java
private static final String DEBUG_TAG = "MyActivity"; ... long eventID = 188; ... ContentResolver cr = getContentResolver(); ContentValues values = new ContentValues(); Uri updateUri = null; // The new title for the event values.put(Events.TITLE, "Kickboxing"); updateUri = ContentUris.withAppendedId(Events.CONTENT_URI, eventID); int rows = cr.update(updateUri, values, null, null); Log.i(DEBUG_TAG, "Rows updated: " + rows);
予定を削除
イベントを削除するには、URI に追加された ID として _ID
を使用するか、
選択します。付加された ID を使用した場合、選択することはできません。
削除には、アプリケーションとして実行する方法と同期アダプタとして実行する方法の 2 種類があります。アプリケーションとしての削除では、削除される列が 1 に設定されます。このフラグは、
行が削除され、その行が削除される必要があることを、
サーバーに伝播されます。同期アダプタとしての削除では、すべての関連データとともにデータベースからイベントが削除されます。次の例は、アプリケーションが _ID
を使用してイベントを削除する例です。
Kotlin
val DEBUG_TAG = "MyActivity" ... val eventID: Long = 201 ... val deleteUri: Uri = ContentUris.withAppendedId(CalendarContract.Events.CONTENT_URI, eventID) val rows: Int = contentResolver.delete(deleteUri, null, null) Log.i(DEBUG_TAG, "Rows deleted: $rows")
Java
private static final String DEBUG_TAG = "MyActivity"; ... long eventID = 201; ... ContentResolver cr = getContentResolver(); Uri deleteUri = null; deleteUri = ContentUris.withAppendedId(Events.CONTENT_URI, eventID); int rows = cr.delete(deleteUri, null, null); Log.i(DEBUG_TAG, "Rows deleted: " + rows);
Attendees テーブル
CalendarContract.Attendees
テーブルの各行は、イベントの 1 人の参加者またはゲストを表します。発信中
query()
は、会議の参加者のリストを返します。
特定のEVENT_ID
のイベントを
このEVENT_ID
特定のイベントの _ID
と一致する必要があります。
次の表に、
定義できます。新しい参加者を挿入する際には、ATTENDEE_NAME
を除くすべてを含める必要があります。
定数 | 説明 |
---|---|
EVENT_ID |
イベントの ID。 |
ATTENDEE_NAME |
参加者の名前。 |
ATTENDEE_EMAIL |
参加者のメールアドレス。 |
ATTENDEE_RELATIONSHIP |
参加者とイベントの関係。次のいずれか: |
ATTENDEE_TYPE |
参加者のタイプ。次のいずれか: |
ATTENDEE_STATUS |
参加者の出席ステータス。次のいずれか: |
参加者を追加する
次の例では、あるイベントに 1 人の参加者を挿入しています。なお、
EVENT_ID
は必須です。
Kotlin
val eventID: Long = 202 ... val values = ContentValues().apply { put(CalendarContract.Attendees.ATTENDEE_NAME, "Trevor") put(CalendarContract.Attendees.ATTENDEE_EMAIL, "trevor@example.com") put( CalendarContract.Attendees.ATTENDEE_RELATIONSHIP, CalendarContract.Attendees.RELATIONSHIP_ATTENDEE ) put(CalendarContract.Attendees.ATTENDEE_TYPE, CalendarContract.Attendees.TYPE_OPTIONAL) put( CalendarContract.Attendees.ATTENDEE_STATUS, CalendarContract.Attendees.ATTENDEE_STATUS_INVITED ) put(CalendarContract.Attendees.EVENT_ID, eventID) } val uri: Uri = contentResolver.insert(CalendarContract.Attendees.CONTENT_URI, values)
Java
long eventID = 202; ... ContentResolver cr = getContentResolver(); ContentValues values = new ContentValues(); values.put(Attendees.ATTENDEE_NAME, "Trevor"); values.put(Attendees.ATTENDEE_EMAIL, "trevor@example.com"); values.put(Attendees.ATTENDEE_RELATIONSHIP, Attendees.RELATIONSHIP_ATTENDEE); values.put(Attendees.ATTENDEE_TYPE, Attendees.TYPE_OPTIONAL); values.put(Attendees.ATTENDEE_STATUS, Attendees.ATTENDEE_STATUS_INVITED); values.put(Attendees.EVENT_ID, eventID); Uri uri = cr.insert(Attendees.CONTENT_URI, values);
Reminders テーブル
CalendarContract.Reminders
テーブルの各行
イベントの 1 つのリマインダーを表します。query()
を呼び出すと、指定された EVENT_ID
を持つイベントのリマインダー リストが返されます。
次の表に、リマインダーに関する書き込み可能なフィールドを示します。新しいリマインダーを挿入する際には、これらをすべて含める必要があります。同期アダプタは、サポートするリマインダーのタイプを CalendarContract.Calendars
テーブルで指定します。詳しくは、
ALLOWED_REMINDERS
をご覧ください。
定数 | 説明 |
---|---|
EVENT_ID |
イベントの ID。 |
MINUTES |
リマインダーを配信する予定の時間(分)。 |
METHOD |
サーバーで設定されるアラーム メソッド。次のいずれか: |
リマインダーを追加
この例では、イベントにリマインダーを追加します。このリマインダーは、イベントの 15 分前に通知されます。
Kotlin
val eventID: Long = 221 ... val values = ContentValues().apply { put(CalendarContract.Reminders.MINUTES, 15) put(CalendarContract.Reminders.EVENT_ID, eventID) put(CalendarContract.Reminders.METHOD, CalendarContract.Reminders.METHOD_ALERT) } val uri: Uri = contentResolver.insert(CalendarContract.Reminders.CONTENT_URI, values)
Java
long eventID = 221; ... ContentResolver cr = getContentResolver(); ContentValues values = new ContentValues(); values.put(Reminders.MINUTES, 15); values.put(Reminders.EVENT_ID, eventID); values.put(Reminders.METHOD, Reminders.METHOD_ALERT); Uri uri = cr.insert(Reminders.CONTENT_URI, values);
インスタンスのテーブル
「
CalendarContract.Instances
テーブルには、
イベントの発生時刻の開始時刻と終了時刻。このテーブルの各行
単一のイベントの発生を表します。インスタンス テーブルは書き込みはできず、
は、イベントの発生をクエリする手段を提供します。
次の表に、インスタンスに対してクエリできるフィールドの一部を示します。備考
タイムゾーンは
KEY_TIMEZONE_TYPE
および
KEY_TIMEZONE_INSTANCES
。
定数 | 説明 |
---|---|
BEGIN |
インスタンスの開始時刻(UTC ミリ秒)。 |
END |
インスタンスの終了時刻(UTC ミリ秒単位)。 |
END_DAY |
インスタンスの、カレンダーのタイムゾーンにおけるユリウス暦での終了日。 |
END_MINUTE |
米国の午前 0 時から測定されたインスタンスの終了時刻(分)は、 カレンダーのタイムゾーンが適用されます。 |
EVENT_ID |
このインスタンスのイベントの _ID 。 |
START_DAY |
カレンダーのタイムゾーンを基準とする、インスタンスのジュリアン開始日。 |
START_MINUTE |
午前 0 時を基準として測定されたインスタンスの開始分(分)。 カレンダーのタイムゾーンが適用されます。 |
instances テーブルにクエリを実行する
Instances テーブルにクエリするには、クエリの範囲を示す時刻を URI に指定する必要があります。この例では、CalendarContract.Instances
です。
「TITLE
」フィールドへのアクセス権を取得する
CalendarContract.EventsColumns
インターフェースの実装。
つまり、TITLE
はデータベース ビューによって返されているのであって、CalendarContract.Instances
テーブルそのものへのクエリによって返されているのではありません。
Kotlin
const val DEBUG_TAG: String = "MyActivity" val INSTANCE_PROJECTION: Array<String> = arrayOf( CalendarContract.Instances.EVENT_ID, // 0 CalendarContract.Instances.BEGIN, // 1 CalendarContract.Instances.TITLE // 2 ) // The indices for the projection array above. const val PROJECTION_ID_INDEX: Int = 0 const val PROJECTION_BEGIN_INDEX: Int = 1 const val PROJECTION_TITLE_INDEX: Int = 2 // Specify the date range you want to search for recurring // event instances val startMillis: Long = Calendar.getInstance().run { set(2011, 9, 23, 8, 0) timeInMillis } val endMillis: Long = Calendar.getInstance().run { set(2011, 10, 24, 8, 0) timeInMillis } // The ID of the recurring event whose instances you are searching // for in the Instances table val selection: String = "${CalendarContract.Instances.EVENT_ID} = ?" val selectionArgs: Array<String> = arrayOf("207") // Construct the query with the desired date range. val builder: Uri.Builder = CalendarContract.Instances.CONTENT_URI.buildUpon() ContentUris.appendId(builder, startMillis) ContentUris.appendId(builder, endMillis) // Submit the query val cur: Cursor = contentResolver.query( builder.build(), INSTANCE_PROJECTION, selection, selectionArgs, null ) while (cur.moveToNext()) { // Get the field values val eventID: Long = cur.getLong(PROJECTION_ID_INDEX) val beginVal: Long = cur.getLong(PROJECTION_BEGIN_INDEX) val title: String = cur.getString(PROJECTION_TITLE_INDEX) // Do something with the values. Log.i(DEBUG_TAG, "Event: $title") val calendar = Calendar.getInstance().apply { timeInMillis = beginVal } val formatter = SimpleDateFormat("MM/dd/yyyy") Log.i(DEBUG_TAG, "Date: ${formatter.format(calendar.time)}") }
Java
private static final String DEBUG_TAG = "MyActivity"; public static final String[] INSTANCE_PROJECTION = new String[] { Instances.EVENT_ID, // 0 Instances.BEGIN, // 1 Instances.TITLE // 2 }; // The indices for the projection array above. private static final int PROJECTION_ID_INDEX = 0; private static final int PROJECTION_BEGIN_INDEX = 1; private static final int PROJECTION_TITLE_INDEX = 2; ... // Specify the date range you want to search for recurring // event instances Calendar beginTime = Calendar.getInstance(); beginTime.set(2011, 9, 23, 8, 0); long startMillis = beginTime.getTimeInMillis(); Calendar endTime = Calendar.getInstance(); endTime.set(2011, 10, 24, 8, 0); long endMillis = endTime.getTimeInMillis(); Cursor cur = null; ContentResolver cr = getContentResolver(); // The ID of the recurring event whose instances you are searching // for in the Instances table String selection = Instances.EVENT_ID + " = ?"; String[] selectionArgs = new String[] {"207"}; // Construct the query with the desired date range. Uri.Builder builder = Instances.CONTENT_URI.buildUpon(); ContentUris.appendId(builder, startMillis); ContentUris.appendId(builder, endMillis); // Submit the query cur = cr.query(builder.build(), INSTANCE_PROJECTION, selection, selectionArgs, null); while (cur.moveToNext()) { String title = null; long eventID = 0; long beginVal = 0; // Get the field values eventID = cur.getLong(PROJECTION_ID_INDEX); beginVal = cur.getLong(PROJECTION_BEGIN_INDEX); title = cur.getString(PROJECTION_TITLE_INDEX); // Do something with the values. Log.i(DEBUG_TAG, "Event: " + title); Calendar calendar = Calendar.getInstance(); calendar.setTimeInMillis(beginVal); DateFormat formatter = new SimpleDateFormat("MM/dd/yyyy"); Log.i(DEBUG_TAG, "Date: " + formatter.format(calendar.getTime())); } }
カレンダー インテント
アプリケーションがカレンダー データの読み取りや書き込みを実行するのに権限は要りません。その代わりに、Android のカレンダー アプリケーションがサポートするインテントを使用し、読み取りと書き込みの操作をそのアプリケーションに引き渡します。次の表に、カレンダー プロバイダがサポートするインテントを示します。
アクション | URI | 説明 | その他 |
---|---|---|---|
VIEW |
CalendarContract.CONTENT_URI 。
このインテントの使用例については、インテントを使用してカレンダー データを表示するをご覧ください。
|
<ms_since_epoch> で指定された時間にカレンダーを開く。 |
なし。 |
Events.CONTENT_URI を使用しても参照できます。このインテントの使用例については、インテントを使用してカレンダー データを表示するをご覧ください。
|
<event_id> で指定されたイベントを表示します。 |
CalendarContract.EXTRA_EVENT_BEGIN_TIME CalendarContract.EXTRA_EVENT_END_TIME |
|
EDIT |
Events.CONTENT_URI を使用しても参照できます。このインテントの使用例については、インテントを使用したイベントの編集をご覧ください。
|
<event_id> で指定されたイベントを編集します。 |
CalendarContract.EXTRA_EVENT_BEGIN_TIME CalendarContract.EXTRA_EVENT_END_TIME |
EDIT INSERT |
Events.CONTENT_URI 。
このインテントの使用例については、インテントを使用してイベントを挿入するをご覧ください。
|
予定を作成します。 | 次の表に示された任意のエクストラ。 |
次の表に、カレンダー プロバイダでサポートされているインテント エクストラを示します。
インテント エクストラ | 説明 |
---|---|
Events.TITLE |
イベントの名前。 |
CalendarContract.EXTRA_EVENT_BEGIN_TIME |
イベントの開始時刻(エポックからのミリ秒単位)。 |
CalendarContract.EXTRA_EVENT_END_TIME |
イベントの終了時刻(エポックからのミリ秒単位)。 |
CalendarContract.EXTRA_EVENT_ALL_DAY |
イベントが終日であることを示すブール値。指定できる値:
true または false 。 |
Events.EVENT_LOCATION |
イベントの場所。 |
Events.DESCRIPTION |
イベントの説明。 |
Intent.EXTRA_EMAIL |
招待者のメールアドレス(コンマ区切りリスト形式)。 |
Events.RRULE |
イベントの繰り返しルール。 |
Events.ACCESS_LEVEL |
イベントが公開か非公開か。 |
Events.AVAILABILITY |
このイベントを埋まっている時間に数えるか、それともスケジュールのやり直しが利く空き時間とみなすか。 |
以降のセクションでは、これらのインテントの使用方法について説明します。
インテントを使用してイベントを挿入する
INSERT
インテントを使用する
を使用すると、アプリケーションからカレンダー自体に予定の挿入タスクを渡すことができます。
このアプローチでは、マニフェスト ファイルに WRITE_CALENDAR
権限を含める必要はありません。
このアプローチを使用するアプリケーションをユーザーが実行すると、
予定の追加を完了します。INSERT
インテントでは、追加フィールドを使用して以下の操作を行います。
カレンダーの予定の詳細がフォームに事前入力されます。それに対して、ユーザーはイベントのキャンセル、必要に応じたイベントの編集、イベントのカレンダーへの保存ができます。
2012 年 1 月 19 日にイベントのスケジュールを設定するコード スニペットを以下に示します。 を呼び出せます。このコード スニペットについては、次の点に注意してください。
Events.CONTENT_URI
を指定します。 として指定します。CalendarContract.EXTRA_EVENT_BEGIN_TIME
とCalendarContract.EXTRA_EVENT_END_TIME
の追加フィールドを使用して、イベントの時間をフォームに自動入力します。これらの値は、エポックからの UTC ミリ秒単位であることが必要です。Intent.EXTRA_EMAIL
エクストラ フィールドを使用して、参加者をメールアドレスで示したコンマ区切りリストを指定しています。
Kotlin
val startMillis: Long = Calendar.getInstance().run { set(2012, 0, 19, 7, 30) timeInMillis } val endMillis: Long = Calendar.getInstance().run { set(2012, 0, 19, 8, 30) timeInMillis } val intent = Intent(Intent.ACTION_INSERT) .setData(CalendarContract.Events.CONTENT_URI) .putExtra(CalendarContract.EXTRA_EVENT_BEGIN_TIME, startMillis) .putExtra(CalendarContract.EXTRA_EVENT_END_TIME, endMillis) .putExtra(CalendarContract.Events.TITLE, "Yoga") .putExtra(CalendarContract.Events.DESCRIPTION, "Group class") .putExtra(CalendarContract.Events.EVENT_LOCATION, "The gym") .putExtra(CalendarContract.Events.AVAILABILITY, CalendarContract.Events.AVAILABILITY_BUSY) .putExtra(Intent.EXTRA_EMAIL, "rowan@example.com,trevor@example.com") startActivity(intent)
Java
Calendar beginTime = Calendar.getInstance(); beginTime.set(2012, 0, 19, 7, 30); Calendar endTime = Calendar.getInstance(); endTime.set(2012, 0, 19, 8, 30); Intent intent = new Intent(Intent.ACTION_INSERT) .setData(Events.CONTENT_URI) .putExtra(CalendarContract.EXTRA_EVENT_BEGIN_TIME, beginTime.getTimeInMillis()) .putExtra(CalendarContract.EXTRA_EVENT_END_TIME, endTime.getTimeInMillis()) .putExtra(Events.TITLE, "Yoga") .putExtra(Events.DESCRIPTION, "Group class") .putExtra(Events.EVENT_LOCATION, "The gym") .putExtra(Events.AVAILABILITY, Events.AVAILABILITY_BUSY) .putExtra(Intent.EXTRA_EMAIL, "rowan@example.com,trevor@example.com"); startActivity(intent);
インテントを使用したイベントの編集
イベントは直接更新できます。詳しくは、イベントの更新をご覧ください。ただし、EDIT
インテントを使用すれば、パーミッションのないアプリケーションが、カレンダー アプリケーションにイベント編集を引き渡すことができます。ユーザーがカレンダーで予定の編集を完了すると、
使用できます。
次の例のインテントは、指定されたイベントの新しいタイトルを設定して、ユーザーがそのイベントをカレンダーで編集できるようにしています。
Kotlin
val eventID: Long = 208 val uri: Uri = ContentUris.withAppendedId(CalendarContract.Events.CONTENT_URI, eventID) val intent = Intent(Intent.ACTION_EDIT) .setData(uri) .putExtra(CalendarContract.Events.TITLE, "My New Title") startActivity(intent)
Java
long eventID = 208; Uri uri = ContentUris.withAppendedId(Events.CONTENT_URI, eventID); Intent intent = new Intent(Intent.ACTION_EDIT) .setData(uri) .putExtra(Events.TITLE, "My New Title"); startActivity(intent);
インテントを使用してカレンダー データを表示する
カレンダー プロバイダでは、VIEW
インテントを使用するために次の 2 つの方法が用意されています。
- 特定の日付のカレンダーを開く方法。
- アクティビティを表示する。
次の例は、特定の日付のカレンダーを開く方法を示しています。
Kotlin
val startMillis: Long ... val builder: Uri.Builder = CalendarContract.CONTENT_URI.buildUpon() .appendPath("time") ContentUris.appendId(builder, startMillis) val intent = Intent(Intent.ACTION_VIEW) .setData(builder.build()) startActivity(intent)
Java
// A date-time specified in milliseconds since the epoch. long startMillis; ... Uri.Builder builder = CalendarContract.CONTENT_URI.buildUpon(); builder.appendPath("time"); ContentUris.appendId(builder, startMillis); Intent intent = new Intent(Intent.ACTION_VIEW) .setData(builder.build()); startActivity(intent);
次の例は、イベントを開いて表示する方法を示したものです。
Kotlin
val eventID: Long = 208 ... val uri: Uri = ContentUris.withAppendedId(CalendarContract.Events.CONTENT_URI, eventID) val intent = Intent(Intent.ACTION_VIEW).setData(uri) startActivity(intent)
Java
long eventID = 208; ... Uri uri = ContentUris.withAppendedId(Events.CONTENT_URI, eventID); Intent intent = new Intent(Intent.ACTION_VIEW) .setData(uri); startActivity(intent);
同期アダプター
アプリケーションと同期アダプタとの間で、カレンダー プロバイダにアクセスする方法の違いは、次のいくつかだけです。
- 同期アダプタは、
CALLER_IS_SYNCADAPTER
をtrue
に設定して、それが同期アダプタであることを示す必要があります。 - 同期アダプタは、
ACCOUNT_NAME
とACCOUNT_TYPE
をクエリ パラメータとして URI に指定する必要があります。 - 同期アダプターには、アプリケーションまたはウィジェットよりも多くの列への書き込みアクセス権があります。
たとえば、アプリケーションで変更できるのは、カレンダーの特性の一部のみです。
名前、表示名、公開設定、カレンダーが
同期します。これに対し、同期アダプターはこれらの列だけでなく、他の多くの列にもアクセスできます。
カレンダーの色、タイムゾーン、アクセスレベル、場所などです
ただし、同期アダプターは
ACCOUNT_NAME
とACCOUNT_TYPE
。
次に示すヘルパー メソッドを使用すると、同期アダプタで使用するための URI が返されます。
Kotlin
fun asSyncAdapter(uri: Uri, account: String, accountType: String): Uri { return uri.buildUpon() .appendQueryParameter(CalendarContract.CALLER_IS_SYNCADAPTER, "true") .appendQueryParameter(CalendarContract.Calendars.ACCOUNT_NAME, account) .appendQueryParameter(CalendarContract.Calendars.ACCOUNT_TYPE, accountType).build() }
Java
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(); }