ContentProviderの扱いについて

843 views
Skip to first unread message

nemui

unread,
Jul 18, 2011, 7:24:09 AM7/18/11
to Android-SDK-Japan
お世話になります。nemuiといいます。

ContentProviderの扱いについて、皆さまの考えや手法を聞かせてもらえればと思います。

Calendarと連携をとるアプリを考えています。
ContentProvider(=CalendarProvider)によるinsertは出来ます。
しかし、自分が挿入したデータか否かをどのように識別するか、これが解らないでいます。
ContentProviderを利用した場合に編集削除を反映させる作法というか、ベストプラクティスは
どういうものでしょうか。

当初自アプリで_IDを控えておけばと考えましたが、よく考えればこれ、テーブル上で一意なだけで、
システムとしてみると一意になることが保障されているようには見えません。
# 特にGoogleカレンダーは一定の期間分しかデバイスに持ちませんし。
そもそもsqlite3のAUTOINCREMENTって取得時点で存在しなければ以前採番した番号を再度採番しますし・・・

ContentObserverを登録しておけば、先方での変更も追えますので、再採番も通知を受け取れそうに思えますが、
プロセスが落ちていると通知が受け取れない。サービス化という手段もありますが、そこまでしないと連携はとれない?

挿入側で一意になる何かを生成して埋め込んでおく手もありますが、適した列を持つものに限られます。
CalendarProviderでいえば無さそうに見えます。ExtendedPropertiesなら突っ込んでもいいのかな?


確かにカレンダーにデータを作れるだけで、後は知らないというアプリは見かけますけど・・・
そんなものなんですか。

Ryosuke Matsuuchi

unread,
Jul 18, 2011, 11:32:11 PM7/18/11
to android-...@googlegroups.com
nemui様

こんにちは。 松内です。


■「自分が挿入するデータ」の判別について

nemui様の「自分が挿入するデータ」が、 Gmail などの既存アプリと
同一の種類の連絡先データなのか、あるいは独自に作成されたアプリが
提供する独自の連絡先データなのか、によってアプローチが変わって
くると思います。


(a) Gmailなど既存の Account type (すでに提供されている ContentProvider)
に対して挿入する場合

すでに存在する Account type のデータに対して何らかのマーキングを
行うには、(うまくいくかどうか未確認ですが)
Dataテーブルの DATA1 ... DATA15 カラムのうち まだ使われていないカラムに
値を書き込んでおき、後でそのカラムの値を取り出して判定する、という
方法が使えるかもしれません。 それ以外の方法としては、挿入対象が
Gmail アカウントであることが事前にわかっているような場合には、
_ID の代わりに email アドレスを ID として用いて どこか別の場所にデータを
格納する、という方法も考えられますね。 使っている端末の中だけで
一意であればよい、というような場合には、普通に _ID を使っても
問題ないケースも多そうです。  あるいは、ユーザーに見えてしまうので
ちょっと汚いですが、「メモ」欄に特定の文字列を埋め込んでしまう
というのも用途によってはアリかもしれませんね。


(b) 自分が作成するアプリで 独自形式の連絡先データを管理し、それが
標準の Contacts リストにも表示されるようにしたい場合

Android 2.0 以降では、 SyncAdapter (正確には AbstractThreadedSyncAdapter)
という API を利用することで、 自分のアプリで新しい Account type を提供
することができます (例: Facebook アプリを Android 端末にインストールする
と、通常の Google アカウントに加えてFacebook アカウントとの連絡先の同期も
できるようになりますが、この機能は SyncAdapter API を利用して提供されています)。

この方法が nemui 様のアプリで使えそうな場合には、下記のようなサンプルを
参考にしていただくとよいかと思います。

  Android SDK - SampleSyncAdapter
  http://developer.android.com/resources/samples/SampleSyncAdapter/index.html
  ↑新しい Account type を定義して同期機能を提供する実装例

また、一般に ContentProvider を用いて データ同期を設計するときに
考慮しておくべき設計パターンについて、 2010年の Google I/O プレゼンテー
ションで弊社の Virgil Dobjanschi がいくつか紹介していますので、
こちらもご参考にしていただけましたら幸いです。


■データの同期について
 
ContentObserver はもともと、「データに何らかの変更が起こった →
ListView的な UI を更新する」というシナリオを想定して提供されて
いる API です。  UIの更新のときは、画面に表示されている部分を
再度 (ループで) 取得する、という使い方を想定していて、「どのレ
コードがどのように変更/追加/削除されたか」という情報を提供す
る機能はContentObserver にはありません。 

ですので、たとえば 連絡先データの全体を同期して、 端末でアクセスできる
すべての連絡先情報のコピーをごっそり作る、というようなプログラムを
書くのは現状では(とくに連絡先リストが大規模になってきたら)困難
だと思います。 

