page.title=カレンダー プロバイダ @jd:body

本書の内容

  1. 基本
  2. ユーザー パーミッション
  3. Calendars テーブル
    1. カレンダーへのクエリ
    2. カレンダーの変更
    3. カレンダーの挿入
  4. Events テーブル
    1. イベントの追加
    2. イベントのアップデート
    3. イベントの削除
  5. Attendees テーブル
    1. 参加者の追加
  6. Reminders テーブル
    1. リマインダーの追加
  7. Instances テーブル
    1. Instances テーブルへのクエリ
  8. カレンダーのインテント
    1. インテントを使用したイベントの挿入
    2. インテントを使用したイベントの編集
    3. インテントを使用したカレンダー データの参照
  9. 同期アダプタ

キークラス

  1. {@link android.provider.CalendarContract.Calendars}
  2. {@link android.provider.CalendarContract.Events}
  3. {@link android.provider.CalendarContract.Attendees}
  4. {@link android.provider.CalendarContract.Reminders}

カレンダー プロバイダは、ユーザーのカレンダー イベントのためのリポジトリです。カレンダー プロバイダ API を使用すると、カレンダー、イベント、参加者、リマインダーなどに対するクエリ、挿入、アップデート、削除の操作を実行できます。

カレンダー プロバイダ API は、アプリケーションや同期アダプタで使用できます。ルールは、呼び出しを実行しているプログラムのタイプによって異なります。 本書では主に、カレンダー プロバイダ API のアプリケーションとしての使用について説明します。 同期アダプタの場合の違いについては、同期アダプタをご覧ください。

通常、カレンダー データを読み取ったり書き込んだりするためには、アプリケーションのマニフェストにユーザー パーミッションで説明している適切なパーミッションが含まれている必要があります。 一般的な操作を簡単に実行できるようにするため、カレンダー プロバイダには、いくつかのインテントが用意されています。これらについては、カレンダーのインテントで説明しています。 これらのインテントは、ユーザーをカレンダー アプリケーションに誘導して、イベントを挿入、参照、編集できるようにします。 ユーザーは、カレンダー アプリケーションを操作した後、元のアプリケーションに戻ります。 これにより、アプリケーションがパーミッションを要求したり、イベントの参照や作成のためのインターフェースを提供したりする必要がなくなります。

基本

コンテンツ プロバイダは、データを保存してアプリケーションからアクセスできるようにします。 Android プラットフォームによって提供されるコンテンツ プロバイダ(カレンダー プロバイダを含む)は、一般にリレーショナル データベース モデルに基づくテーブルのセットとしてデータを公開します。このモデルにおいて、各行はレコード、各列は特定のタイプと意味のデータになっています。 アプリケーションと同期アダプタは、ユーザーのカレンダー データを保持するデータベース テーブルの読み取りおよび書き込みアクセスを、カレンダー プロバイダ API を使用して取得できます。

各コンテンツ プロバイダは、データセットを一意に指定するパブリック URI({@link android.net.Uri} オブジェクトとしてラップされています)を公開します。 複数のデータセット(複数のテーブル)を制御するコンテンツ プロバイダは、データセットごとに個別の URI を公開します。 プロバイダの URI はすべて、文字列「content://」で始まります。 これは、コンテンツ プロバイダによって管理されているデータであることを示します。 カレンダー プロバイダは、クラス(テーブル)それぞれの URI のための定数を定義します。 URI の形式は <class>.CONTENT_URI です。 たとえば、{@link android.provider.CalendarContract.Events#CONTENT_URI Events.CONTENT_URI} のようになります。

図 1 に、カレンダー プロバイダのデータモデルを図示します。メイン テーブルとそれらを相互にリンクしているフィールドが示されています。

Calendar Provider Data Model

図 1. カレンダー プロバイダのデータモデル。

ユーザーは複数のカレンダーを持つことができ、カレンダーをそれぞれ異なるタイプのアカウント(Google カレンダー、Exchange など)と関連付けることができます。

