AndroidカスタムContentProvider
カスタムContentProvider
----------------------------
コンテンツプロバイダは、データソースとのやりとりに用いる、コンテンツ解析器(ContentResolver)は、具体的なコンテンツプロバイダの操作を担当する.データソースは、ファイルまたはデータベースであるもよい.複数のコンテンツ解析器は、スレッドが安全であるため、コンテンツプロバイダに同時にアクセスすることができる.
1つのURIは1つのリソースを決定することができ、1つのコンテンツプロバイダは複数のURIを有することができる.しかし、すべてのURIのAUTHEORITYは同じです.
Androidには共有メモリがないため、別のプロセスのデータにアクセスするにはコンテンツプロバイダで操作する必要がある.
1.ContentProviderを継承し、すべての抽象メソッドを書き換える.
Android OSはContentProviderのonCreate()メソッドを自動的に呼び出し、データベースは必要に応じて有効にする.
2.AndroidManifestを配置する.xml
android:name="tl.android.data.TestContentProvider">
name:ContentProviderサブクラスの完全クラスパスを指定します.
authorities:ContentProviderの唯一のIDを指定します(推奨:会社名.provider.データテーブル名+provider)
3.コンテンツプロバイダに対して各種定数を定義.
CONTENT_URI
TABLE_NAME
DATABASE_NAME
DATABASE_VERSION
...
4.ContentResolverによるデータレコードの挿入
5.生成されたデータベースを取得し、表示
*.dbは一般的にアプリケーションディレクトリのdatabasesの下にある.
例:
/data/data/tl.android.apps/databases/books.db
データベースをCにコピーするには、次の手順に従います.
adb pull/data/data/tl.android.apps/databases/books.db c:\
生成されるbooks.dbドラッグsqlite 3.exe(Android SDK toolsディレクトリ)
データベース内のテーブルの表示
.tables
特定のテーブルの表示
select * from table_name;
参照コード:
TestContentProvider.java
MainActivity.java
AndroidManifest.xml
----------------------------
コンテンツプロバイダは、データソースとのやりとりに用いる、コンテンツ解析器(ContentResolver)は、具体的なコンテンツプロバイダの操作を担当する.データソースは、ファイルまたはデータベースであるもよい.複数のコンテンツ解析器は、スレッドが安全であるため、コンテンツプロバイダに同時にアクセスすることができる.
1つのURIは1つのリソースを決定することができ、1つのコンテンツプロバイダは複数のURIを有することができる.しかし、すべてのURIのAUTHEORITYは同じです.
Androidには共有メモリがないため、別のプロセスのデータにアクセスするにはコンテンツプロバイダで操作する必要がある.
1.ContentProviderを継承し、すべての抽象メソッドを書き換える.
Android OSはContentProviderのonCreate()メソッドを自動的に呼び出し、データベースは必要に応じて有効にする.
2.AndroidManifestを配置する.xml
name:ContentProviderサブクラスの完全クラスパスを指定します.
authorities:ContentProviderの唯一のIDを指定します(推奨:会社名.provider.データテーブル名+provider)
3.コンテンツプロバイダに対して各種定数を定義.
CONTENT_URI
TABLE_NAME
DATABASE_NAME
DATABASE_VERSION
...
4.ContentResolverによるデータレコードの挿入
5.生成されたデータベースを取得し、表示
*.dbは一般的にアプリケーションディレクトリのdatabasesの下にある.
例:
/data/data/tl.android.apps/databases/books.db
データベースをCにコピーするには、次の手順に従います.
adb pull/data/data/tl.android.apps/databases/books.db c:\
生成されるbooks.dbドラッグsqlite 3.exe(Android SDK toolsディレクトリ)
データベース内のテーブルの表示
.tables
特定のテーブルの表示
select * from table_name;
参照コード:
TestContentProvider.java
package tl.android.data;
import java.util.HashMap;
import tl.android.data.TestContentProviderMetaData.BookTableMetaData;
import android.content.ContentProvider;
import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.database.sqlite.SQLiteQueryBuilder;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
import android.net.Uri;
import android.provider.BaseColumns;
import android.text.TextUtils;
import android.util.Log;
public class TestContentProvider extends ContentProvider {
public static final String TAG = "amos_tl";
public DatabaseHelper openHelper = null;
//-- JavaBean .
public static HashMap<String, String> sBookProjectionMap = null;
static{
sBookProjectionMap = new HashMap<String, String >();
sBookProjectionMap.put(BookTableMetaData._ID, BookTableMetaData._ID);
sBookProjectionMap.put(BookTableMetaData.BOOK_NAME, BookTableMetaData.BOOK_NAME);
sBookProjectionMap.put(BookTableMetaData.BOOK_ISBN, BookTableMetaData.BOOK_ISBN);
sBookProjectionMap.put(BookTableMetaData.BOOK_AUTHOR, BookTableMetaData.BOOK_AUTHOR);
sBookProjectionMap.put(BookTableMetaData.CREATED_DATE, BookTableMetaData.CREATED_DATE);
sBookProjectionMap.put(BookTableMetaData.MODIFIED_DATE, BookTableMetaData.MODIFIED_DATE);
}
//-- URI
private static UriMatcher sUriMatcher = null;
//-- URI
private static final int INCOMMING_BOOK_COLLECTION_URI_INDICATOR = 1;
private static final int INCOMMING_SINGLE_BOOK_URI_INDICATOR = 2;
static{
sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
sUriMatcher.addURI(TestContentProviderMetaData.AUTHORITY, "books", INCOMMING_BOOK_COLLECTION_URI_INDICATOR);
sUriMatcher.addURI(TestContentProviderMetaData.AUTHORITY, "books/#", INCOMMING_SINGLE_BOOK_URI_INDICATOR);
}
@Override
public int delete(Uri uri, String whereClause, String[] whereArgs) {
Log.i(TAG, "del");
// TODO Auto-generated method stub
SQLiteDatabase db = openHelper.getWritableDatabase();
int count = 0;
switch(sUriMatcher.match(uri)){
case INCOMMING_BOOK_COLLECTION_URI_INDICATOR:
count = db.delete(BookTableMetaData.TABLE_NAME, whereClause, whereArgs);
break;
case INCOMMING_SINGLE_BOOK_URI_INDICATOR:
String rowID = uri.getPathSegments().get(1);
String where = BookTableMetaData._ID + "=" + rowID + (!TextUtils.isEmpty(whereClause)?" AND (" + whereClause + ')':"");
count = db.delete(BookTableMetaData.TABLE_NAME, where, whereArgs);
break;
default:
throw new IllegalArgumentException("Unknown URI " + uri);
}
this.getContext().getContentResolver().notifyChange(uri, null);
return count;
}
@Override
public String getType(Uri uri) {
switch(sUriMatcher.match(uri)){
case INCOMMING_BOOK_COLLECTION_URI_INDICATOR:
return BookTableMetaData.CONTENT_TYPE;
case INCOMMING_SINGLE_BOOK_URI_INDICATOR:
return BookTableMetaData.CONTENT_ITEM_TYPE;
default:
throw new IllegalArgumentException("Unknown URI " + uri);
}
}
@Override
public Uri insert(Uri uri, ContentValues values) {
// TODO Auto-generated method stub
Log.i(TAG, "insert");
if(sUriMatcher.match(uri) != INCOMMING_BOOK_COLLECTION_URI_INDICATOR){
throw new IllegalArgumentException("Unknown URI " + uri);
}
long now = Long.valueOf(System.currentTimeMillis());
if(values.containsKey(BookTableMetaData.CREATED_DATE) == false){
values.put(BookTableMetaData.CREATED_DATE, now);
}
if(values.containsKey(BookTableMetaData.MODIFIED_DATE) == false){
values.put(BookTableMetaData.MODIFIED_DATE, now);
}
if(values.containsKey(BookTableMetaData.BOOK_NAME) == false){
//values.put(BookTableMetaData.BOOK_NAME, "null");
throw new SQLException("Failed to insert row ,because Book Name is needed " + uri);
}
if(values.containsKey(BookTableMetaData.BOOK_ISBN) == false){
values.put(BookTableMetaData.BOOK_ISBN, "Unknown ISBN");
}
if(values.containsKey(BookTableMetaData.BOOK_AUTHOR) == false){
values.put(BookTableMetaData.BOOK_AUTHOR, "Unknown author");
}
SQLiteDatabase db = openHelper.getWritableDatabase();
long rowID = db.insert(BookTableMetaData.TABLE_NAME, BookTableMetaData.BOOK_NAME, values);
if(rowID > 0){
Uri insertBookedUri = ContentUris.withAppendedId(BookTableMetaData.CONTENT_URI, rowID);
getContext().getContentResolver().notifyChange(insertBookedUri, null);
return insertBookedUri;
}
throw new SQLException("Failed to insert row into " + uri);
}
@Override
public boolean onCreate() {
// TODO Auto-generated method stub
Log.i(TAG, "create table");
openHelper = new DatabaseHelper(this.getContext());
Log.i(TAG, openHelper.toString());
return true;
}
@Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
// TODO Auto-generated method stub
Log.i(TAG, "query");
Cursor cursor = null;
SQLiteQueryBuilder qb = null;
qb = new SQLiteQueryBuilder();
switch(sUriMatcher.match(uri)){
case INCOMMING_BOOK_COLLECTION_URI_INDICATOR:
qb.setTables(BookTableMetaData.TABLE_NAME);
qb.setProjectionMap(sBookProjectionMap);
break;
case INCOMMING_SINGLE_BOOK_URI_INDICATOR:
qb.setTables(BookTableMetaData.TABLE_NAME);
qb.setProjectionMap(sBookProjectionMap);
qb.appendWhere(BookTableMetaData._ID + "=" + uri.getPathSegments().get(1));
break;
default:
throw new IllegalArgumentException("Unknown URI " + uri);
}
String orderBy = "";
if(TextUtils.isEmpty(sortOrder)){
orderBy = BookTableMetaData.DEFAULT_SORT_ORDER;
}else{
orderBy = sortOrder;
}
SQLiteDatabase db = openHelper.getReadableDatabase();
Cursor c = qb.query(db, projection, selection, selectionArgs, null, null, orderBy);
int i = c.getCount();
ContentResolver cr = this.getContext().getContentResolver();
c.setNotificationUri(cr, uri);
return c;
}
@Override
public int update(Uri uri, ContentValues values, String selection,
String[] selectionArgs) {
// TODO Auto-generated method stub
Log.i(TAG, "update");
SQLiteDatabase db = openHelper.getWritableDatabase();
int count = 0;
switch(sUriMatcher.match(uri)){
case INCOMMING_BOOK_COLLECTION_URI_INDICATOR:
count = db.update(BookTableMetaData.TABLE_NAME, values, selection, selectionArgs);
break;
case INCOMMING_SINGLE_BOOK_URI_INDICATOR:
String rowID = uri.getPathSegments().get(1);
String where = "BookTableMetaData._ID" + "=" + rowID + (!TextUtils.isEmpty(selection)?" AND(" + selection + ')':"");
count = db.update(BookTableMetaData.TABLE_NAME, values, where, selectionArgs);
break;
default:
throw new IllegalArgumentException("Unknown URI " + uri);
}
getContext().getContentResolver().notifyChange(uri, null);
return count;
}
//-- create table
public class DatabaseHelper extends SQLiteOpenHelper{
public DatabaseHelper(Context context) {
super(context, TestContentProviderMetaData.DATABASE_NAME, null, TestContentProviderMetaData.DATABASE_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
// TODO Auto-generated method stub
String sql = "CREATE TABLE " + BookTableMetaData.TABLE_NAME
+ " (" + TestContentProviderMetaData.BookTableMetaData._ID
+ " INTEGER PRIMARY KEY,"
+ BookTableMetaData.BOOK_NAME + " TEXT,"
+ BookTableMetaData.BOOK_ISBN + " TEXT,"
+ BookTableMetaData.BOOK_AUTHOR + " TEXT,"
+ BookTableMetaData.CREATED_DATE + " INTEGER,"
+ BookTableMetaData.MODIFIED_DATE + " INTEGER"
+ ");";
Log.i(TAG, db.getPath());
db.execSQL(sql);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// TODO Auto-generated method stub
Log.i(TAG, "Upgrade database from " + oldVersion + " to "
+ newVersion + ", which will destroy old data!");
String sql = "DROP TABLE IF EXISTS " + BookTableMetaData.TABLE_NAME;
db.execSQL(sql);
onCreate(db);
}
}
}
class TestContentProviderMetaData {
public static final String DATABASE_NAME = "books.db";
public static final int DATABASE_VERSION = 1;
public static final String AUTHORITY = "tl.android.provider.bookprovider";
public static final String BOOKS_TABLE_NAME = "books";
public static final class BookTableMetaData implements BaseColumns{
public static final String TABLE_NAME = "books";
// String
public static final String BOOK_NAME = "name";
// String
public static final String BOOK_ISBN = "isbn";
// String
public static final String BOOK_AUTHOR = "author";
// Integer
public static final String CREATED_DATE = "created";
// Integer
public static final String MODIFIED_DATE = "modified";
public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/books");
//--
public static final String CONTENT_TYPE = "vnd.android.cursor.dir/vnd.androidbook.book";
//--
public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/vnd.androidbook.book";
public static final String DEFAULT_SORT_ORDER = "modified DESC";
}
}
MainActivity.java
package tl.android.apps;
import tl.android.data.TestContentProvider;
import android.app.Activity;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
public class MainActivity extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
ContentResolver cr = this.getContentResolver();
ContentValues cv = new ContentValues();
cv.put("name", "android pro");
cr.insert(TestContentProvider.CONTENT_URI, cv);
cv.put("name", "android programming");
cr.insert(TestContentProvider.CONTENT_URI, cv);
}
}
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="tl.android.apps" android:versionCode="1" android:versionName="1.0">
<application android:icon="@drawable/icon" android:label="@string/app_name">
<activity android:name="tl.android.apps.MainActivity" android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<provider android:authorities="tl.android.provider.bookprovider"
android:name="tl.android.data.TestContentProvider"></provider>
</application>
<uses-sdk android:minSdkVersion="4" />
</manifest>