Hatena::ブログ(Diary)

にゃんだふる日記

2010-07-25

[][] Android 2.2 のカレンダーContentProvier に対応 12:32

タオソフトウェアさんの Android 2.2 のカレンダーパッケージ名 | の記事を見て、

カレンダーのRead/Writeを行っている自アプリも対応させないといけないなあ、と思いつつ

何となく動いている(時々、カレンダーアイテム削除の反応が遅いくらい)ので放置していたのですが、やっと対応しました。

アプリの場合、カレンダーパッケージを叩いているわけではなく、ContentProvier経由でカレンダーのRead/Writeを実行しているのですが、

下記のようにContentProvierが変更されていました。

Android 2.2未満
content://calendar
Android 2.2以上
content://com.android.calendar

アプリでは、Androidの元ソースのandroid.provider.Calendar をコピペしてCONTENT_URIを参照していました。

package android.provider;

import ....

public final class Calendar {

    public static final String AUTHORITY = "calendar";

    public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY);

その部分を今回、下記のように置き換えました。

定数:CONTENT_URIの部分を、static初期化ブロック内でAndroidバージョンを判定して置換しているのがポイントです。

アプリ側では、Androidバージョンの違いを意識することはありません(正確には、新規追加されたColumnがあるのだが、自アプリでは使っていないので)。

package android.provider;

import ....

public final class Calendar {

    // AUTHORITY は、static{} で初期化。
    public static final String AUTHORITY;

    public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY);

    static {
        final int sdkVersion = Build.VERSION.SDK_INT;
        // 8=Build.VERSION_CODES.FROYO
        if (sdkVersion < 8) {
            AUTHORITY = "calendar";
        } else {
            AUTHORITY = "com.android.calendar";
        }
    }

これで、Android 2.2 のカレンダーContentProvierに対応できたのですが、HTC SenseやAUのカレンダーContentProvierも違うらしいです。HTC Senseは、Desireがあるので対応する予定です。AUのやつは、実機が無いので検証できないのと、自アプリのニーズが少ないと思うので対応予定はありません。

HTCの場合でも、ContentProvierの部分はAndroid標準のAPIと互換性があるので上記の"content://com.android.calendar"のままでいけました。

Silent-BobSilent-Bob 2011/07/03 03:50 こんにちは。
カレンダーに予定を追加する機能を実装する際に参考にさせていただきました。
ありがとうございました。

一つお願いがあります。
HTC SenseやDesireでは"content://xxx"の箇所が独自で失敗しているようなのですが、
それに関する資料が見つからなく対策ができず、とても困っています。
もし、ご存知でしたら教えて頂けないでしょうか。

rmiyarmiya 2011/07/03 06:51 追記していなかったのですが、
HTC Desire、HTC EVO 4Gでも、"content://com.android.calendar"の設定でいけました。
"content://xxx"の部分は、HTC製の端末でも共通になっているのでContentProvider経由でのread/writeは互換性があります。

違うのは、HTC製の端末に搭載されたカレンダーアプリを起動する場合です。
この場合、HTCカレンダーアプリのパッケージ名を指定する必要があります。
see http://www.taosoftware.co.jp/blog/2010/04/htc_sense.html

Silent-BobSilent-Bob 2011/07/03 17:34 お忙しい中、迅速な返信、誠にありがとうございます。
"content://com.android.calendar"で問題無いとのことで安心いたしました。

現在、カレンダーのUri特定後、Myカレンダー一覧を取得する部分を実装中なのですが、
一覧をHTC Desireでは取得できないようでしたで、
URI周りに問題があるのかなと思い、質問させていただきました。

私はDesireを持っていないため利用者様からの見聞でしかないのですが、
http://d.hatena.ne.jp/Silent-Bob/20110703/1309679484
の最下部に記述したようなソースでは取得できませんでした。

rmiya様が対策をご存知でしたら、ご教授していただきたく思います。

rmiyarmiya 2011/07/08 00:47 Blogを拝見させていただきました。
気になったのが、"access_level=700"の指定です。
私の場合、"access_level>=500 AND sync_events=1"でカレンダー一覧を取得しています(この設定は、Android標準のカレンダーアプリのソースを参照にした筈)。

あと、HTC製端末のカレンダーContentProviderにはクセがあって、
デフォルト登録されるGoogleカレンダーは一覧に表示されますが、
ユーザーが後から追加したGoogleカレンダーは一覧に表示されない場合があります。
ので、HTC製の端末の標準カレンダーアプリのカレンダー一覧に対象のカレンダー名が表示されることを確認してみてはいかがでしょう。

なお、一覧に表示されないGoogleカレンダーがあった場合、Web上のGoogleカレンダーの設定画面から、表示されないカレンダーをエクスポート→カレンダーを削除→カレンダーを新規作成→カレンダーをインポートの手順でカレンダーの再作成を行った後、Android端末からカレンダーを同期すると表示される場合がありました。再現手順がちょっと曖昧なので参考までに。