整個流程在 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();
 
                 }
         }
}
 
沒有留言:
張貼留言