整個流程在 Android 官網(Create Your Content Provider)已經有很豐富的介紹,在此筆記一下 :P 加快自己往後回憶。
新增自己的 content provider 的用亦是供別人來存取自身 app 的資料(大多是 SQLite 操作),而實做流程並不難,但有一些小事要留意:
- 假設你的 app 的 package name 為 com.example.study,實做為 Content Provider Class 為 MyContentProvider。
- 首先,建立一個 app 名為 MyContentProvider,但不需要 Activity,新增完後,在新增一個 class 名為 MyContentProvider 並繼承 android.content.ContentProvider。
- 由於 content provider 給予外頭存取時,用到的格式為 "content://AUTHORITY/DBTable" 的型態,故決定 Content Provider 的 AUTHORITY 數值及使用的 SQLite db table name,此例定為 "com.example.study" 和 "MyTable1"、"MyTable2" 兩者。
- 實做 SQLiteOpenHelper,此例為 MyDBHelper,過程中建立兩張表,分別為 MyTable1 和 MyTable2 兩張表
CREATE TABLE MyTable1 ( _ID INTEGER PRIMARY KEY, _DATE DATETIME NULL )
CREATE TABLE MyTable2 ( _ID INTEGER PRIMARY KEY, _DATA VARCHAR(50) NULL )- 決定 content provider 所提供的 URI 服務後,使用 UriMatcher 來實做判斷方式
private static final UriMatcher mUriMatcher;
private static final int URI_TYPE_TABLE1 = 1;
private static final int URI_TYPE_TABLE2 = 2;
static {
mUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
mUriMatcher.addURI(AUTHORITY, MyDBHelper._DB_TABLE1, URI_TYPE_TABLE1);
mUriMatcher.addURI(AUTHORITY, MyDBHelper._DB_TABLE2, URI_TYPE_TABLE2);
}- 實做 content provider 的相關函數,此例僅實做 String getType(Uri uri) 和 Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) 兩個函數,前者用來告知 URI 所回傳的資料型態,後者則是 URI Query 時,將取得的 Cursor 操作方式(此為 SQLite 常用方式)
- 設定 AndroidManifest.xml,跟系統註冊使用 content provider。AndroidManifest.xml -> Application 分頁 -> Application Nodes -> Add -> Provider -> Name 欄位瀏覽 -> 選擇 MyContentProvider 後,並輸入 Authorities 欄位資訊(此例為com.example.study)
- 最後,實做一個 TestingActivity 來執行 content provider 的 query 動作,並從 Log.w 觀察情況。
程式碼:
MyContentProvider.java:
package com.example.study;
import android.content.ContentProvider;
import android.content.ContentValues;
import android.content.Context;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
import android.database.sqlite.SQLiteOpenHelper;
import android.net.Uri;
public class MyContentProvider extends ContentProvider {
private static final String AUTHORITY = "com.example.study";
private static final UriMatcher mUriMatcher;
private static final int URI_TYPE_TABLE1 = 1;
private static final int URI_TYPE_TABLE2 = 2;
static {
mUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
mUriMatcher.addURI(AUTHORITY, MyDBHelper._DB_TABLE1, URI_TYPE_TABLE1);
mUriMatcher.addURI(AUTHORITY, MyDBHelper._DB_TABLE2, URI_TYPE_TABLE2);
}
private class MyDBHelper extends SQLiteOpenHelper {
public static final String _DB_NAME = "MyDatabases.db";
public static final String _DB_TABLE1 = "MyTable1";
public static final String _DB_TABLE2 = "MyTable2";
public static final int _DB_VERSION = 1;
public MyDBHelper(Context context) {
super(context, _DB_NAME, null, _DB_VERSION);
}
public MyDBHelper(Context context, String name, CursorFactory factory, int version) {
super(context, name, factory, version);
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL( "CREATE TABLE "+_DB_TABLE1+" ( _ID INTEGER PRIMARY KEY, _DATE DATETIME NULL )" );
db.execSQL( "CREATE TABLE "+_DB_TABLE2+" ( _ID INTEGER PRIMARY KEY, _DATA VARCHAR(50) NULL )" );
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS "+_DB_TABLE1);
db.execSQL("DROP TABLE IF EXISTS "+_DB_TABLE2);
}
}
MyDBHelper mHelper = null;
private void genTesting() {
SQLiteDatabase mDB = mHelper.getWritableDatabase();
// MyDBHelper._DB_TABLE1
mDB.execSQL("INSERT INTO "+MyDBHelper._DB_TABLE1+" (_DATE) VALUES (datetime('now'))");
// MyDBHelper._DB_TABLE2
ContentValues values = new ContentValues();
values.put("_DATA", "Hello World!");
mDB.insertOrThrow(MyDBHelper._DB_TABLE2, null, values);
mDB.close();
}
@Override
public boolean onCreate() {
// TODO Auto-generated method stub
mHelper = new MyDBHelper(getContext());
return true;
}
@Override
public String getType(Uri uri) {
// TODO Auto-generated method stub
switch(mUriMatcher.match(uri)) {
case URI_TYPE_TABLE1:
return "vnd.android.cursor.item/vnd."+AUTHORITY+"."+MyDBHelper._DB_TABLE1; // one row
case URI_TYPE_TABLE2:
return "vnd.android.cursor.dir/vnd."+AUTHORITY+"."+MyDBHelper._DB_TABLE2; // multiple rows
default:
throw new IllegalArgumentException("Unknown URI " + uri);
}
}
@Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
// TODO Auto-generated method stub
genTesting();
Cursor out = null;
SQLiteDatabase mDB = null;
switch(mUriMatcher.match(uri)) {
case URI_TYPE_TABLE1:
mDB = mHelper.getWritableDatabase();
out = mDB.rawQuery("SELECT * FROM "+MyDBHelper._DB_TABLE1+" ORDER BY _ID DESC LIMIT 1", null);
out.moveToFirst();
break;
case URI_TYPE_TABLE2:
mDB = mHelper.getWritableDatabase();
out = mDB.rawQuery("SELECT * FROM "+MyDBHelper._DB_TABLE2, null);
out.moveToFirst();
break;
default:
throw new IllegalArgumentException("Unknown URI " + uri);
}
return out;
}
@Override
public Uri insert(Uri uri, ContentValues values) {
// TODO Auto-generated method stub
return null;
}
@Override
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
// TODO Auto-generated method stub
return 0;
}
@Override
public int delete(Uri arg0, String arg1, String[] arg2) {
// TODO Auto-generated method stub
return 0;
}
}
MyContentProviderTestingActivity.java:
package com.example.study.test;
import android.app.Activity;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
public class MyContentProviderTestingActivity extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Cursor c = getContentResolver().query(
Uri.parse("content://com.example.study/MyTable1"),
null,null,null,null ); // get all
if( c != null ) {
c.moveToFirst();
while(c.isAfterLast()==false) {
Log.e("CP","MyTalbe1 field1:"+c.getString(0)+", field2:"+c.getString(1));
c.moveToNext();
}
c.close();
c = getContentResolver().query(
Uri.parse("content://com.example.study/MyTable2"),
null,null,null,null ); // get all
c.moveToFirst();
while(c.isAfterLast()==false) {
Log.e("CP","MyTalbe2 field1:"+c.getString(0)+", field2:"+c.getString(1));
c.moveToNext();
}
c.close();
}
}
}
沒有留言:
張貼留言