スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

Android コンテントプロバイダ(ContentProvider)とライブフォルダの連携

<pre><code>コンテントプロバイダとライブフォルダの連携	
ライブフォルダとは、ユーザが簡単にコンテントプロバイダにアクセスできる機能です。
アプリケーションを介さず、直接データにアクセスすることが可能となります。
今回は、コンテントプロバイダのデータをライブフォルダで一覧表示し、詳細な情報をアクティビティで表示します。
ホーム画面を長押しすると以下のダイアログが表示されます。
image002.jpg

フォルダを選択すると配置可能なライブフォルダが一覧表示されます。
image004.jpg
選択したライブフォルダがホーム画面へ配置されます。
image006.jpg
ライブフォルダのアイコンをクリックすると、コンテントプロバイダからデータを取得し、画面へ表示します。<a href="http://egycolock.blog.fc2.com/img/20121107111442897.jpg/" target="_blank"><img src="http://blog-imgs-53.fc2.com/e/g/y/egycolock/20121107111442897.jpg" alt="image008 (1)" border="0" width="207" height="336" /></a>
※グリッド形式での表示
任意の1件を選択すると、詳細情報を出力するアクティビティが表示されます。
image010.jpg

独自のコンテントプロバイダをライブフォルダで利用するには以下の手順となります。
1.データを提供するコンテントプロバイダの構築
2.ホーム画面上で呼ばれるライブフォルダの作成
3.ライブフォルダから1件選択されたときの詳細情報を表示するアクティビティの作成
となります。
データを提供するコンテントプロバイダ
■データを公開する際のURI、データ構造などを定数ファイルとして構築します。
○ContentsManager定数用クラス

1: public class ContentsManager implements BaseColumns{ ①
2: //公開URI
3: public static final String AUTHORITY = "com.android.provider.Moogle";
4: public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/moogle"); ②
5: public static final Uri LIVE_FOLDER = Uri.parse("content://"+AUTHORITY+"/live_folders/moogle");
6: public static final String DATA1 = "data1";
7: public static final String DATA2 = "data2";
8:
9: }
10:

①BaseColumnsをインタフェースすることで、基本項目である「_id」「_count」が利用できます。
②URIの定義として「content://」をスキーマとします。今回はライブフォルダ用と二つ設定します。
■提供するデータを保持するSQLiteクラスを構築します。
○SampleDB

1: package sample.live.folder;
2:
3: import android.content.Context;
4: import android.da ase.sqlite.SQLiteDa ase;
5: import android.da ase.sqlite.SQLiteOpenHelper;
6:
7: public class SampleDB extends SQLiteOpenHelper {
8: private static final String DA ASE_NAME = "SAMPLE";
9: private static final int DA ASE_VERSION = 1;
10: public static final String LE_NAME = "SAMPLE";
11:
12: private static final String CREATE_SCHEDULE_ LE_SQL = "create le "
13: + LE_NAME + " (_id integer primary key autoincrement," //_idは自動採番
14: + " data1 text not null," + " data2 text not null,"
15: + " )";
16:
17: private static final String DROP_SCHEDULE_ LE_SQL = "drop le if exists SAMPLE";
18:
19: SampleDB(Context context) {
20: super(context, DA ASE_NAME, null, DA ASE_VERSION);
21: }
22:
23: @Override
24: public void onCreate(SQLiteDa ase db) {
25: db.execSQL(CREATE_SCHEDULE_ LE_SQL);
26: }
27:
28: @Override
29: public void onUpgrade(SQLiteDa ase db, int oldVersion, int newVersion) {
30: db.execSQL(DROP_SCHEDULE_ LE_SQL);
31: onCreate(db);
32: }
33:
34: }
35:

■データを提供するコンテントプロバイダクラスです。
○ContentsProviderコンテントプロバイダ実装クラス

