淺談Android Content Provider的使用
Content Provider:一個(gè)組件,必須放在應(yīng)用的主包或應(yīng)用的子包之下;
組件的配置需要在清單文件中進(jìn)行配置;content provider需要在application節(jié)點(diǎn)中進(jìn)行配置;
內(nèi)容提供者在應(yīng)用中的作用是對(duì)外共享數(shù)據(jù)(任意類(lèi)型的數(shù)據(jù))使用的,別的程序可以對(duì)數(shù)據(jù)進(jìn)行CRUD,如通訊錄;
如果采用文件的方式對(duì)外共享數(shù)據(jù),會(huì)因?yàn)槲募念?lèi)型不同而需要使用不同的api訪問(wèn)方式導(dǎo)致訪問(wèn)繁雜,而內(nèi)容提供者提供了統(tǒng)一的api對(duì)數(shù)據(jù)進(jìn)行操作;
<provider
android:name=".PersonProvider"<!-- 內(nèi)容提供者類(lèi)的名稱(chēng) -->
android:authorities="cn.wordtech.providers.personprovider"
android:exported="false" ><!-- 解決 android Permission Denial error!,在監(jiān)聽(tīng)內(nèi)容提供者數(shù)據(jù)發(fā)生變化時(shí)需要配置此項(xiàng) -->
</provider>
另:
android:authorities:為內(nèi)容提供者指定一個(gè)唯一的標(biāo)識(shí),這樣別的應(yīng)用才可以唯一獲取此provider;
Uri 代表了要操作的數(shù)據(jù);
Uri主要包含兩部分的信息:1>>需要操作的ContentProvider,2>>對(duì)ContentProvider中的什么數(shù)據(jù)進(jìn)行操作
ContentProvider(內(nèi)容提供者)的scheme已經(jīng)由Android所規(guī)定,scheme為:content://
主機(jī)名(或Authority)用于唯一標(biāo)識(shí)這個(gè)ContentProvider,外部調(diào)用者可以根據(jù)此標(biāo)識(shí)來(lái)找到它,
路徑(path)可以用來(lái)表示我們要操作的數(shù)據(jù),路徑的構(gòu)建根據(jù)業(yè)務(wù)而定。
ex:
要操作person表中id為10的記錄,可以構(gòu)建這樣的路徑:/person/10
要操作person表中id為10的記錄的name字段,可以構(gòu)建這樣的路徑:/person/10/name
要操作person表中的所有記錄,可以構(gòu)建這樣的路徑:/person
要操作XXX表中的記錄,可以構(gòu)建這樣的路徑:/XXX
要操作的數(shù)據(jù)不一定是數(shù)據(jù)庫(kù)中的文件,也可以是文件,xml或網(wǎng)絡(luò)等其它方式
ex:
要操作xml文件中person節(jié)點(diǎn)下的name節(jié)點(diǎn),可以構(gòu)建這樣的路徑:/person/name
public class PersonProvider extends ContentProvider {// Content Provider需要繼承自ContentProvider類(lèi)
// 刪改查中,都有兩種情況:
// person 對(duì)整個(gè)表進(jìn)行操作
// person/id 對(duì)表中的與id對(duì)應(yīng)記錄進(jìn)行操作
private DBOpenHelper dbOpenHelper;
private static final UriMatcher MATCHER = new UriMatcher(UriMatcher.NO_MATCH);// new UriMatcher(code);code即為匹配不成功時(shí)返回的值;
private static final int PERSONS = 1;
private static final int PERSON = 2;
// 設(shè)置匹配項(xiàng)
static {
MATCHER.addURI("cn.wordtech.providers.personprovider", "person",PERSONS);
MATCHER.addURI("cn.wordtech.providers.personprovider", "person/#",PERSON);// #號(hào)表示數(shù)字
}
// content://cn.wordtech.providers.personprovider/person
@Override
public boolean onCreate() {
// 由系統(tǒng)調(diào)用,當(dāng)ContentProvider的實(shí)例被創(chuàng)建出來(lái)的時(shí)候被調(diào)用,Android開(kāi)機(jī)后,當(dāng)?shù)谝淮斡袘?yīng)用訪問(wèn)ContentProvider時(shí)才創(chuàng)建ContentProvider;
dbOpenHelper = new DBOpenHelper(getContext(), 1);
return false;
}
// 可以供外部的應(yīng)用查詢(xún)數(shù)據(jù),返回查詢(xún)得到的游標(biāo)對(duì)象
@Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
SQLiteDatabase db = dbOpenHelper.getWritableDatabase();
switch (MATCHER.match(uri)) {
case 1:
return db.query("person", projection, selection, selectionArgs,
null, null, sortOrder);
case 2:
long rowid = ContentUris.parseId(uri);// 返回要操作的id
String where = "personid=" + rowid;
if (selection != null && !"".equals(selection.trim())) {
where += "and" + selection;
}
return db.query("person", projection, where, selectionArgs, null,
null, sortOrder);
default:
throw new IllegalArgumentException("");
}
}
// 此方法用于返回目前Uri所代表的數(shù)據(jù)的MIME類(lèi)型,
// 如果操作的數(shù)據(jù)屬于集合類(lèi)型,則MIME字符串就以"vnd.android.cursor.dir"開(kāi)頭
// 如果操作的數(shù)據(jù)屬于非集合類(lèi)型,則MIME字符串就以"vnd.android.cursor.item"開(kāi)頭
@Override
public String getType(Uri uri) {
switch (MATCHER.match(uri)) {
case 1:
return "vnd.android.cursor.dir/person";
case 2:
return "vnd.android.cursor.item/person";
default:
throw new IllegalArgumentException("");
}
}
// 此方法需要返回操作記錄對(duì)應(yīng)的Uri
@Override
public Uri insert(Uri uri, ContentValues values) {
SQLiteDatabase db = dbOpenHelper.getWritableDatabase();
switch (MATCHER.match(uri)) {
case 1:
long rowid = db.insert("person", "", values);// 返回行號(hào)?主鍵值
// Uri insertUri = Uri
// .parse("content://com.sqlite.PersonProvider/person/"
// + rowid);
Uri insertUri = ContentUris.withAppendedId(uri, rowid);
return insertUri;
default:
throw new IllegalArgumentException("this is Unknow Uri:" + uri);
}
}
// 返回受影響的行數(shù)
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
SQLiteDatabase db = dbOpenHelper.getWritableDatabase();
int num = 0;
switch (MATCHER.match(uri)) {
case 1:
num = db.delete("person", selection, selectionArgs);// 清空整個(gè)表
break;
case 2:
long rowid = ContentUris.parseId(uri);// 返回要操作的id
String where = "personid=" + rowid;
if (selection != null && !"".equals(selection.trim())) {
where += "and" + selection;
}
num = db.delete("person", where, selectionArgs);
break;
default:
throw new IllegalArgumentException("");
}
return num;
}
@Override // 返回受影響的行數(shù)
public int update(Uri uri, ContentValues values, String selection,String[] selectionArgs) {
SQLiteDatabase db = dbOpenHelper.getWritableDatabase();
int num = 0;
switch (MATCHER.match(uri)) {
case 1:
num = db.update("person", values, selection, selectionArgs);
break;
case 2:
long rowid = ContentUris.parseId(uri);// 返回要操作的id
String where = "personid=" + rowid;
if (selection != null && !"".equals(selection.trim())) {
where += "and" + selection;
}
num = db.update("person", values, where, selectionArgs);
break;
default:
throw new IllegalArgumentException("");
}
return num;
}
}
下面是對(duì)前一個(gè)類(lèi)進(jìn)行測(cè)試
public class AccessContentProviderTest extends AndroidTestCase {
public void testinsert() {
Uri uri = Uri.parse("content://cn.wordtech.providers.personprovider/person");// 根據(jù)標(biāo)識(shí)名得到內(nèi)容提供者
ContentResolver cr = this.getContext().getContentResolver(); // This class provides applications access to the content model
ContentValues values = new ContentValues();
values.put("name", "Livingstone");
values.put("phone", "110");
values.put("amount", "1111111111");
cr.insert(uri, values);// 在cr的內(nèi)部會(huì)調(diào)用內(nèi)容提供者的值;
}
public void testdelete() {
Uri uri = Uri.parse("content://cn.wordtech.providers.personprovider/person/1");// 根據(jù)標(biāo)識(shí)名得到內(nèi)容提供者
ContentResolver cr = this.getContext().getContentResolver();
cr.delete(uri, null, null);
}
public void testupdate() {
Uri uri = Uri.parse("content://cn.wordtech.providers.personprovider/person/2");// 根據(jù)標(biāo)識(shí)名得到內(nèi)容提供者
ContentResolver cr = this.getContext().getContentResolver();
ContentValues values = new ContentValues();
values.put("name", "Livingstone11");
cr.update(uri, values, null, null);
}
public void testquery() {
Uri uri = Uri.parse("content://cn.wordtech.providers.personprovider/person");// 根據(jù)標(biāo)識(shí)名得到內(nèi)容提供者
ContentResolver cr = this.getContext().getContentResolver();
Cursor cursor = cr.query(uri, null, null, null, "personid asc");
while (cursor.moveToNext()) {
String name = cursor.getString(cursor.getColumnIndex("name"));
Log.i("Name", name);
}
}
}
- Android開(kāi)發(fā)之ContentProvider的使用詳解
- Android中自定義ContentProvider實(shí)例
- 基于Android 監(jiān)聽(tīng)ContentProvider 中數(shù)據(jù)變化的相關(guān)介紹
- 實(shí)例講解Android中ContentProvider組件的使用方法
- 基于Android ContentProvider的總結(jié)詳解
- Android中自定義ContentProvider實(shí)例
- Android應(yīng)用中使用ContentProvider掃描本地圖片并顯示
- 深入U(xiǎn)nderstanding Android ContentProvider詳解
- Android內(nèi)容提供者ContentProvider用法實(shí)例分析
- Android組件content provider使用解析
相關(guān)文章
Android中使用RecylerView實(shí)現(xiàn)聊天框效果
這篇文章主要介紹了Android中使用RecylerView實(shí)現(xiàn)聊天框效果,本文通過(guò)示例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2018-08-08
Android編程之監(jiān)聽(tīng)器用法實(shí)例分析
這篇文章主要介紹了Android編程之監(jiān)聽(tīng)器用法,結(jié)合實(shí)例形式較為詳細(xì)的分析了Android監(jiān)聽(tīng)器的功能及針對(duì)短信的監(jiān)聽(tīng)與響應(yīng)操作技巧,需要的朋友可以參考下2016-01-01
Android基于socket實(shí)現(xiàn)的簡(jiǎn)單C/S聊天通信功能
這篇文章主要介紹了Android基于socket實(shí)現(xiàn)的簡(jiǎn)單C/S聊天通信功能,結(jié)合實(shí)例形式分析了Android使用socket實(shí)現(xiàn)客服端與服務(wù)器端數(shù)據(jù)的發(fā)送與接收處理技巧,需要的朋友可以參考下2016-10-10
Android中Toolbar隨著ScrollView滑動(dòng)透明度漸變效果實(shí)現(xiàn)
這篇文章主要介紹了Android中Toolbar隨著ScrollView滑動(dòng)透明度漸變效果實(shí)現(xiàn),非常不錯(cuò),具有參考借鑒價(jià)值,需要的的朋友參考下2017-01-01
Android Studio 新手入門(mén)教程(一)基本設(shè)置圖解
這篇文章主要介紹了Android Studio 新手入門(mén)教程(一)基本設(shè)置圖解,需要的朋友可以參考下2017-12-12
android dialog邊框去除白色邊框?qū)崿F(xiàn)思路及代碼
android dialog邊框含有白色真是美中不足啊,本文將介紹如何去除白色邊框,有思路及代碼,感興趣的朋友可以了解下2013-01-01
Retrofit自定義請(qǐng)求參數(shù)注解的實(shí)現(xiàn)思路
這篇文章主要給大家介紹了Retrofit自定義請(qǐng)求參數(shù)注解的實(shí)現(xiàn)思路,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2018-12-12