とはいえ、連絡先データについては 上記 SyncAdapter のような仕組みを
用いて拡張性を提供していますので、これらを組み合わせてご利用いただ
くことで「まるごとコピー・まるごと同期」の必要性はそもそもないの
ではないか、というのが現在の想定です。


若干ランダムですが、ひとまずざっと思いつくのは上記のような点になります。
ご参考にしていただけそうでしょうか?
もう少し 詳しく議論/検証/補足したほうがよさそうな点などありましたら ご指摘ください。


- Ryosuke Matsuuchi 松内 良介 | Developer Advocate | Google


2011/7/18 nemui <ne.n...@gmail.com>

--
このメールは Google グループのグループ「Android-SDK-Japan」の登録者に送られています。
このグループに投稿するには、android-...@googlegroups.com にメールを送信してください。
このグループから退会するには、android-sdk-ja...@googlegroups.com にメールを送信してください。
詳細については、http://groups.google.com/group/android-sdk-japan?hl=ja からこのグループにアクセスしてください。


Keiji Ariyama

unread,
Jul 19, 2011, 1:43:42 AM7/19/11
to android-...@googlegroups.com
nemuiさん

 有山と申します。

> しかし、自分が挿入したデータか否かをどのように識別するか、これが解らな
いでいます。

松内さんのContactsの例に近いのですが、CalendarProvider2のソースを見た限
り、僕自身は、ExtendedPropertiesに含めるのが妥当と考えています。

 携帯端末は、ネットへの接続が保証されないので、採番の関係で常に同期して
いなければ整合性がとれない構成より、素直に特殊なフィールドを用意した方が
良いかと。。。

--
Keiji,
ml_an...@c-lis.co.jp

nemui

unread,
Jul 19, 2011, 3:20:18 PM7/19/11
to Android-SDK-Japan
松内様、有山様、返信ありがとうございます。

挿入側で一意になる何かを生成して埋め込んでおき、それで識別するのが現実的ですか。

そもそもの要求は自アプリから作成したカレンダーのイベントに対して編集・削除も反映させたいというものです。
松内様の(a)の考えです。
ところで、端末内だけでも
1. アプリAがContentProvider経由でデータ作成
2. アプリBが先のデータを削除
3. 続けてContentProvider経由でデータ作成
と処理すると、IDは同じだが別インスタンスのデータとなるので、_IDで済むパターンはないと思いますが。
同期云々はあまり関係ないなというのが私の認識です。
同期すれば_sync_idが付くのでそれが利用できるということですかね?

埋め込むとしてどの列を利用するかですね。
私の場合、個人的なアプリなので割り切りは簡単ですが、一般向けだと難しい問題に思えます。

ExtendedPropertiesの件、私もCalendarProvider2のソースコードを見て使ってよさそうに思いましたが、
これ、そもそも何のために用意されているのか解らず、ふんぎりがつきませんでした。
CalendarProviderに限るとドキュメント無状態ですし、SDKに含まれていない現状は何とかしてほしいと思います。

Keiji Ariyama

unread,
Jul 20, 2011, 3:15:52 AM7/20/11
to android-...@googlegroups.com
nemuiさん

 有山です。

> 挿入側で一意になる何かを生成して埋め込んでおき、それで識別するのが現実
的ですか。
 あ、誤解を与えてしまったようで申し訳ないです。
 一意になる何かを生成して埋め込むのではなくて、「アプリAで追加したデー
タである」と判定できるフラグ(true, false or String)のようなものを埋め込
むと言うイメージで話をしてました。

 Googleカレンダーの例であれば、各スケジュールごとに一意なIDのようなもの
がサーバーによって付けられる。それを使うと言うイメージです。

 独自のContentProvidersで、データを管理するサーバーと連携するという前提
であれば、サーバーに接続するアプリをインストールした端末が複数存在した場
合には、一意性の保証は、サーバー側でしか出来ないと考えているためです。

 宜しくお願いいたします。

--
Keiji,
ml_an...@c-lis.co.jp

nemui

unread,
Jul 20, 2011, 10:47:17 AM7/20/11
to Android-SDK-Japan
有山様。

それだと「アプリAで追加したデータである」が判別できても、
「アプリAのどのデータと紐付くか」が判別できなくないですか。
アプリAが一つしかデータを持たないのであればそれでもよいと思いますが。

ともかく、自前で識別する何かを実装しないといけないのは解りました。

サーバに更新されると_sync_idが付くので一意なんでしょうけどね。
端末側だけでは難しいですよね。厳密に考えだすと、複数端末対応だとか、
java.util.UUIDだとGUIDにならないとか。
割り切るのをどこにするかという問題でにあるのかな。
Reply all
Reply to author
Forward
0 new messages