{@link android.provider.CalendarContract} は、カレンダーのデータモデルとイベント関連の情報を定義します。データは、次に示すいくつかのテーブルに保存されます。

テーブル(クラス) 説明

{@link android.provider.CalendarContract.Calendars}

このテーブルは、該当するカレンダー固有の情報を保持します。 各行には、名前、色、同期情報など、1 つのカレンダーに関する詳細が格納されます。
{@link android.provider.CalendarContract.Events} このテーブルは、該当するイベント固有の情報を保持します。 各行には、1 つのイベントに関する情報が格納されます—イベントのタイトル、場所、開始時刻、終了時刻などが該当します。 イベントは、単発だったり繰り返し発生したりすることが考えられます。参加者、リマインダー、拡張プロパティは、個別のテーブルに格納されます。 これらのテーブルにはそれぞれ、Events テーブルの {@link android.provider.BaseColumns#_ID} を参照する {@link android.provider.CalendarContract.AttendeesColumns#EVENT_ID} があります。
{@link android.provider.CalendarContract.Instances} このテーブルは、あるイベントの発生ごとの開始時刻と終了時刻を保持します。 各行は、イベントの発生 1 回を表します。 単発イベントには、イベントのインスタンスが 1 対 1 で対応します。 繰り返しのイベントには、そのイベントの複数回の発生それぞれに対応する複数の行が自動生成されます。
{@link android.provider.CalendarContract.Attendees} このテーブルは、イベントの参加者(ゲスト)の情報を保持します。 各行は、1 回のイベントの 1 人のゲストを表します。 ゲストのタイプと、ゲストのイベントへの出欠の回答を指定します。
{@link android.provider.CalendarContract.Reminders} このテーブルは、アラートや通知のデータを保持します。 各行は、1 回のイベントの 1 つのアラートを表します。1 つのイベントが複数のリマインダーを持つことができます。 1 イベントあたりの最大リマインダー数は {@link android.provider.CalendarContract.CalendarColumns#MAX_REMINDERS} で指定され、指定されたカレンダーを所有する同期アダプタによって設定されます。 リマインダーは、イベント開始前の分単位で指定され、ユーザーに注意喚起する手段を示す情報を保持します。

カレンダー プロバイダ API は、柔軟で効果的な設計になっています。ですが同時に、エンドユーザーにとって使いやすくすることや、カレンダーとそのデータの整合性を保護することが重要です。 次に、そのために API の使用に際して留意すべきことを示します。

ユーザー パーミッション

カレンダー データを読み込むためには、アプリケーションはマニフェスト ファイルに {@link android.Manifest.permission#READ_CALENDAR} パーミッションを含める必要があります。 カレンダー データを削除、挿入、アップデートするためには、{@link android.Manifest.permission#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 テーブル

{@link android.provider.CalendarContract.Calendars} テーブルには、個々のカレンダーの詳細情報が格納されます。 次に示す Calendars の列は、アプリケーションと同期アダプタのどちらからも書き込み可能です。 サポートされているすべてのフィールドの一覧については、{@link android.provider.CalendarContract.Calendars} のリファレンスをご覧ください。

定数 説明
{@link android.provider.CalendarContract.Calendars#NAME} カレンダーの名前。
{@link android.provider.CalendarContract.Calendars#CALENDAR_DISPLAY_NAME} ユーザーに表示されるこのカレンダーの名前。
{@link android.provider.CalendarContract.Calendars#VISIBLE} カレンダーが表示対象として選択されているかどうかを示すブール値。値 0 は、このカレンダーに関連付けられているイベントを表示しないことを示します。 値 1 は、このカレンダーに関連付けられているイベントを表示することを示します。 この値は、{@link android.provider.CalendarContract.Instances} テーブルの行の生成に影響を与えます。
{@link android.provider.CalendarContract.CalendarColumns#SYNC_EVENTS} カレンダーを同期してそのイベントを端末に格納するかどうかを示すブール値。 値 0 は、このカレンダーを同期せず、イベントを端末に格納しないことを指定します。 値 1 は、このカレンダーのイベントを同期し、イベントを端末に格納することを指定します。

カレンダーへのクエリ

次の例は、特定のユーザーが所有するカレンダーを取得する方法を示しています。 簡潔にするため、この例のクエリ操作はユーザー インターフェース スレッド(「メインスレッド」)内に示されています。 実際には、メインスレッドではなく非同期スレッドで実行してください。 詳細については、「ローダ」をご覧ください。 データを読み込むだけでなく変更する場合は、{@link android.content.AsyncQueryHandler} をご覧ください。

// 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 が「sampleuser@google.com」で、ACCOUNT_TYPE が「com.google」で、OWNER_ACCOUNT が「sampleuser@google.com」であるカレンダーを検索します。 ユーザーが所有しているだけでなく参照したことのあるすべてのカレンダーを確認するには、OWNER_ACCOUNT を省略します。このクエリは、データベース クエリが返した結果セットをトラバースするのに使用できる {@link android.database.Cursor} オブジェクトを返します。 コンテンツ プロバイダでのクエリの使用については、「コンテンツ プロバイダ」をご覧ください。

// 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[] {"sampleuser@gmail.com", "com.google",
        "sampleuser@gmail.com"}; 
// Submit the query and get a Cursor object back. 
cur = cr.query(uri, EVENT_PROJECTION, selection, selectionArgs, null);

次のセクションでは、カーソルを使用して結果セットをステップ単位で移動します。例の冒頭で設定した定数を使用して各フィールドの値を返します。

// 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...

   ...
}

カレンダーの変更

カレンダーのアップデートを実行する場合、カレンダーの {@link android.provider.BaseColumns#_ID} を、URI({@link android.content.ContentUris#withAppendedId(android.net.Uri,long) withAppendedId()})の末尾に追加された ID として、または最初の selection 項目として指定できます。 先ほどの selection を "_id=?" で始め、最初の selectionArg をカレンダーの {@link android.provider.BaseColumns#_ID} にする必要があります。 URL に含まれる ID をエンコードすることでも、アップデートを実行できます。この例では、カレンダーの表示名をこの({@link android.content.ContentUris#withAppendedId(android.net.Uri,long) withAppendedId()} を使用する)アプローチで変更しています。

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

カレンダーの挿入

カレンダーは主に同期アダプタで管理するように設計されているため、新しいカレンダーは必ず同期アダプタとして挿入してください。 ほとんどの場合、アプリケーションはカレンダーに対し、表示名の変更のような表面的な変更しかできません。 アプリケーションがローカル カレンダーを作成する必要がある場合は、{@link android.provider.CalendarContract.SyncColumns#ACCOUNT_TYPE} として {@link android.provider.CalendarContract#ACCOUNT_TYPE_LOCAL} を使用し、カレンダーの挿入を同期アダプタとして実行することで作成できます。{@link android.provider.CalendarContract#ACCOUNT_TYPE_LOCAL} は、端末アカウントと関連付けられていないカレンダー用の特殊なアカウント タイプです。 このタイプのカレンダーは、サーバーと同期されません。同期アダプタの詳細については、同期アダプタをご覧ください。

Events テーブル

{@link android.provider.CalendarContract.Events} テーブルには、個々のイベントの詳細情報が格納されます。 イベントを追加、アップデート、削除するためには、アプリケーションはマニフェスト ファイルに {@link android.Manifest.permission#WRITE_CALENDAR} パーミッションを含める必要があります。

次に示す Events の列は、アプリケーションと同期アダプタのどちらからも書き込み可能です。 サポートされているすべてのフィールドの一覧については、{@link android.provider.CalendarContract.Events} のリファレンスをご覧ください。

定数 説明
{@link android.provider.CalendarContract.EventsColumns#CALENDAR_ID} イベントが属するカレンダーの {@link android.provider.BaseColumns#_ID}。
{@link android.provider.CalendarContract.EventsColumns#ORGANIZER} イベントの主催者(所有者)のメールアドレス。
{@link android.provider.CalendarContract.EventsColumns#TITLE} イベントのタイトル。
{@link android.provider.CalendarContract.EventsColumns#EVENT_LOCATION} イベントが開催される場所。
{@link android.provider.CalendarContract.EventsColumns#DESCRIPTION} イベントの説明。
{@link android.provider.CalendarContract.EventsColumns#DTSTART} エポックからの UTC ミリ秒単位で表現されたイベント開始時刻。
{@link android.provider.CalendarContract.EventsColumns#DTEND} エポックからの UTC ミリ秒単位で表現されたイベント終了時刻。
{@link android.provider.CalendarContract.EventsColumns#EVENT_TIMEZONE} イベントのタイムゾーン。
{@link android.provider.CalendarContract.EventsColumns#EVENT_END_TIMEZONE} イベントの終了時刻のタイムゾーン。
{@link android.provider.CalendarContract.EventsColumns#DURATION} RFC5545 形式でのイベントの期間。たとえば、"PT1H" という値はイベントが 1 時間であること、"P2W" という値は期間が 2 週間であることを示します。
{@link android.provider.CalendarContract.EventsColumns#ALL_DAY} 値 1 は、そのイベントがローカルのタイムゾーンで定義された終日を占めることを示します。 値 0 は、1 日のどこかで始まって終わる定例のイベントであることを示します。
{@link android.provider.CalendarContract.EventsColumns#RRULE} イベント形式の繰り返し発生ルール。たとえば、"FREQ=WEEKLY;COUNT=10;WKST=SU" のようになります。 その他の例については、こちらをご覧ください。
{@link android.provider.CalendarContract.EventsColumns#RDATE} イベントの繰り返し発生日。通常、{@link android.provider.CalendarContract.EventsColumns#RDATE} は {@link android.provider.CalendarContract.EventsColumns#RRULE} と組み合わせて、繰り返し発生全体を定義するのに使用します。 詳細については、RFC5545 の仕様をご覧ください。
{@link android.provider.CalendarContract.EventsColumns#AVAILABILITY} このイベントを埋まっている時間に数えるか、それともスケジュールのやり直しが利く空き時間とみなすか。
{@link android.provider.CalendarContract.EventsColumns#GUESTS_CAN_MODIFY} ゲストがイベントを変更できるかどうか。
{@link android.provider.CalendarContract.EventsColumns#GUESTS_CAN_INVITE_OTHERS} ゲストが他のゲストを招待できるかどうか。
{@link android.provider.CalendarContract.EventsColumns#GUESTS_CAN_SEE_GUESTS} ゲストが他の参加者のリストを参照できるかどうか。

イベントの追加

アプリケーションが新しいイベントを挿入する場合は、{@link android.content.Intent#ACTION_INSERT INSERT} インテントを使用することをお勧めします。詳細については、インテントを使用したイベントの挿入をご覧ください。 ただし、必要があればイベントを直接挿入できます。 ここではその方法について説明します。

新しいイベントを挿入するためのルールは次のとおりです。

イベントの挿入の例を次に示します。簡潔にするため、この例は UI スレッドで実行されています。 実際には、挿入やアップデートは非同期スレッドで実行して、アクションをバックグラウンド スレッドに移してください。 詳細については、{@link android.content.AsyncQueryHandler} をご覧ください。

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 が必要になることはよくあります—イベントに対する参加者やリマインダーの追加などが該当します。

イベントのアップデート

アプリケーションでユーザーによるイベントの編集を許可する場合は、{@link android.content.Intent#ACTION_EDIT EDIT} インテントを使用することをお勧めします。詳細については、インテントを使用したイベントの挿入をご覧ください。ただし、イベントは必要に応じて直接編集できます。 イベントのアップデートを実行する場合は、イベントの _ID を、URI({@link android.content.ContentUris#withAppendedId(android.net.Uri,long) withAppendedId()})の末尾に追加された ID として、または前出の selection の最初の項目として指定できます。 前出の selection を "_id=?" で始め、最初の selectionArg をカレンダーの _ID にする必要があります。 ID なしの selection を使用してアップデートすることもできます。次に、イベントのアップデートの例を示します。 ここでは、{@link android.content.ContentUris#withAppendedId(android.net.Uri,long) withAppendedId()} を使用するアプローチでイベントのタイトルを変更しています。

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 = getContentResolver().update(updateUri, values, null, null);
Log.i(DEBUG_TAG, "Rows updated: " + rows);  

イベントの削除

イベントは、目的のイベントの {@link android.provider.BaseColumns#_ID} を URI の末尾に追加する ID として使用するか、標準的な選択を使用して削除できます。 ID の追加で削除を実行する場合、選択はできません。削除には、アプリケーションとして実行する方法と同期アダプタとして実行する方法の 2 種類があります。 アプリケーションとしての削除では、削除される列が 1 に設定されます。 このフラグは同期アダプタに対して、その行が削除されたことを通知し、この削除をサーバーに通知するよう指示します。 同期アダプタとしての削除では、すべての関連データとともにデータベースからイベントが削除されます。 次の例では、アプリケーションがイベントをその {@link android.provider.BaseColumns#_ID} を使用して削除しています。

private static final String DEBUG_TAG = "MyActivity";
...
long eventID = 201;
...
ContentResolver cr = getContentResolver();
ContentValues values = new ContentValues();
Uri deleteUri = null;
deleteUri = ContentUris.withAppendedId(Events.CONTENT_URI, eventID);
int rows = getContentResolver().delete(deleteUri, null, null);
Log.i(DEBUG_TAG, "Rows deleted: " + rows);  

Attendees テーブル

{@link android.provider.CalendarContract.Attendees} テーブルの各行は、あるイベントの 1 人の参加者ないしゲストを表します。 {@link android.provider.CalendarContract.Reminders#query(android.content.ContentResolver, long, java.lang.String[]) query()} を呼び出すと、指定された {@link android.provider.CalendarContract.AttendeesColumns#EVENT_ID} を持つイベントの参加者リストが返されます。 この {@link android.provider.CalendarContract.AttendeesColumns#EVENT_ID} は特定のイベントの {@link android.provider.BaseColumns#_ID} と一致している必要があります。

次の表に、書き込み可能なフィールドを示します。 新しい参加者を挿入する際には、ATTENDEE_NAME を除くすべてを含める必要があります。

定数 説明
{@link android.provider.CalendarContract.AttendeesColumns#EVENT_ID} イベントの ID。
{@link android.provider.CalendarContract.AttendeesColumns#ATTENDEE_NAME} 参加者の名前。
{@link android.provider.CalendarContract.AttendeesColumns#ATTENDEE_EMAIL} 参加者のメールアドレス。
{@link android.provider.CalendarContract.AttendeesColumns#ATTENDEE_RELATIONSHIP}

参加者のイベントに対する関係。次のどれかです。

  • {@link android.provider.CalendarContract.AttendeesColumns#RELATIONSHIP_ATTENDEE}
  • {@link android.provider.CalendarContract.AttendeesColumns#RELATIONSHIP_NONE}
  • {@link android.provider.CalendarContract.AttendeesColumns#RELATIONSHIP_ORGANIZER}
  • {@link android.provider.CalendarContract.AttendeesColumns#RELATIONSHIP_PERFORMER}
  • {@link android.provider.CalendarContract.AttendeesColumns#RELATIONSHIP_SPEAKER}
{@link android.provider.CalendarContract.AttendeesColumns#ATTENDEE_TYPE}

参加者のタイプ。次のどれかです。

  • {@link android.provider.CalendarContract.AttendeesColumns#TYPE_REQUIRED}
  • {@link android.provider.CalendarContract.AttendeesColumns#TYPE_OPTIONAL}
{@link android.provider.CalendarContract.AttendeesColumns#ATTENDEE_STATUS}

参加者の出席ステータス。次のどれかです。

  • {@link android.provider.CalendarContract.AttendeesColumns#ATTENDEE_STATUS_ACCEPTED}
  • {@link android.provider.CalendarContract.AttendeesColumns#ATTENDEE_STATUS_DECLINED}
  • {@link android.provider.CalendarContract.AttendeesColumns#ATTENDEE_STATUS_INVITED}
  • {@link android.provider.CalendarContract.AttendeesColumns#ATTENDEE_STATUS_NONE}
  • {@link android.provider.CalendarContract.AttendeesColumns#ATTENDEE_STATUS_TENTATIVE}

参加者の追加

次の例では、あるイベントに 1 人の参加者を挿入しています。{@link android.provider.CalendarContract.AttendeesColumns#EVENT_ID} は必須です。

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 テーブル

{@link android.provider.CalendarContract.Reminders} テーブルの各行は、あるイベントの 1 つのリマインダーを表します。 {@link android.provider.CalendarContract.Reminders#query(android.content.ContentResolver, long, java.lang.String[]) query()} を呼び出すと、指定された {@link android.provider.CalendarContract.AttendeesColumns#EVENT_ID} を持つイベントのリマインダー リストが返されます。

次の表に、リマインダーに関する書き込み可能なフィールドを示します。新しいリマインダーを挿入する際には、これらをすべて含める必要があります。 同期アダプタは、サポートするリマインダーのタイプを {@link android.provider.CalendarContract.Calendars} テーブルで指定しています。 詳細については、{@link android.provider.CalendarContract.CalendarColumns#ALLOWED_REMINDERS} をご覧ください。

定数 説明
{@link android.provider.CalendarContract.RemindersColumns#EVENT_ID} イベントの ID。
{@link android.provider.CalendarContract.RemindersColumns#MINUTES} リマインダーが通知されるまでの分単位の時間。
{@link android.provider.CalendarContract.RemindersColumns#METHOD}

アラーム手段。サーバーに設定されます。次のどれかです。

  • {@link android.provider.CalendarContract.RemindersColumns#METHOD_ALERT}
  • {@link android.provider.CalendarContract.RemindersColumns#METHOD_DEFAULT}
  • {@link android.provider.CalendarContract.RemindersColumns#METHOD_EMAIL}
  • {@link android.provider.CalendarContract.RemindersColumns#METHOD_SMS}

リマインダーの追加

この例では、イベントにリマインダーを追加します。このリマインダーは、イベントの 15 分前に通知されます。

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

Instances テーブル

{@link android.provider.CalendarContract.Instances} テーブルは、あるイベントの発生の開始時刻と終了時刻を保持します。 各行は、イベントの発生 1 回を表します。 Instances テーブルは書き込みできません。イベントの発生をクエリする手段を提供するためだけのものです。

次の表に、インスタンスに関してクエリできるフィールドの一部を示します。タイムゾーンは {@link android.provider.CalendarContract.CalendarCache#KEY_TIMEZONE_TYPE} と {@link android.provider.CalendarContract.CalendarCache#KEY_TIMEZONE_INSTANCES} で定義されます。

定数 説明
{@link android.provider.CalendarContract.Instances#BEGIN} インスタンスの開始時刻(UTC ミリ秒単位)。
{@link android.provider.CalendarContract.Instances#END} インスタンスの終了時刻(UTC ミリ秒単位)。
{@link android.provider.CalendarContract.Instances#END_DAY} インスタンスの、カレンダーのタイムゾーンにおけるユリウス暦での終了日。
{@link android.provider.CalendarContract.Instances#END_MINUTE} カレンダーのタイムゾーンにおける午前零時を基準にしたインスタンスの終了分。
{@link android.provider.CalendarContract.Instances#EVENT_ID} このインスタンスのイベントの _ID
{@link android.provider.CalendarContract.Instances#START_DAY} インスタンスの、カレンダーのタイムゾーンにおけるユリウス暦での開始日。
{@link android.provider.CalendarContract.Instances#START_MINUTE} カレンダーのタイムゾーンにおける午前零時を基準にしたインスタンスの開始分。

Instances テーブルへのクエリ

Instances テーブルにクエリするには、クエリの範囲を示す時刻を URI に指定する必要があります。この例で、{@link android.provider.CalendarContract.Instances} は {@link android.provider.CalendarContract.EventsColumns} インターフェースの実装を介して {@link android.provider.CalendarContract.EventsColumns#TITLE} フィールドへのアクセスを取得します。 言い換えると、{@link android.provider.CalendarContract.EventsColumns#TITLE} はデータベースの参照に対して返されているのであって、{@link android.provider.CalendarContract.Instances} テーブルそのものへのクエリに対して返されているのではありません。

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 説明 エクストラ

{@link android.content.Intent#ACTION_VIEW VIEW}

content://com.android.calendar/time/<ms_since_epoch>

URI は、{@link android.provider.CalendarContract#CONTENT_URI CalendarContract.CONTENT_URI} を使用しても参照できます。 このインテントの使用例については、インテントを使用したカレンダー データの参照をご覧ください。
<ms_since_epoch> に指定された時刻でカレンダーを開きます。 なし

{@link android.content.Intent#ACTION_VIEW VIEW}

content://com.android.calendar/events/<event_id>

URI は、{@link android.provider.CalendarContract.Events#CONTENT_URI Events.CONTENT_URI} を使用しても参照できます。 このインテントの使用例については、インテントを使用したカレンダー データの参照をご覧ください。
<event_id> で指定されたイベントを参照します。 {@link android.provider.CalendarContract#EXTRA_EVENT_BEGIN_TIME CalendarContract.EXTRA_EVENT_BEGIN_TIME}


{@link android.provider.CalendarContract#EXTRA_EVENT_END_TIME CalendarContract.EXTRA_EVENT_END_TIME}
{@link android.content.Intent#ACTION_EDIT EDIT}

content://com.android.calendar/events/<event_id>

URI は、{@link android.provider.CalendarContract.Events#CONTENT_URI Events.CONTENT_URI} を使用しても参照できます。 このインテントの使用例については、インテントを使用したカレンダー データの編集をご覧ください。
<event_id> で指定されたイベントを編集します。 {@link android.provider.CalendarContract#EXTRA_EVENT_BEGIN_TIME CalendarContract.EXTRA_EVENT_BEGIN_TIME}


{@link android.provider.CalendarContract#EXTRA_EVENT_END_TIME CalendarContract.EXTRA_EVENT_END_TIME}
{@link android.content.Intent#ACTION_EDIT EDIT}

{@link android.content.Intent#ACTION_INSERT INSERT}

content://com.android.calendar/events

URI は、{@link android.provider.CalendarContract.Events#CONTENT_URI Events.CONTENT_URI} を使用しても参照できます。 このインテントの使用例については、インテントを使用したカレンダー データの挿入をご覧ください。
イベントを作成します。 次の表に示された任意のエクストラ。

次の表に、カレンダー プロバイダによってサポートされているインテント エクストラを示します。

インテント エクストラ 説明
{@link android.provider.CalendarContract.EventsColumns#TITLE Events.TITLE} イベントの名前。
{@link android.provider.CalendarContract#EXTRA_EVENT_BEGIN_TIME CalendarContract.EXTRA_EVENT_BEGIN_TIME} イベントの開始時刻(エポックからのミリ秒単位)。
{@link android.provider.CalendarContract#EXTRA_EVENT_END_TIME CalendarContract.EXTRA_EVENT_END_TIME} イベントの終了時刻(エポックからのミリ秒単位)。
{@link android.provider.CalendarContract#EXTRA_EVENT_ALL_DAY CalendarContract.EXTRA_EVENT_ALL_DAY} イベントが終日かどうかを示すブール値。使用できる値は true または false です。
{@link android.provider.CalendarContract.EventsColumns#EVENT_LOCATION Events.EVENT_LOCATION} イベントの場所。
{@link android.provider.CalendarContract.EventsColumns#DESCRIPTION Events.DESCRIPTION} イベントの説明。
{@link android.content.Intent#EXTRA_EMAIL Intent.EXTRA_EMAIL} 招待者のメールアドレス(コンマ区切りリスト形式)。
{@link android.provider.CalendarContract.EventsColumns#RRULE Events.RRULE} イベントの反復ルール。
{@link android.provider.CalendarContract.EventsColumns#ACCESS_LEVEL Events.ACCESS_LEVEL} イベントが公開か非公開か。
{@link android.provider.CalendarContract.EventsColumns#AVAILABILITY Events.AVAILABILITY} このイベントを埋まっている時間に数えるか、それともスケジュールのやり直しが利く空き時間とみなすか。

次のセクションでは、これらのインテント使用方法を説明します。

インテントを使用したイベントの挿入

{@link android.content.Intent#ACTION_INSERT INSERT} インテントを使用すると、アプリケーションはイベント挿入タスクをカレンダーそのものに引き渡すことができます。このアプローチでは、アプリケーションは {@link android.Manifest.permission#WRITE_CALENDAR} パーミッションをマニフェスト ファイルに含める必要さえなくなります。

このアプローチのアプリケーションをユーザーが実行すると、アプリケーションによってユーザーがカレンダーに誘導されイベントを追加できるようになります。 {@link android.content.Intent#ACTION_INSERT INSERT} インテントは、追加フィールドを使用して、カレンダーに格納されている詳細情報をフォームに自動入力します。 それに対して、ユーザーはイベントのキャンセル、必要に応じたイベントの編集、イベントのカレンダーへの保存ができます。

次に示すのは、2012 年 1 月 19 日の午前 7:30 から 午前 8:30 までのイベントをスケジュールするコード スニペットです。 このコード スニペットの以下の点に注目してください。

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

インテントを使用したイベントの編集

イベントは、イベントのアップデートで説明したように、直接アップデートできます。ただし、{@link android.content.Intent#ACTION_EDIT EDIT} インテントを使用すれば、パーミッションのないアプリケーションが、カレンダー アプリケーションにイベント編集を引き渡すことができます。カレンダーでのイベント編集を終えたユーザーは、元のアプリケーションに戻ります。

次の例のインテントは、指定されたイベントの新しいタイトルを設定して、ユーザーがそのイベントをカレンダーで編集できるようにしています。

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

インテントを使用したカレンダー データの参照

カレンダー プロバイダには、{@link android.content.Intent#ACTION_VIEW VIEW} インテントを使用する次の 2 つの方法が用意されています。

次の例は、特定の日付のカレンダーを開く方法を示しています。

// 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);

次の例は、参照するためにイベントを開く方法を示しています。

long eventID = 208;
...
Uri uri = ContentUris.withAppendedId(Events.CONTENT_URI, eventID);
Intent intent = new Intent(Intent.ACTION_VIEW)
   .setData(uri);
startActivity(intent);

同期アダプタ

アプリケーションと同期アダプタとの間で、カレンダー プロバイダにアクセスする方法の違いは、次のいくつかだけです。

次に示すヘルパー メソッドを使用すると、同期アダプタで使用するための URI が返されます。

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

同期アダプタの実装例(カレンダーに特化されたものではありません)については、SampleSyncAdapter をご覧ください。