1: public class ContentsProvider extends ContentProvider { ①
2: private static final int INSERT = 1;
3: private static final int DETAILS = 2;
4: private static final int LIVE_FOLDERS = 3;
5:
6: private static final UriMatcher URI_MATCHER;
7: private static HashMap<String, String> PROJECTION_MAP;
8: private static HashMap<String, String> LIVE_FOLDER_PROJECTION_MAP;
9: // DBHelper処理
10: private SampleDB dbHelper;
11: static {
12:
13: URI_MATCHER = new UriMatcher(UriMatcher.NO_MATCH); ②
14: URI_MATCHER.addURI(ContentsManager.AUTHORITY, "moogle", INSERT);
15: URI_MATCHER.addURI(ContentsManager.AUTHORITY, "moogle/#", DETAILS);
16: URI_MATCHER.addURI(ContentsManager.AUTHORITY, "live_folders/moogle",
17: LIVE_FOLDERS);
18:
19: PROJECTION_MAP = new HashMap<String, String>(); ③
20: PROJECTION_MAP.put(BaseColumns._ID, "_id");
21: PROJECTION_MAP.put(ContentsManager.DATA1, "data1");
22: PROJECTION_MAP.put(ContentsManager.DATA2, "data2");
23: LIVE_FOLDER_PROJECTION_MAP = new HashMap<String, String>();
24: LIVE_FOLDER_PROJECTION_MAP.put(BaseColumns._ID, "_id");
25: LIVE_FOLDER_PROJECTION_MAP.put(ContentsManager.DATA2, "data2 as name"); // 別名
26: }
27:
28: @Override
29: public boolean onCreate() {
30: Log.d("LiveTest", "ContentsProvider onCreate() ");
31:
32: dbHelper = new SampleDB(getContext());
33: return true;
34: }
35:
36: @Override
37: public Uri insert(Uri uri, ContentValues initialValues) {
38: Log.d("LiveTest", "ContentsProvider insert() " + uri.toString());
39: if (URI_MATCHER.match(uri) != INSERT) { ④
40: throw new IllegalArgumentException("Unknown URL *** " + uri);
41: }
42:
43: ContentValues values;
44: if (initialValues != null) {
45: values = new ContentValues(initialValues);
46: } else {
47: values = new ContentValues();
48: }
49:
50: SQLiteDa ase db = dbHelper.getWri leDa ase();
51:
52: long rowID = db.insert(SampleDB. LE_NAME, "NULL", values); //DBへのInsert処理
53: if (rowID > 0) {
54: Uri newUri = ContentUris.withAppendedId(
55: ContentsManager.CONTENT_URI, rowID); ⑤
56: getContext().getContentResolver().notifyChange(newUri, null);
57: return newUri;
58: }
59: throw new SQLException("Failed to insert row into " + uri);
60:
61: }
62:
63: @Override
64: public int delete(Uri uri, String where, String[] whereArgs) {
65: return 0;
66: }
67:
68: @Override
69: public int update(Uri uri, ContentValues values, String where,
70: String[] whereArgs) {
71: return 0;
72: }
73:
74: @Override
75: public Cursor query(Uri uri, String[] projection, String selection, ⑥
76: String[] selectionArgs, String sortOrder) {
77: Log.d("LiveTest", "ContentsProvider query() " + uri.toString());
78:
79: SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
80:
81: switch (URI_MATCHER.match(uri)) {
82:
83: case DETAILS:
84: Log.d("LiveTest", "ContentsProvider query() DETAILS");
85: qb.set les(SampleDB. LE_NAME);
86: qb.setProjectionMap(PROJECTION_MAP);
87: qb.appendWhere("_id=" + uri.getPathSegments().get(1));
88: break;
89: case LIVE_FOLDERS:
90: qb.set les(SampleDB. LE_NAME);
91: qb.setProjectionMap(LIVE_FOLDER_PROJECTION_MAP);
92: break;
93:
94: default:
95: throw new IllegalArgumentException("Unknown URL " + uri);
96: }
97: String orderBy;
98: if (TextUtils.isEmpty(sortOrder)) {
99: orderBy = "data1";
100: } else {
101: orderBy = sortOrder;
102: }
103:
104: SQLiteDa ase db = dbHelper.getReadableDa ase();
105: Cursor c = qb.query(db, projection, selection, selectionArgs, null,
106: null, orderBy);
107: c.setNotificationUri(getContext().getContentResolver(), uri);
108: return c;
109: }
110:
111: /**
112: * 返却するための新たな MIME タイプを定義する
113: */
114: @Override
115: public String getType(Uri uri) { ⑦
116: Log.d("LiveTest", "ContentsProvider getType() " + uri.toString());
117: switch (URI_MATCHER.match(uri)) {
118: case DETAILS:
119: return "vnd.android.cursor.item/vnd.moogle.data";
120: default:
121: throw new IllegalArgumentException("Unknown URL " + uri);
122: }
123: }
124:
125: }
126:

①ContentProviderを継承します
②UriMatcherを利用しURIを判断します。
第一引数:コンテントプロバイダの識別子
第二引数:種類を判断するためのコンテントプロバイダのパス
第三引数:URIが一致した際の戻り値
③DBのsetProjectionMapで利用するHashMapを生成します。setProjectionMapとは、抽出する列を別名で
取得することができる機能です。
今回使用するライブフォルダでは「name」カラムしか画面に出力できない仕様となっているため別名を設定します。
④insert処理では、URIがINSERTと一致する場合のみ実行できるようにします。
⑤戻り値として、行のIDを付加したURIを返します。
このURIを利用してバイナリデータを置くことができます。今回は利用しません。
⑥queryメソッドは、ContentResolver.query()、またはActivity.managedQuery()メソッドによって呼び出されます。
今回はライブフォルダへ表示する一覧データと、1件のデータ取得を行います。
呼び出されたのがライブフォルダか詳細かを判断するためにUriMatcherを利用します。
抽出するデータの内容はsetProjectionMapで変更します。
⑦独自のコンテントプロバイダクラスで扱う、MIMEタイプをgetTypeメソッドで定義します。
単一レコードを返すときは「vnd.android.cursor.item/vnd.あなたの会社名」
複数レコードを返すときは「vnd.android.cursor.dir/vnd.あなたの会社名」
となります。
今回は詳細を表示するさいの「単一レコード」のみ実装します。
■マニフェストファイルにコンテントプロバイダを記述します。

1: <application android:icon="@drawable/icon" android:label="@string/app_name">
2: ・・・省略・・・
3: <provider android:name="ContentsProvider" android:authorities="com.android.provider.Moogle" />
4: ・・・省略・・・
5: </application>
6:

ライブフォルダの構築
ライブフォルダを構築するたのアクティビティクラスを作成します。
○LiveFolderActivity

1: package sample.live.folder;
2:
3: import android.app.Activity;
4: import android.content.ContentValues;
5: import android.content.Intent;
6: import android.net.Uri;
7: import android.os.Bundle;
8: import android.provider.LiveFolders;
9: import android.util.Log;
10:
11: public class LiveFolderActivity extends Activity {
12: @Override
13: public void onCreate(Bundle savedInstanceState) {
14: super.onCreate(savedInstanceState);
15: Log.d("LiveTest", "LiveFolderActivity onCreate() ");
16:
17: // ProviderのInsertをCallするURIを設定 ①
18: Uri contentUri = ContentsManager.CONTENT_URI;
19:
20: ContentValues values = new ContentValues();
21: values.put(ContentsManager.DATA1, "D1");
22: values.put(ContentsManager.DATA2, "D2");
23: // ContentResolverを介してアクセスする
24: Uri uri = getContentResolver().insert(contentUri, values); ②
25: values.clear();
26: values.put(ContentsManager.DATA1, "D3");
27: values.put(ContentsManager.DATA2, "D4");
28: uri = getContentResolver().insert(contentUri, values);
29:
30: final Intent intent = getIntent();
31: if (intent != null) {
32: final String action = intent.getAction(); ③
33: if (LiveFolders.ACTION_CREATE_LIVE_FOLDER.equals(action)) {
34: Log.d("LiveTest",
35: LiveFolderActivity ACTION_CREATE_LIVE_FOLDER );
36:
37: Intent i = new Intent();
38: i.setData(ContentsManager.LIVE_FOLDER); ④
39: i.putExtra(LiveFolders.EXTRA_LIVE_FOLDER_BASE_INTENT, ⑤
40: new Intent(Intent.ACTION_VIEW,
41: ContentsManager.CONTENT_URI));
42: i.putExtra(LiveFolders.EXTRA_LIVE_FOLDER_DISPLAY_MODE,
43: LiveFolders.DISPLAY_MODE_GRID); ⑥
44: i.putExtra(LiveFolders.EXTRA_LIVE_FOLDER_NAME, "moogleフォルダ");
45: i.putExtra(LiveFolders.EXTRA_LIVE_FOLDER_ICON, ⑦
46: Intent.ShortcutIconResource.fromContext(this,
47: R.drawable.icon));
48: setResult(RESULT_OK, i);
49: } else {
50: setResult(RESULT_CANCELED);
51: }
52: }
53: finish();
54: }
55: }
56:

①今回はテストのため、ライブフォルダ実行時にデータの登録を行います。
データInsert用のURIを取得します。
②プロバイダにはContentResolverを介してアクセスします。
③Intentからアクションを取得し、CREATE_LIVE_FOLDERの場合のみ後続処理を行います。
④setDataにライブフォルダ用のURIを設定します。
⑤EXTRA_LIVE_FOLDER_BASE_INTENTとは、ライブフォルダ一覧から選択されたときに実行される処理です。
今回は、Intentを介してACTION_VIEWに対応するアクティビティを呼び出します。
また、呼び出す際はコンテントプロバイダのgetTypeメソッドが実行されます。受け取るURIには選択したレコードIDが
付加されたURIが引数として渡されます。
そのため、getTypeメソッドではURIMatcherの結果Detailsと判断し、単一レコード用のMIMEタイプを返します。
⑥ライブフォルダの表示形式を設定します。
リスト形式:LiveFolders.DISPLAY_MODE_LIST
グリッド形式:LiveFolders.DISPLAY_MODE_GRID
⑦ライブフォルダのアイコン、名称を設定します。
■ライブフォルダをホームに表示するため、マニフェストファイルに以下を追記します
○マニフェストファイル追記

1: <application android:icon="@drawable/icon" android:label="@string/app_name">
2: ・・・省略・・・
3:
4: <activity android:name=".LiveFolderActivity" android:label="テストProvider">
5: <intent-filter>
6: <action android:name="android.intent.action.CREATE_LIVE_FOLDER" /> ①
7: <category android:name="android.intent.category.DEFAULT" />
8: </intent-filter>
9: </activity>
10:
11: ・・・省略・・・
12: </application>

①actionに「android.intent.action.CREATE_LIVE_FOLDER」を定義したアクティビティは
配置可能なライブフォルダ一覧へ表示されます。
ライブフォルダ一覧からレコード選択時に呼び出されるアクティビティ
ライブフォルダ一覧から任意のレコードが選択されたときに、詳細情報を表示するアクティビティです
1: package sample.live.folder;
2:
3: import android.app.Activity;
4: import android.da ase.Cursor;
5: import android.net.Uri;
6: import android.os.Bundle;
7: import android.util.Log;
8: import android.widget.TextView;
9:
10: public class DetailsActivity extends Activity {
11: @Override
12: public void onCreate(Bundle savedInstanceState) {
13: super.onCreate(savedInstanceState);
14: Log.d("LiveTest", "DetailsActivity onCreate() ");
15:
16: Uri uri = getIntent().getData(); ①
17: Cursor cursor = managedQuery(uri, null, null, null, null); ②
18: cursor.moveToFirst();
19: TextView tv = new TextView(this);
20: tv.setText("データ1="+ cursor.getString(cursor.getColumnIndex(ContentsManager.DATA1))
21: + " データ2="+ cursor.getString(cursor.getColumnIndex(ContentsManager.DATA2)));
22: setContentView(tv);
23: }
24: }
25:
①アクティビティが呼ばれた際のURIを取得します。
ここで取得されるURIは選択したレコードIDが付加されたURIとなります。
②取得したURIでコンテントプロバイダを呼び出します。呼び出されるqueryメソッドでは
レコードIDが付加されたURIため、URIMatcherではDetailsと判断をします。
■マニフェストファイルの追加
詳細情報を表示するDetailsActivityクラスは、ライブフォルダの一覧から任意のレコードを選択されたときに
呼ばれなければいけません。
以下の内容で呼び出されます。
action:android.intent.action.VIEW
mimeType:vnd.android.cursor.item/vnd.moogle.data
そのため、以下のようにintent-filterを設定します。。
○マニフェストファイル
1: <application android:icon="@drawable/icon" android:label="@string/app_name">
2:
3: ・・・省略・・・
4: <activity android:name=".DetailsActivity">
5: <intent-filter>
6: <action android:name="android.intent.action.VIEW" />
7: <category android:name="android.intent.category.DEFAULT" />
8: <data android:mimeType="vnd.android.cursor.item/vnd.moogle.data" />
9: </intent-filter>
10: </activity>
11: </application>
</code></pre>
スポンサーサイト

テーマ : android
ジャンル : コンピュータ

コメントの投稿

非公開コメント

おすすめアプリ
カテゴリ
最新記事
リンク
アクセスカウンター
アクセス解析
imobile
i-mobile
i-mobile
i-mobile
i-mobile
i-mobile
検索フォーム
RSSリンクの表示
リンク
ブロとも申請フォーム

この人とブロともになる

QRコード
QR
Amazon
Androidお勧め参考書
EC studio
商品
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。