Android之自定义ContentProvider详解
第一個版本 ?對android中MIME類型的理解
初始MIME類型,是在學習ContentProvider的時候。
??????當在創建自己的ContentProvider的時,需要從抽象類ContentProvider中派生出自己的子類,并實現其中5個抽象方法:
- query(Uri, String[], String, String[], String) which returns data to the caller
- insert(Uri, ContentValues) which inserts new data into the content provider
- update(Uri, ContentValues, String, String[]) which updates existing data in the content provider
- delete(Uri, String, String[]) which deletes data from the content provider
- getType(Uri) which returns the MIME type of data in the content provider
?????? 至于前四個方法,不是本文想要討論的重點,就不做冗余的闡述了;有意思的是這個方法getType(Uri),根據幫助文檔的解釋,它返回一個MIME類型。
?????? 首先,先百度了一下MIME類型,根據百度百科的解釋:MIME:全稱Multipurpose Internet Mail Extensions,多功能Internet 郵件擴充服務。它是一種多用途網際郵件擴充協議,在1992年最早應用于電子郵件系統,但后來也應用到瀏覽器。MIME類型就是設定某種擴展名的文件用一種應用程序來打開的方式類型,當該擴展名文件被訪問的時候,瀏覽器會自動使用指定應用程序來打開。多用于指定一些客戶端自定義的文件名,以及一些媒體文件打開方式。
????? 看完百度百科的解釋,相信大家和我一樣,仍然不解。結合一個例子,與老師交流之后,我的理解是這樣的:
?????? 在ContentProvider的getType(Uri)方法中,可以顯示的返回一個MIME類型,該方法返回一個字符串,可以是任意的字符串,當我們顯示的返回該MIME類型的時候,相當于通過該方法的驗證,Provider可以識別自身其他方法返回的Cursor的內容,不需要在進行更多的驗證;如果返回其他的字符串(非android能夠識別的MIME類型,例如直接返回當前的包名),則Provider在執行其他方法后,返回Cursor類型的時候,需要再次進行驗證。
??? 還是云里霧里的?下面來看一個使用了MIME類型的自定義ContentProvider的例子:
import android.net.Uri;
public class Shopping {
?
// 定義數據庫的名字
public static final String DATABASE_NAME = "shopping_db";
// 定義數據庫的版本
public static final int DATABASE_VERSION = 1;
// 表的名字
public static final String TABLE_NAME = "t_shopping";
// 定義數據庫的字段
public static final String FIELD_ID = "_id";
public static final String FIELE_NAME = "product_name";
// 定義訪問的類型
public static final int ITEM = 1;
public static final int ITEM_ID = 2;
// 定義MIME類型,訪問單個記錄
public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/vnd.com.stone.shopping";
// 訪問數據集
public static final String CONTENT_ITEM = "vnd.android.cursor.dir/vnd.stone.shopping";
// 定義訪問ContentProvider權限
public static final String AUTHORITY = "com.stone.shopping";
// 定義URI
public static final Uri URI = Uri.parse("content://" + AUTHORITY + "/item");
}?
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
public class MyDbHelper extends SQLiteOpenHelper {
public MyDbHelper(Context context, String name, CursorFactory factory,?int version) {
super(context, name, factory, version);
}
@Override
public void onCreate(SQLiteDatabase db) {
String sql = "CREATE TABLE " + Shopping.TABLE_NAME + " ( "?+?
Shopping.FIELD_ID + " INTEGER primary key autoincrement, "?+ " " + Shopping.FIELE_NAME + " TEXT)";
db.execSQL(sql);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
String sql = "DROP TABLE IF EXISTS " + Shopping.TABLE_NAME;
db.execSQL(sql);
onCreate(db);
}
}??
import android.content.ContentProvider;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.net.Uri;
import android.text.TextUtils;
public class MyProvider extends ContentProvider {
private MyDbHelper myDbHelper;
private static final UriMatcher mUriMatcher; // 進行匹配的Uri的設定
static {
mUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
mUriMatcher.addURI(Shopping.AUTHORITY, "item", Shopping.ITEM);
mUriMatcher.addURI(Shopping.AUTHORITY, "item/#", Shopping.ITEM_ID);
}
@Override
public boolean onCreate() {
// 創建數據庫
myDbHelper = new MyDbHelper(getContext(), Shopping.DATABASE_NAME, null, Shopping.DATABASE_VERSION);
return true;
}
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
SQLiteDatabase db = myDbHelper.getWritableDatabase();
int count = 0;
switch (mUriMatcher.match(uri)) {
case Shopping.ITEM:
ount = db.delete(Shopping.TABLE_NAME, selection, selectionArgs);
break;
case Shopping.ITEM_ID:
// 通過Uri獲取Id,根據主鍵進行刪除
String id = uri.getPathSegments().get(1);
System.out.println(String.valueOf(uri.getPathSegments().size()));
count = db.delete(Shopping.TABLE_NAME,Shopping.FIELD_ID + "=" + id, selectionArgs);
break;
default:
throw new IllegalArgumentException();
}
// 通知數據發生改變
getContext().getContentResolver().notifyChange(uri, null);
return count;
}
@Override
public Uri insert(Uri uri, ContentValues values) {
SQLiteDatabase db = myDbHelper.getWritableDatabase();
long row = 0;
if (mUriMatcher.match(uri) != Shopping.ITEM) {
throw new IllegalArgumentException();
}
row = db.insert(Shopping.TABLE_NAME, Shopping.FIELD_ID, values);
if (row > 0) {
Uri noteUri = ContentUris.withAppendedId(Shopping.URI, row);
getContext().getContentResolver().notifyChange(uri, null);
return noteUri;
}
return null;
}
@Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
SQLiteDatabase db = myDbHelper.getReadableDatabase();
Cursor cursor = null;
switch (mUriMatcher.match(uri)) {
case Shopping.ITEM:
cursor = db.query(Shopping.TABLE_NAME, projection, selection, selectionArgs, null, null, sortOrder);
break;
case Shopping.ITEM_ID:
String id = uri.getPathSegments().get(1);
cursor = db.query(Shopping.TABLE_NAME, projection,?Shopping.FIELD_ID + "=" + id + (!TextUtils.isEmpty(selection) ? " AND (" + selection + ')' : ""),
selectionArgs,?null, null, sortOrder);
break;
default:
throw new IllegalArgumentException();
}
cursor.setNotificationUri(getContext().getContentResolver(), uri);
return cursor;
}
@Override
public int update(Uri uri, ContentValues values, String selection,?String[] selectionArgs) {
SQLiteDatabase db = myDbHelper.getWritableDatabase();
int count = 0;
switch (mUriMatcher.match(uri)) {
case Shopping.ITEM:
count = db.update(Shopping.TABLE_NAME, values, selection, selectionArgs);
break;
case Shopping.ITEM_ID:
String id = uri.getPathSegments().get(1);
count = db.update(Shopping.TABLE_NAME, values, Shopping.FIELD_ID?+ "="?+ id?+ (!TextUtils.isEmpty(selection) ? " AND (" + selection?+ ')' : ""),
selectionArgs);
break;
default:
throw new IllegalArgumentException();
}
getContext().getContentResolver().notifyChange(uri, null);
return count;
}
@Override
public String getType(Uri uri) { // 進行Uri匹配完成不同的處理工作
switch (mUriMatcher.match(uri)) {
case Shopping.ITEM:
return Shopping.CONTENT_ITEM;
case Shopping.ITEM_ID:
return Shopping.CONTENT_ITEM_TYPE;
default:
throw new IllegalArgumentException();
}
}
}
??? 在上面的例子中,首先有一個Shopping類,定義了一系列的常量。包括訪問的數據庫的相關信息和URI的定義,其中最重要的就是下面的兩句,MIME類型的定義:
public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/vnd.stone.shopping";
public static final String CONTENT_ITEM = "vnd.android.cursor.dir/vnd.stone.shopping";?
??? 其次是一個MyDbHelper類,繼承自SQLiteOpenHelper類,用于一些數據庫相關操作,這里就不贅述了。
??? 最后的MyProvider類使我們的重頭戲,首先我們來看這一段代碼:
private static final UriMatcher mUriMatcher; // 進行匹配的Uri的設定
static {
?? mUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
?? mUriMatcher.addURI(Shopping.AUTHORITY, "item", Shopping.ITEM);
?? mUriMatcher.addURI(Shopping.AUTHORITY, "item/#", Shopping.ITEM_ID);
}
??? UriMatcher表示一個Uri的匹配器,它會對我們請求的Uri進行匹配,而匹配的格式就是這里我們通過addURI()方法添加格式。
??? 接下來,首先執行的就是getType(Uri)方法,下面來看該方法體中的代碼:
switch (mUriMatcher.match(uri)) {
case Shopping.ITEM:
return Shopping.CONTENT_ITEM;
case Shopping.ITEM_ID:
return Shopping.CONTENT_ITEM_TYPE;
default:
throw new IllegalArgumentException();
}???
??? 當請求過來的Uri通過mUriMatcher.match(uri)方法進行匹配,根據不同的匹配值來返回不同的MIME類型。下面我們來結合query(Uri, String[], String, String[], String)這個方法來解釋一下:
??? 在該方法中,返回一個Cursor游標對象。而Cursor中是單條的記錄還是一個集合,需要和在getType()方法中返回的類型保持一致。當返回的MIME類型是Shopping.CONTENT_ITEM時,Cursor應該是一個集合;當返回的MIME類型是Shopping.CONTENT_ITEM_TYPE時,Cursor應該是單條記錄。
??? 由于在getType()方法里面,我們顯示的返回了android平臺可以識別的MIME類型,所以在執行query()方法返回Cursor對象的時候,系統將不需要再進行驗證,從而可以說是節省了系統開銷。
?
????話已至此,那么何謂android平臺可以識別的MIME類型呢?下面來分析一下MIME類型的結構:
????其實,MIME類型其實就是一個字符串,中間有一個 “/” 來隔開,“/”前面的部分是系統識別的部分,就相當于我們定義一個變量時的變量數據類型,通過這個“數據類型”,系統能夠知道我們所要表示的是個什么東西。至于 “/” 后面的部分就是我們自已來隨便定義的“變量名”了。
????那么,既然MIME類型就是一個字符串,那么我們的getType()自然也可以隨便返回一個系統不能識別的字符串啦?沒錯,有些時候我們確實也這樣處理,比如說可以這樣寫:
?
public String getType(Uri uri) {
return getContext().getPackageName();?
}
?
??? 這里,我們把當前上下文的包名返回了。這樣處理的結果是怎樣的呢?
?
??? 簡單的說,系統不能夠識別它了,也就不會做任何處理。仍然以query()方法來說,當執行完方法體(這里需要注意一下:在這種情況下,即使我們沒有通過返回MIME類型字符串來進行驗證處理,但是在query()方法中再次對Uri進行了匹配并根據不同的Uri類型進行了不同的操作)返回Cursor對象的時候,這時候系統不能肯定返回的Cursor對象是否合法,因此需要對其進行驗證,這樣對系統資源算是一個浪費了吧。所以,我們最好還是顯示的返回一個MIME類型吧,當然要寫正確了,讓我們android平臺可以識別。
sourceurl:http://blog.csdn.net/h3g2010/article/details/6093366
第二個版本
在Android中,每個程序都在自己的進程中運行,互不干擾.這樣的好處不說了,但是帶來的問題就是想要在程序之間實現數據共享,在沒有其它工具的幫助下,就難以實現了.為了解決這個問題,ContentProvider就派上用場了.
一,說說ContentProvider怎么用.
???1,把你想要共享出去的數據用一個URl表示出來.如:content://contacts/people/5(聯系人信息中Id位5的聯系人記錄).或者這樣也行:Uri person =ContentUris.withAppendedId(People.CONTENT_URI,5);來封裝.
?? 2,所有的Content Providers都會實現一些共同的接口,可以通過唯一的ContentResolveer來向外提供數據,冰進行一系列的增刪改查;ContentResolver cr = getContentResplver();
?? 3,cr利用定義好的uri(作為參數送給cr封裝好的方法里面進行一系列的操作);
至于ContentProvider的實例化,這些不需要我們去做,系統會做這件事.對于ContentProvider,正常情況下,只需一個,但是ContentResolver可以存在多個,在不同進程中的
ContentResolver可以使用同一個ContentProvider.
二,定義自己的ContentProvider
??? 根據我個人的理解,這作用就有點像J2EE里面的DAO的作用.
?? ?
??? 1,實現一個定義節本字段的類.示例如下:
???????? ?
???????? ?
? public class NotePad
{
?? ?//ContentProvider的uri
?? ?public static final String?? ?AUTHORITY?? ?= "com.google.provider.NotePad";
?? ?private NotePad(){}
?? ?// 定義基本字段
?? ?public static final class Notes implements BaseColumns
?? ?{
?? ??? ?private 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";
?? ?}
}
???????? ?
?解釋一下MIME類型,假如你要處理的數據類型是新的類型,就得定義一個新的MIME類型,一邊ContentProvider.getType(url)來調用;
?粉單個與多個;
?
?2,創建自己的ContentProvider
???? ?
????如果要共享的是數據庫,我們在這里可以封裝一個SqlLiteOpenHelper,以便建庫建表 ,對于 SqlLiteOpenHelper 用過數據庫的人應該都懂,在這里就不贅述了;
?? ?
??? 然后在ContentProvider里面實現增刪改查,另外如果有自定義類型的話,還的在ContentProvider劉main實現一個方法?? ?
?? ??? ?
?? ?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);
?? ??? ?}
?? ?}
?
?實例如下:
?
???? 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<String, String>?? ?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<String, String>();
?? ??? ?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;
?? ?}
}
這樣我們就實現了一個自定義的ContentProvider,檔然最后不要忘記一件事情了,在AndroidMinifest.xml中聲明我們定義好的ContentProvider
??? <provider android:name="NotePadProvider"?
??? android:authorities="com.google.provider.NotePad"/>
?? ?
好了,一切OK!
總結
以上是生活随笔為你收集整理的Android之自定义ContentProvider详解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Android之URI简介
- 下一篇: Android之监测database的改