日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 运维知识 > Android >内容正文

Android

Android之自定义ContentProvider详解

發(fā)布時(shí)間:2023/12/4 Android 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Android之自定义ContentProvider详解 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

第一個(gè)版本 ?對(duì)android中MIME類型的理解

初始MIME類型,是在學(xué)習(xí)ContentProvider的時(shí)候。

??????當(dāng)在創(chuàng)建自己的ContentProvider的時(shí),需要從抽象類ContentProvider中派生出自己的子類,并實(shí)現(xiàn)其中5個(gè)抽象方法:

  • 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

?????? 至于前四個(gè)方法,不是本文想要討論的重點(diǎn),就不做冗余的闡述了;有意思的是這個(gè)方法getType(Uri),根據(jù)幫助文檔的解釋,它返回一個(gè)MIME類型。

?????? 首先,先百度了一下MIME類型,根據(jù)百度百科的解釋:MIME:全稱Multipurpose Internet Mail Extensions,多功能Internet 郵件擴(kuò)充服務(wù)。它是一種多用途網(wǎng)際郵件擴(kuò)充協(xié)議,在1992年最早應(yīng)用于電子郵件系統(tǒng),但后來(lái)也應(yīng)用到瀏覽器。MIME類型就是設(shè)定某種擴(kuò)展名的文件用一種應(yīng)用程序來(lái)打開(kāi)的方式類型,當(dāng)該擴(kuò)展名文件被訪問(wèn)的時(shí)候,瀏覽器會(huì)自動(dòng)使用指定應(yīng)用程序來(lái)打開(kāi)。多用于指定一些客戶端自定義的文件名,以及一些媒體文件打開(kāi)方式。

????? 看完百度百科的解釋,相信大家和我一樣,仍然不解。結(jié)合一個(gè)例子,與老師交流之后,我的理解是這樣的:

?????? 在ContentProvider的getType(Uri)方法中,可以顯示的返回一個(gè)MIME類型,該方法返回一個(gè)字符串,可以是任意的字符串,當(dāng)我們顯示的返回該MIME類型的時(shí)候,相當(dāng)于通過(guò)該方法的驗(yàn)證,Provider可以識(shí)別自身其他方法返回的Cursor的內(nèi)容,不需要在進(jìn)行更多的驗(yàn)證;如果返回其他的字符串(非android能夠識(shí)別的MIME類型,例如直接返回當(dāng)前的包名),則Provider在執(zhí)行其他方法后,返回Cursor類型的時(shí)候,需要再次進(jìn)行驗(yàn)證。

??? 還是云里霧里的?下面來(lái)看一個(gè)使用了MIME類型的自定義ContentProvider的例子:

import android.net.Uri;

public class Shopping {

?

// 定義數(shù)據(jù)庫(kù)的名字
public static final String DATABASE_NAME = "shopping_db";
// 定義數(shù)據(jù)庫(kù)的版本
public static final int DATABASE_VERSION = 1;
// 表的名字
public static final String TABLE_NAME = "t_shopping";
// 定義數(shù)據(jù)庫(kù)的字段
public static final String FIELD_ID = "_id";
public static final String FIELE_NAME = "product_name";
// 定義訪問(wèn)的類型
public static final int ITEM = 1;
public static final int ITEM_ID = 2;
// 定義MIME類型,訪問(wèn)單個(gè)記錄
public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/vnd.com.stone.shopping";
// 訪問(wèn)數(shù)據(jù)集
public static final String CONTENT_ITEM = "vnd.android.cursor.dir/vnd.stone.shopping";
// 定義訪問(wèn)ContentProvider權(quán)限
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; // 進(jìn)行匹配的Uri的設(shè)定
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() {

// 創(chuàng)建數(shù)據(jù)庫(kù)
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:

// 通過(guò)Uri獲取Id,根據(jù)主鍵進(jìn)行刪除

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();

}

// 通知數(shù)據(jù)發(fā)生改變

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) { // 進(jìn)行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();

}

}

}

??? 在上面的例子中,首先有一個(gè)Shopping類,定義了一系列的常量。包括訪問(wèn)的數(shù)據(jù)庫(kù)的相關(guān)信息和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";?

??? 其次是一個(gè)MyDbHelper類,繼承自SQLiteOpenHelper類,用于一些數(shù)據(jù)庫(kù)相關(guān)操作,這里就不贅述了。

??? 最后的MyProvider類使我們的重頭戲,首先我們來(lái)看這一段代碼:

