Android
ContentProvider
サーチ…
備考
コンテンツプロバイダは、構造化されたデータセットへのアクセスを管理します。それらはデータをカプセル化し、データセキュリティを定義するためのメカニズムを提供します。コンテンツプロバイダは、あるプロセスのデータを別のプロセスで実行されているコードと接続する標準インタフェースです。
コンテンツプロバイダのデータにアクセスするには、アプリケーションのContext
でContentResolver
オブジェクトを使用して、プロバイダとしてクライアントとして通信します。 ContentResolver
オブジェクトは、 ContentProvider
を実装するクラスのインスタンスであるプロバイダオブジェクトと通信します。プロバイダオブジェクトは、クライアントからのデータ要求を受け取り、要求された処理を実行し、結果を返します。
他のアプリケーションとデータを共有しない場合は、独自のプロバイダを開発する必要はありません。ただし、独自のアプリケーションでカスタム検索提案を提供するには、独自のプロバイダが必要です。複雑なデータやファイルをアプリケーションから他のアプリケーションにコピーして貼り付ける場合は、独自のプロバイダも必要です。
Android自体には、オーディオ、ビデオ、画像、個人の連絡先情報などのデータを管理するコンテンツプロバイダが含まれています。いくつかはandroid.provider
パッケージのリファレンスドキュメントに記載されています。いくつかの制限があり、これらのプロバイダにはどのAndroidアプリケーションからでもアクセスできます。
基本的なコンテンツプロバイダクラスの実装
1)契約クラスを作成する
コントラクトクラスは、アプリケーションがコンテンツURI、列名、インテントアクション、およびコンテンツプロバイダのその他の機能を操作するのに役立つ定数を定義します。契約クラスはプロバイダに自動的には含まれません。プロバイダの開発者はそれらを定義し、他の開発者が利用できるようにする必要があります。
プロバイダには通常、1つの権限があり、Androidの内部名として機能します。他のプロバイダとの競合を避けるために、一意のコンテンツ権限を使用してください。この推奨事項はAndroidパッケージ名にも当てはまるため、プロバイダ権限を、プロバイダを含むパッケージ名の拡張子として定義することができます。たとえば、Androidパッケージ名がcom.example.appname
場合、プロバイダにcom.example.appname.provider
という権限を与える必要があります。
public class MyContract {
public static final String CONTENT_AUTHORITY = "com.example.myApp";
public static final String PATH_DATATABLE = "dataTable";
public static final String TABLE_NAME = "dataTable";
}
コンテンツURIは、プロバイダ内のデータを識別するURIです。コンテンツURIには、プロバイダ全体(その権限)の記号名と、テーブルまたはファイル(パス)を指す名前が含まれます。オプションのid部分は、テーブル内の個々の行を指します。 ContentProviderのすべてのデータアクセスメソッドは、引数としてコンテンツURIを持ちます。これにより、アクセスするテーブル、行、またはファイルを決定することができます。契約クラスでこれらを定義します。
public static final Uri BASE_CONTENT_URI = Uri.parse("content://" + CONTENT_AUTHORITY);
public static final Uri CONTENT_URI = BASE_CONTENT_URI.buildUpon().appendPath(PATH_DATATABLE).build();
// define all columns of table and common functions required
2)ヘルパークラスを作成する
ヘルパークラスは、データベースの作成とバージョン管理を管理します。
public class DatabaseHelper extends SQLiteOpenHelper {
// Increment the version when there is a change in the structure of database
public static final int DATABASE_VERSION = 1;
// The name of the database in the filesystem, you can choose this to be anything
public static final String DATABASE_NAME = "weather.db";
public DatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
// Called when the database is created for the first time. This is where the
// creation of tables and the initial population of the tables should happen.
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// Called when the database needs to be upgraded. The implementation
// should use this method to drop tables, add tables, or do anything else it
// needs to upgrade to the new schema version.
}
}
3)ContentProviderクラスを継承するクラスを作成する
public class MyProvider extends ContentProvider {
public DatabaseHelper dbHelper;
public static final UriMatcher matcher = buildUriMatcher();
public static final int DATA_TABLE = 100;
public static final int DATA_TABLE_DATE = 101;
UriMatcherは、権限とパスを整数値にマップします。 match()
メソッドは、URIのユニークな整数値を返しますmatch()
ユニークであれば、任意の数を指定できます)。 switchステートメントは、テーブル全体を照会するか、単一のレコードを照会するかを選択します。私たちのUriMatcherは、URIがTableのContent URIであれば100を返し、URIがそのテーブル内の特定の行を指す場合には101を返します。 #
ワイルドカードを使用して任意の数字と*
に一致させ、任意の文字列に一致させることができます。
public static UriMatcher buildUriMatcher() {
UriMatcher uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
uriMatcher.addURI(CONTENT_AUTHORITY, MyContract.PATH_DATATABLE, DATA_TABLE);
uriMatcher.addURI(CONTENT_AUTHORITY, MyContract.PATH_DATATABLE + "/#", DATA_TABLE_DATE);
return uriMatcher;
}
重要: addURI()
呼び出しは重要です! UriMatcherは最初に追加されたものから最後に追加されたものまで順次に表示されます。 #
や*
ようなワイルドカードは欲張りなので、あなたがあなたのURIを正しく注文したことを確認する必要があります。例えば:
uriMatcher.addURI(CONTENT_AUTHORITY, "/example", 1);
uriMatcher.addURI(CONTENT_AUTHORITY, "/*", 2);
マッチャーは/*
マッチに頼る前に最初に/example
を探しますので、適切な順序です。これらのメソッド呼び出しが逆転し、 uriMatcher.match("/example")
呼び出すと、UriMatcherは/*
パスに出会って間違った結果を返すとマッチを探すのを止めます!
これらの関数をオーバーライドする必要があります:
onCreate() :プロバイダを初期化します。 Androidシステムは、プロバイダを作成した直後にこのメソッドを呼び出します。 ContentResolverオブジェクトがプロバイダにアクセスしようとするまで、プロバイダは作成されません。
@Override
public boolean onCreate() {
dbhelper = new DatabaseHelper(getContext());
return true;
}
getType() :コンテンツURIに対応するMIMEタイプを返します。
@Override
public String getType(Uri uri) {
final int match = matcher.match(uri);
switch (match) {
case DATA_TABLE:
return ContentResolver.CURSOR_DIR_BASE_TYPE + "/" + MyContract.CONTENT_AUTHORITY + "/" + MyContract.PATH_DATATABLE;
case DATA_TABLE_DATE:
return ContentResolver.ANY_CURSOR_ITEM_TYPE + "/" + MyContract.CONTENT_AUTHORITY + "/" + MyContract.PATH_DATATABLE;
default:
throw new UnsupportedOperationException("Unknown Uri: " + uri);
}
}
query() :プロバイダからデータを取得します。引数を使用して、照会する表、戻す行と列、および結果のソート順を選択します。データをCursorオブジェクトとして返します。
@Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
Cursor retCursor = dbHelper.getReadableDatabase().query(
MyContract.TABLE_NAME, projection, selection, selectionArgs, null, null, sortOrder);
retCursor.setNotificationUri(getContext().getContentResolver(), uri);
return retCursor;
}
プロバイダに新しい行を挿入します。引数を使用して宛先テーブルを選択し、使用する列値を取得します。新しく挿入された行のコンテンツURIを返します。
@Override
public Uri insert(Uri uri, ContentValues values)
{
final SQLiteDatabase db = dbHelper.getWritableDatabase();
long id = db.insert(MyContract.TABLE_NAME, null, values);
return ContentUris.withAppendedId(MyContract.CONTENT_URI, ID);
}
delete() :プロバイダから行を削除します。引数を使用して、削除するテーブルと行を選択します。削除された行の数を返します。
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
SQLiteDatabase db = dbHelper.getWritableDatabase();
int rowsDeleted = db.delete(MyContract.TABLE_NAME, selection, selectionArgs);
getContext().getContentResolver().notifyChange(uri, null);
return rowsDeleted;
}
update() :プロバイダの既存の行を更新します。引数を使用して、更新するテーブルと行を選択し、新しい列の値を取得します。更新された行の数を返します。
@Override
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
SQLiteDatabase db = dbHelper.getWritableDatabase();
int rowsUpdated = db.update(MyContract.TABLE_NAME, values, selection, selectionArgs);
getContext().getContentResolver().notifyChange(uri, null);
return rowsUpdated;
}
4)マニフェストファイルの更新
<provider
android:authorities="com.example.myApp"
android:name=".DatabaseProvider"/>