【android学習の十一】——データストレージ3:データ共有ContentProvider,ContentResolver
11676 ワード
声明:学習した書籍「Androidアプリケーション開発の秘密」は、この書籍を学習したログを記録し、引用した関連コードと総括説明は、商業的な用途がなく、完全に自己学習の記録であり、学習したばかりでは多くの問題が避けられないが、間違いがあれば批判してください.
三、データストレージ3:データ共有ContentProvider,ContentResolver
このブログを補足して、前に勉強してずっと整理したいと思っていましたが、どうやって手をつけるか分かりません.この内容は前のweb開発の考え方と一定の違いがあるので、自分では少し1週間遅れてこのブログを補充しました.
前述したように、各プログラムはスレッド制御であり、データは共有できないが、ContentProviderはこの問題を解決し、ContentProviderはすべてのアプリケーション間のデータ格納と検索の橋渡しであり、各プログラム間でデータ共有を実現する役割を果たす.
ContentProviderは抽象クラスであり、このクラスから継承するにはgetType,insert,delete,update,queryメソッドを実装しなければならないため、上記のインタフェースを提供してデータを取得し、操作する必要があります.
私たちがWeb開発を学んでModel 1のMVCに触れたばかりの頃のように、データ層側はエンティティに対する添削を実現したが、ビジネス層側ではデータ操作のサービスをカプセル化したほうがいい.そうすれば、ビジネス層がデータ層を直接操作することを避け、この仕事を対応するサービスの実現に任せ、より良い管理を行うことができる.ここでContentResolverが引き出され,その役割はサービスの実装に対応してContentProviderを操作することと理解できる.
ContentResolverオブジェクトの取得はgetContentResolver()メソッドで取得できます
ここで説明する必要があるのは、各ContentProviderは外部に共通のURI(Uriオブジェクトにパッケージされている)を提供し、アプリケーションにデータを共有する必要がある場合はContentProviderを使用してこれらのデータに対してURIを定義する必要があり、他のアプリケーションはContentProviderを通じてこのURIに転送してデータを操作することができる.URIは、「content://」、データの経路、表示IDの3つの部分で構成されています(オプション).次のようになります.
content://media/internal/imagesこのURIはデバイスに格納されているすべてのピクチャを返す
content://contacts/people/5連絡先情報のIDが5の連絡先レコード
content://contacts:/people/このURIはデバイス上のすべての連絡先情報を返す.
もちろんproviderパッケージの下には、次のような補助クラスも用意されています.
ここでは個人的にはOSGIにおけるSeriviceの登録に似ていると思いますが、現在のシステムが提供しているサービス(ここでは共有データ)をId(ここではURI)と表示し、Idで対応するサービスを取得して操作します.ContentResolverはURIをそのパラメータとして使用し、そのContentResolverがどのContentProviderを操作しているかを示す.
上の行のコードがContentResolverがNotesに対応するURIを操作した場合、後のパラメータvaluesがデータ値になります.
【拡張学習】:自分でContentproviderを作成し、データ型が現在存在しない場合は、自分の戻り列を定義するとともに、対応する新しいMIMEタイプを定義する必要があります.現在共有データにないタイプは構成と定義が必要で、そうでないと認識できません.
ここでは、SDKが書き換えたインスタンスNotesを使用してテストを行います.上記のすべてのMIMEタイプと戻り列の定義はNotePadクラスにあります.
同時に対応するAndroidManifest.xmlファイルでproviderを構成する必要があります
NotePadProviderクラス:
最終アクションのActivityクラスは次のとおりです.
もちろんActivityクラスに対応するには、プロファイルに登録する必要があります.
このようなインスタンスの実行効果:
対応するバックグラウンド・データベースの内容:
ここまでで今回のデータ共有の整理を完了します.
三、データストレージ3:データ共有ContentProvider,ContentResolver
このブログを補足して、前に勉強してずっと整理したいと思っていましたが、どうやって手をつけるか分かりません.この内容は前のweb開発の考え方と一定の違いがあるので、自分では少し1週間遅れてこのブログを補充しました.
前述したように、各プログラムはスレッド制御であり、データは共有できないが、ContentProviderはこの問題を解決し、ContentProviderはすべてのアプリケーション間のデータ格納と検索の橋渡しであり、各プログラム間でデータ共有を実現する役割を果たす.
ContentProviderは抽象クラスであり、このクラスから継承するにはgetType,insert,delete,update,queryメソッドを実装しなければならないため、上記のインタフェースを提供してデータを取得し、操作する必要があります.
私たちがWeb開発を学んでModel 1のMVCに触れたばかりの頃のように、データ層側はエンティティに対する添削を実現したが、ビジネス層側ではデータ操作のサービスをカプセル化したほうがいい.そうすれば、ビジネス層がデータ層を直接操作することを避け、この仕事を対応するサービスの実現に任せ、より良い管理を行うことができる.ここでContentResolverが引き出され,その役割はサービスの実装に対応してContentProviderを操作することと理解できる.
ContentResolverオブジェクトの取得はgetContentResolver()メソッドで取得できます
ここで説明する必要があるのは、各ContentProviderは外部に共通のURI(Uriオブジェクトにパッケージされている)を提供し、アプリケーションにデータを共有する必要がある場合はContentProviderを使用してこれらのデータに対してURIを定義する必要があり、他のアプリケーションはContentProviderを通じてこのURIに転送してデータを操作することができる.URIは、「content://」、データの経路、表示IDの3つの部分で構成されています(オプション).次のようになります.
content://media/internal/imagesこのURIはデバイスに格納されているすべてのピクチャを返す
content://contacts/people/5連絡先情報のIDが5の連絡先レコード
content://contacts:/people/このURIはデバイス上のすべての連絡先情報を返す.
もちろんproviderパッケージの下には、次のような補助クラスも用意されています.
Uri person = ContentUris.withAppendedId(People.CONTENT_URI , 5);
ここでは個人的にはOSGIにおけるSeriviceの登録に似ていると思いますが、現在のシステムが提供しているサービス(ここでは共有データ)をId(ここではURI)と表示し、Idで対応するサービスを取得して操作します.ContentResolverはURIをそのパラメータとして使用し、そのContentResolverがどのContentProviderを操作しているかを示す.
getContentResolver().insert(NotePad.Notes.CONTENT_URI, values);
上の行のコードがContentResolverがNotesに対応するURIを操作した場合、後のパラメータvaluesがデータ値になります.
【拡張学習】:自分でContentproviderを作成し、データ型が現在存在しない場合は、自分の戻り列を定義するとともに、対応する新しいMIMEタイプを定義する必要があります.現在共有データにないタイプは構成と定義が必要で、そうでないと認識できません.
ここでは、SDKが書き換えたインスタンスNotesを使用してテストを行います.上記のすべてのMIMEタイプと戻り列の定義はNotePadクラスにあります.
public class NotePad {
public static final String AUTHORITY = "com.google.provider.NotePad"; //ContentProvider uri
public NotePad(){}
//
public static final class Notes implements BaseColumns{
public Notes(){}
public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/notes");
// MIME -
public static final String CONTENT_TYPE = "vnd.android.cursor.dir/vnd.google.note";
// MIME -
public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/vnd.google.note";
public static final String DEFAULT_SORT_ORDER = "modified DESC";
//
public static final String TITLE = "title";
public static final String NOTE = "note";
public static final String CREATEDDATE = "created";
public static final String MODIFIEDDATE = "modified";
}
}
同時に対応するAndroidManifest.xmlファイルでproviderを構成する必要があります
NotePadProviderクラス:
public class NotePadProvider extends ContentProvider{
private static final String TAG = "NotePadProvider";
//
private static final String DATABASE_NAME = "note_pad.db";
private static final int DATABASE_VERSION = 2;
//
private static final String NOTES_TABLE_NAME = "notes";
private static HashMap sNotesProjectionMap;
private static final int NOTES = 1;
private static final int NOTE_ID = 2;
private static final UriMatcher sUriMatcher;
private DatabaseHelper mOpenHelper;
// SQL
private static final String CREATE_TABLE="CREATE TABLE "
+ NOTES_TABLE_NAME
+ " (" + Notes._ID
+ " INTEGER PRIMARY KEY,"
+ Notes.TITLE
+ " TEXT,"
+ Notes.NOTE
+ " TEXT,"
+ Notes.CREATEDDATE
+ " INTEGER,"
+ Notes.MODIFIEDDATE
+ " INTEGER" + ");";
static{
sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
sUriMatcher.addURI(NotePad.AUTHORITY, "notes", NOTES);
sUriMatcher.addURI(NotePad.AUTHORITY, "notes/#", NOTE_ID);
sNotesProjectionMap = new HashMap();
sNotesProjectionMap.put(Notes._ID, Notes._ID);
sNotesProjectionMap.put(Notes.TITLE, Notes.TITLE);
sNotesProjectionMap.put(Notes.NOTE, Notes.NOTE);
sNotesProjectionMap.put(Notes.CREATEDDATE, Notes.CREATEDDATE);
sNotesProjectionMap.put(Notes.MODIFIEDDATE, Notes.MODIFIEDDATE);
}
private static class DatabaseHelper extends SQLiteOpenHelper{
// -
DatabaseHelper(Context context){
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
//
@Override
public void onCreate(SQLiteDatabase db){
db.execSQL(CREATE_TABLE);
}
//
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion){
db.execSQL("DROP TABLE IF EXISTS notes");
onCreate(db);
}
}
@Override
public boolean onCreate(){
mOpenHelper = new DatabaseHelper(getContext());
return true;
}
@Override
//
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder){
SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
switch (sUriMatcher.match(uri)){
case NOTES:
qb.setTables(NOTES_TABLE_NAME);
qb.setProjectionMap(sNotesProjectionMap);
break;
case NOTE_ID:
qb.setTables(NOTES_TABLE_NAME);
qb.setProjectionMap(sNotesProjectionMap);
qb.appendWhere(Notes._ID + "=" + uri.getPathSegments().get(1));
break;
default:
throw new IllegalArgumentException("Unknown URI " + uri);
}
String orderBy;
if (TextUtils.isEmpty(sortOrder)){
orderBy = NotePad.Notes.DEFAULT_SORT_ORDER;
}else{
orderBy = sortOrder;
}
SQLiteDatabase db = mOpenHelper.getReadableDatabase();
Cursor c = qb.query(db, projection, selection, selectionArgs, null, null, orderBy);
c.setNotificationUri(getContext().getContentResolver(), uri);
return c;
}
@Override
// ,
public String getType(Uri uri){
switch (sUriMatcher.match(uri)){
case NOTES:
return Notes.CONTENT_TYPE;
case NOTE_ID:
return Notes.CONTENT_ITEM_TYPE;
default:
throw new IllegalArgumentException("Unknown URI " + uri);
}
}
@Override
//
public Uri insert(Uri uri, ContentValues initialValues){
if (sUriMatcher.match(uri) != NOTES){
throw new IllegalArgumentException("Unknown URI " + uri);
}
ContentValues values;
if (initialValues != null){
values = new ContentValues(initialValues);
}else{
values = new ContentValues();
}
Long now = Long.valueOf(System.currentTimeMillis());
if (values.containsKey(NotePad.Notes.CREATEDDATE) == false){
values.put(NotePad.Notes.CREATEDDATE, now);
}
if (values.containsKey(NotePad.Notes.MODIFIEDDATE) == false){
values.put(NotePad.Notes.MODIFIEDDATE, now);
}
if (values.containsKey(NotePad.Notes.TITLE) == false){
Resources r = Resources.getSystem();
values.put(NotePad.Notes.TITLE, r.getString(android.R.string.untitled));
}
if (values.containsKey(NotePad.Notes.NOTE) == false){
values.put(NotePad.Notes.NOTE, "");
}
SQLiteDatabase db = mOpenHelper.getWritableDatabase();
long rowId = db.insert(NOTES_TABLE_NAME, Notes.NOTE, values);
if (rowId > 0){
Uri noteUri = ContentUris.withAppendedId(NotePad.Notes.CONTENT_URI, rowId);
getContext().getContentResolver().notifyChange(noteUri, null);
return noteUri;
}
throw new SQLException("Failed to insert row into " + uri);
}
@Override
//
public int delete(Uri uri, String where, String[] whereArgs){
SQLiteDatabase db = mOpenHelper.getWritableDatabase();
int count;
switch (sUriMatcher.match(uri)){
case NOTES:
count = db.delete(NOTES_TABLE_NAME, where, whereArgs);
break;
case NOTE_ID:
String noteId = uri.getPathSegments().get(1);
count = db.delete(NOTES_TABLE_NAME, Notes._ID + "=" + noteId + (!TextUtils.isEmpty(where) ? " AND (" + where + ')' : ""), whereArgs);
break;
default:
throw new IllegalArgumentException("Unknown URI " + uri);
}
getContext().getContentResolver().notifyChange(uri, null);
return count;
}
@Override
//
public int update(Uri uri, ContentValues values, String where, String[] whereArgs){
SQLiteDatabase db = mOpenHelper.getWritableDatabase();
int count;
switch (sUriMatcher.match(uri)){
case NOTES:
count = db.update(NOTES_TABLE_NAME, values, where, whereArgs);
break;
case NOTE_ID:
String noteId = uri.getPathSegments().get(1);
count = db.update(NOTES_TABLE_NAME, values, Notes._ID + "=" + noteId + (!TextUtils.isEmpty(where) ? " AND (" + where + ')' : ""), whereArgs);
break;
default:
throw new IllegalArgumentException("Unknown URI " + uri);
}
getContext().getContentResolver().notifyChange(uri, null);
return count;
}
}
最終アクションのActivityクラスは次のとおりです.
public class DataProviderActivity extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
//
ContentValues values = new ContentValues();
values.put(NotePad.Notes.TITLE, "title1");
values.put(NotePad.Notes.NOTE, "NoteNote1");
getContentResolver().insert(NotePad.Notes.CONTENT_URI, values);
values.clear();
values.put(NotePad.Notes.TITLE, "title2");
values.put(NotePad.Notes.NOTE, "NoteNote2");
getContentResolver().insert(NotePad.Notes.CONTENT_URI, values);
/* */
displayNote();
}
private void displayNote() {
// TODO Auto-generated method stub
String columns[] = new String[]{
NotePad.Notes._ID,
NotePad.Notes.TITLE,
NotePad.Notes.NOTE,
NotePad.Notes.CREATEDDATE,
NotePad.Notes.MODIFIEDDATE
};
Uri myUri = NotePad.Notes.CONTENT_URI;
Cursor cursor = this.managedQuery(myUri, columns, null, null, null);
if (cursor.moveToFirst()) {
String id = null;
String title = null;
do{
id = cursor.getString(cursor.getColumnIndex(NotePad.Notes._ID));
title = cursor.getString(cursor.getColumnIndex(NotePad.Notes.TITLE));
Toast toast=Toast.makeText(this, "TITLE:"+id + "NOTE:" + title, Toast.LENGTH_LONG);
toast.setGravity(Gravity.TOP|Gravity.CENTER, 0, 40);
toast.show();
}while(cursor.moveToNext());
}
}
}
もちろんActivityクラスに対応するには、プロファイルに登録する必要があります.
このようなインスタンスの実行効果:
対応するバックグラウンド・データベースの内容:
ここまでで今回のデータ共有の整理を完了します.