Android 4.0の新機能を試す-AndroidでCalendarを操作する

2011.12.04

Ice Cream Sandwich

10月にAndroidの最新版OSであるIce Cream Sandwich(以下4.0と表記)のSDKが公開され、先日日本では初となる4.0搭載のスマートフォン、 「Galaxy Nexus」が発売されました。実機でいろいろとためせるようになったため、新機能を試してみます。

あらためてカレンダー操作を行う

以前の記事では、非公式のAPIを使用してAndroidのカレンダーを操作してみました。 4.0でカレンダー用のAPIが公式のAPIとなったため、android.provider.CalendarContractクラスを使用して操作することが可能です。 しかし、4.0ではいままで使用していた非公式APIは正しく動作しない場合もあるようなので、4.0で動くようにしてみましょう。

<h2新しいCalendar API

カレンダー用のデータは、CalendarContractというクラスによって定義されており、ユーザーのカレンダーデータは CalendarContractのサブクラスで定義される下記のテーブルに保存されます。

  • カレンダー自体の情報を持つCalendarContract.Calendars
  • カレンダーのイベント情報を持つCalendarContract.Events
  • イベント毎の開始時刻、終了時刻を持つCalendarContract.Instances
  • イベントの参加者に関する情報を持つCalendarContract.Attendees
  • アラート情報を持つCalendarContract.Reminders
  • 拡張用フィールドを持つCalendarContract.ExtendedProperties

なお、カレンダーデータにアクセスするためには READ_CALENDAR (読み込み)、WRITE_CALENDAR(書き込み)の権限が必要になります。

セットアップ

本記事での動作確認環境は下記の通りです。

  • OS : MacOS X 10.7.2
  • Android SDK : r15
  • 動作確認機種 : Galaxy Nexus

自分のカレンダー情報を取得してみる

では前回と同じく、自分のカレンダー情報を取得してみましょう。 Build targetをAndroid 4.0に指定し、Android Projectを作成します。 最初にAndroidManifest.xmlに権限を追加します。

<uses-permission android:name="android.permission.READ_CALENDAR" />
<uses-permission android:name="android.permission.WRITE_CALENDAR" />

次にActivityに処理を追加し、カレンダーを取得する処理を追加してみましょう。 ※下記コードはボタンを押したら実行なり起動時に実行なり、適当に組み込んでください。

import android.database.Cursor;
import android.net.Uri;
import android.util.Log;
import android.provider.CalendarContract;

// カラム
String[] projection = new String[] { "_id", "name" };
// Uriの作成
Uri calendars = CalendarContract.Calendars.CONTENT_URI;
// クエリ実行
Cursor c = managedQuery(calendars, projection, null, null, null);
// 値を取得
if (c.moveToFirst()) {
	String name;
	String id;
	int nameColumn = c.getColumnIndex("name");
	int idColumn = c.getColumnIndex("_id");
	do {
		name = c.getString(nameColumn);
		id = c.getString(idColumn);
		Log.d("Calendar Data", "id=" + id + ",name=" + name);
	} while (c.moveToNext());
}

カレンダー取得に関しては2.3以前とほぼ同じ処理内容です。違う点はURIをCalendarContract.Calendars.CONTENT_URIで指定している部分です。 ※一応、Uriを以前と同じく「content://com.android.calendar/calendars」と指定してもカレンダー取得は成功します

処理を実行してみると、自分のアカウントで登録されているカレンダーのIDと名前が取得できます。

イベントの登録をしてみる

次にイベント情報を自分のカレンダーに設定してみましょう。 ここも基本的にはいままでと同じくContentValuesを作成し、ContentResolverのメソッドでイベントを登録します。 ContentValuesのキーはCalendarContract.Eventsに定義されおり、CalendarContract.Events.CONTENT_URIのURIで登録します。

import android.database.Cursor;
import android.net.Uri;
import android.util.Log;
import android.provider.CalendarContract;
import android.content.ContentValues;

//イベント開始・終了時間を設定
long startMillis = 0;
long endMillis = 0;
Calendar beginTime = Calendar.getInstance();
beginTime.set(2012, 0, 1, 10, 00);
startMillis = beginTime.getTimeInMillis();
Calendar endTime = Calendar.getInstance();
endTime.set(2012, 0, 1, 12, 00);
endMillis = endTime.getTimeInMillis();

//イベントデータを登録
ContentResolver cr = getContentResolver();
ContentValues values = new ContentValues();
values.put(CalendarContract.Events.DTSTART, startMillis);
values.put(CalendarContract.Events.DTEND, endMillis);
values.put(CalendarContract.Events.TITLE, "テストイベント");
values.put(CalendarContract.Events.DESCRIPTION, "これはテストイベントです。");
values.put(CalendarContract.Events.CALENDAR_ID, <ここに登録したいカレンダーIDを設定>);
Uri uri = cr.insert(CalendarContract.Events.CONTENT_URI, values);

CalendarContract.Events.CALENDAR_IDにはイベントを登録したいカレンダーIDを指定します。 カレンダー取得コードで確認したカレンダーIDを設定してください。 実際に上記コードを実行すると、指定したカレンダーにイベントが登録され、Googleカレンダーにも同期されます。

まとめ

今回はAndroid 4.0でカレンダー情報にアクセスしてみました。 カレンダーの取得は2.3以前のコードでも動作しましたが、イベントの登録やカレンダー同期は以前のコードではうまく動作しないことがあるようです。 以前の非公式APIで実装したプログラムは、4.0での動作をあらためて見直す必要がありますね。

参考サイトなど