private static final UriMatcher mUriMatcher; // 進(jìn)行匹配的Uri的設(shè)定
static {
?? mUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
?? mUriMatcher.addURI(Shopping.AUTHORITY, "item", Shopping.ITEM);
?? mUriMatcher.addURI(Shopping.AUTHORITY, "item/#", Shopping.ITEM_ID);
}

??? UriMatcher表示一個(gè)Uri的匹配器,它會(huì)對(duì)我們請(qǐng)求的Uri進(jìn)行匹配,而匹配的格式就是這里我們通過(guò)addURI()方法添加格式。

??? 接下來(lái),首先執(zhí)行的就是getType(Uri)方法,下面來(lái)看該方法體中的代碼:

switch (mUriMatcher.match(uri)) {

case Shopping.ITEM:

return Shopping.CONTENT_ITEM;

case Shopping.ITEM_ID:

return Shopping.CONTENT_ITEM_TYPE;

default:

throw new IllegalArgumentException();

}???

??? 當(dāng)請(qǐng)求過(guò)來(lái)的Uri通過(guò)mUriMatcher.match(uri)方法進(jìn)行匹配,根據(jù)不同的匹配值來(lái)返回不同的MIME類型。下面我們來(lái)結(jié)合query(Uri, String[], String, String[], String)這個(gè)方法來(lái)解釋一下:

??? 在該方法中,返回一個(gè)Cursor游標(biāo)對(duì)象。而Cursor中是單條的記錄還是一個(gè)集合,需要和在getType()方法中返回的類型保持一致。當(dāng)返回的MIME類型是Shopping.CONTENT_ITEM時(shí),Cursor應(yīng)該是一個(gè)集合;當(dāng)返回的MIME類型是Shopping.CONTENT_ITEM_TYPE時(shí),Cursor應(yīng)該是單條記錄。

??? 由于在getType()方法里面,我們顯示的返回了android平臺(tái)可以識(shí)別的MIME類型,所以在執(zhí)行query()方法返回Cursor對(duì)象的時(shí)候,系統(tǒng)將不需要再進(jìn)行驗(yàn)證,從而可以說(shuō)是節(jié)省了系統(tǒng)開(kāi)銷。

?

????話已至此,那么何謂android平臺(tái)可以識(shí)別的MIME類型呢?下面來(lái)分析一下MIME類型的結(jié)構(gòu):

????其實(shí),MIME類型其實(shí)就是一個(gè)字符串,中間有一個(gè) “/” 來(lái)隔開(kāi),“/”前面的部分是系統(tǒng)識(shí)別的部分,就相當(dāng)于我們定義一個(gè)變量時(shí)的變量數(shù)據(jù)類型,通過(guò)這個(gè)“數(shù)據(jù)類型”,系統(tǒng)能夠知道我們所要表示的是個(gè)什么東西。至于 “/” 后面的部分就是我們自已來(lái)隨便定義的“變量名”了。

????那么,既然MIME類型就是一個(gè)字符串,那么我們的getType()自然也可以隨便返回一個(gè)系統(tǒng)不能識(shí)別的字符串啦?沒(méi)錯(cuò),有些時(shí)候我們確實(shí)也這樣處理,比如說(shuō)可以這樣寫:

?

public String getType(Uri uri) {

return getContext().getPackageName();?

}

?

??? 這里,我們把當(dāng)前上下文的包名返回了。這樣處理的結(jié)果是怎樣的呢?

?

??? 簡(jiǎn)單的說(shuō),系統(tǒng)不能夠識(shí)別它了,也就不會(huì)做任何處理。仍然以query()方法來(lái)說(shuō),當(dāng)執(zhí)行完方法體(這里需要注意一下:在這種情況下,即使我們沒(méi)有通過(guò)返回MIME類型字符串來(lái)進(jìn)行驗(yàn)證處理,但是在query()方法中再次對(duì)Uri進(jìn)行了匹配并根據(jù)不同的Uri類型進(jìn)行了不同的操作)返回Cursor對(duì)象的時(shí)候,這時(shí)候系統(tǒng)不能肯定返回的Cursor對(duì)象是否合法,因此需要對(duì)其進(jìn)行驗(yàn)證,這樣對(duì)系統(tǒng)資源算是一個(gè)浪費(fèi)了吧。所以,我們最好還是顯示的返回一個(gè)MIME類型吧,當(dāng)然要寫正確了,讓我們android平臺(tái)可以識(shí)別。

sourceurl:http://blog.csdn.net/h3g2010/article/details/6093366


第二個(gè)版本

在Android中,每個(gè)程序都在自己的進(jìn)程中運(yùn)行,互不干擾.這樣的好處不說(shuō)了,但是帶來(lái)的問(wèn)題就是想要在程序之間實(shí)現(xiàn)數(shù)據(jù)共享,在沒(méi)有其它工具的幫助下,就難以實(shí)現(xiàn)了.為了解決這個(gè)問(wèn)題,ContentProvider就派上用場(chǎng)了.

一,說(shuō)說(shuō)ContentProvider怎么用.


???1,把你想要共享出去的數(shù)據(jù)用一個(gè)URl表示出來(lái).如:content://contacts/people/5(聯(lián)系人信息中Id位5的聯(lián)系人記錄).或者這樣也行:Uri person =ContentUris.withAppendedId(People.CONTENT_URI,5);來(lái)封裝.

?? 2,所有的Content Providers都會(huì)實(shí)現(xiàn)一些共同的接口,可以通過(guò)唯一的ContentResolveer來(lái)向外提供數(shù)據(jù),冰進(jìn)行一系列的增刪改查;ContentResolver cr = getContentResplver();

?? 3,cr利用定義好的uri(作為參數(shù)送給cr封裝好的方法里面進(jìn)行一系列的操作);

至于ContentProvider的實(shí)例化,這些不需要我們?nèi)プ?系統(tǒng)會(huì)做這件事.對(duì)于ContentProvider,正常情況下,只需一個(gè),但是ContentResolver可以存在多個(gè),在不同進(jìn)程中的

ContentResolver可以使用同一個(gè)ContentProvider.


二,定義自己的ContentProvider

??? 根據(jù)我個(gè)人的理解,這作用就有點(diǎn)像J2EE里面的DAO的作用.
?? ?
??? 1,實(shí)現(xiàn)一個(gè)定義節(jié)本字段的類.示例如下:
???????? ?
???????? ?
? 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類型-多個(gè)
?? ??? ?public static final String?? ?CONTENT_TYPE?? ??? ?= "vnd.android.cursor.dir/vnd.google.note";

?? ??? ?// 新的MIME類型-單個(gè)
?? ??? ?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類型,假如你要處理的數(shù)據(jù)類型是新的類型,就得定義一個(gè)新的MIME類型,一邊ContentProvider.getType(url)來(lái)調(diào)用;
?粉單個(gè)與多個(gè);

?
?2,創(chuàng)建自己的ContentProvider
???? ?
????如果要共享的是數(shù)據(jù)庫(kù),我們?cè)谶@里可以封裝一個(gè)SqlLiteOpenHelper,以便建庫(kù)建表 ,對(duì)于 SqlLiteOpenHelper 用過(guò)數(shù)據(jù)庫(kù)的人應(yīng)該都懂,在這里就不贅述了;
?? ?
??? 然后在ContentProvider里面實(shí)現(xiàn)增刪改查,另外如果有自定義類型的話,還的在ContentProvider劉main實(shí)現(xiàn)一個(gè)方法?? ?
?? ??? ?
?? ?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);
?? ??? ?}
?? ?}
?
?實(shí)例如下:
?
???? public class NotePadProvider extends ContentProvider
{
?? ?private static final String?? ??? ??? ??? ?TAG?? ??? ??? ??? ??? ?= "NotePadProvider";
?? ?// 數(shù)據(jù)庫(kù)名
?? ?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;
?? ?//創(chuàng)建表SQL語(yǔ)句
?? ?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
?? ?{
?? ??? ?//構(gòu)造函數(shù)-創(chuàng)建數(shù)據(jù)庫(kù)
?? ??? ?DatabaseHelper(Context context)
?? ??? ?{
?? ??? ??? ?super(context, DATABASE_NAME, null, DATABASE_VERSION);
?? ??? ?}
?? ??? ?//創(chuàng)建表
?? ??? ?@Override
?? ??? ?public void onCreate(SQLiteDatabase db)
?? ??? ?{
?? ??? ??? ?db.execSQL(CREATE_TABLE);
?? ??? ?}
?? ??? ?//更新數(shù)據(jù)庫(kù)
?? ??? ?@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
?? ?// 如果有自定義類型,必須實(shí)現(xiàn)該方法
?? ?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
?? ?//插入數(shù)據(jù)庫(kù)
?? ?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
?? ?//刪除數(shù)據(jù)
?? ?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
?? ?//更新數(shù)據(jù)
?? ?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;
?? ?}
}



這樣我們就實(shí)現(xiàn)了一個(gè)自定義的ContentProvider,檔然最后不要忘記一件事情了,在AndroidMinifest.xml中聲明我們定義好的ContentProvider

??? <provider android:name="NotePadProvider"?
??? android:authorities="com.google.provider.NotePad"/>
?? ?
好了,一切OK!

總結(jié)

以上是生活随笔為你收集整理的Android之自定义ContentProvider详解的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。