Android開發(fā)學(xué)習(xí)教程(32)- Android ContentResolver使用教程
—— 星光不問趕路人,時光不負(fù)有心人。
ContentProvider 幫助android:屬性與 ContentProvider ID 相同。在其他應(yīng)用中搜索我的應(yīng)用的Provider時需要知道provider
????
android:name
=
".SampleContentProvider"
????
android:authorities
=
"example.<a href="https://yunjunet.cn/tag/contentprovidersample" contentprovidersample"target="_blank" style="color: rgb(102, 102, 102); cursor: pointer; transition: all 0.3s ease 0s;">contentprovidersample.provider"
????
android:exported
=
"true"
????
android:<a href="https://yunjunet.cn/tag/permission" permission"target="_blank" style="color: rgb(102, 102, 102); cursor: pointer; transition: all 0.3s ease 0s;">permission
=
"com.example.<a href="https://yunjunet.cn/tag/contentprovider" contentprovider"target="_blank" style="color: rgb(102, 102, 102); cursor: pointer; transition: all 0.3s ease 0s;">contentprovidersample.provider.READ_WRITE"
????
android:readPermission
=
"com.harvic.contentProviderBlog.READ"
????
android:writePermission
=
"com.harvic.cotentProviderBlog.WRITE"
/>
android:permission:應(yīng)用程序讀、寫 ContentProvider 中的數(shù)據(jù)所必需的權(quán)限名稱。 本屬性為一次性<a href="https://yunjunet.cn/tag/%e8%ae%be%e7%bd%ae" 設(shè)置"target="_blank" style="color: rgb(102, 102, 102); cursor: pointer; transition: all 0.3s ease 0s;">設(shè)置讀和寫權(quán)限提供了快捷途徑。 不過,readPermission和writePermission屬性優(yōu)先于本設(shè)置。 如果同時設(shè)置了readPermission屬性,則其將控制對 Content Provider 的讀取。 如果設(shè)置了writePermission屬性,則其也將控制對 Content Provider 數(shù)據(jù)的修改。也就是說如果只設(shè)置permission權(quán)限,那么擁有這個權(quán)限的應(yīng)用就可以實現(xiàn)對這里的ContentProvider進(jìn)行讀寫;如果同時設(shè)置了permission和readPermission那么具有readPermission權(quán)限的應(yīng)用才可以讀,擁有permission權(quán)限的才能寫!也就是說只擁有permission權(quán)限是不能讀的,因為readPermission的優(yōu)先級要高于permission;如果同時設(shè)置了readPermission、writePermission、permission那么permission就無效了。
ContentProvider方法
ContentProvider 提供查詢、插入、更新或刪除等 API 以及數(shù)據(jù)庫。如果您知道 Provider 的授權(quán),您的應(yīng)用可以使用 ContentProvider 訪問 Provider。
查詢
首先,您可以創(chuàng)建一個具有權(quán)限的 Uri,并將此 Uri 作為參數(shù)傳遞給 ContentResolver 以進(jìn)行查詢。查詢API 的使用類似于 SQLite 等數(shù)據(jù)庫。您可以設(shè)置查詢等操作來找到您需要的數(shù)據(jù)。然后,您可以通過返回的 Cursor 對象讀取數(shù)據(jù)。
String table_name =?
"cheeses"
;
String authority =?
"com.example.contentprovidersample.provider"
;
Uri uri = Uri.parse(
"content://"
?+ authority +?
"/"
?+ table_name);
Cursor cursor = getContentResolver().query(
????????????????????
uri,??
// uri
????????????????????
null
,?
// projection
????????????????????
null
,?
// selection
????????????????????
null
,?
// selectionArgs
????????????????????
"id"
?// sortOrder
????????????????
);
if
(cursor!=
null
)
{
????
cursor.moveToFirst();
????
do
{
????????
int
?idIndex= cursor.getColumnIndex(
"id"
);
????????
int
?id= cursor.getInt(idIndex);
????????
int
?nameIndex= cursor.getColumnIndex(
"name"
);
????????
String name= cursor.getString(nameIndex);
????
}
while
(cursor.moveToNext());
}
一個Uri由以下幾部分組成:
Authority:授權(quán)信息,用以區(qū)別不同的ContentProvider;
Path:表名,用以區(qū)分ContentProvider中不同的數(shù)據(jù)表;
Id:Id號,用以區(qū)別表中的不同數(shù)據(jù);
如以上例子中的URI_CHEESE就表示cheeses這張表,如果改成
int
?ID =?
5
;
Uri URI_CHEESE_ITEM = Uri.parse(
"content://"
?+ authority +?
"/"
?+ table_name +?
"/"
?+ ID);
就表示cheeses這張表中的id為5的這條數(shù)據(jù)。所以上面例子就表示使用query方法查詢cheeses這張表并返回游標(biāo)Cursor,query方法有五個參數(shù):
第一個參數(shù)uri:可以理解為作為標(biāo)識是操作哪個ContentProvider,uri也可以理解為是ContentProvider的具體
"路徑"
,如上面例子中的
"路徑"
就表示是cheeses表;
第二個參數(shù)projection:查詢cheeses表哪幾列數(shù)據(jù),
null
表示查詢所有列;
第三個參數(shù)selection:查詢條件,建議使用占位符,為
null
是沒有查詢條件,即查詢?nèi)?;(什么是占位符?見上一篇文章SQLite使用教程)
第四個參數(shù)selectionArgs:查詢條件的值,與第三個參數(shù)selection搭配使用;
第五個參數(shù)sortOrder:查詢按某列排序,如上面例子中是按ID升序排列,也可以寫成
"id ASC"
,降序就是
"id DESC"
;
插入
Uri contentUri = Uri.parse(
"content://"
?+ authority +?
"/"
?+ table_name);
ContentValues contentValues =?
new
?ContentValues();
contentValues.put(
"name"
,?
"張三"
);
contentValues.put(
"email"
,?
"123@qq.com"
);
getContentResolver().insert(contentUri, contentValues);
更新
Uri contentUri = Uri.parse(
"content://"
?+ authority +?
"/"
?+ table_name);
ContentValues contentValues =?
new
?ContentValues();
contentValues.put(
"name"
,?
"張三"
);
contentValues.put(
"email"
,?
"123@qq.com"
);
String whereClause =?
"id = ?"
;
String placeHolderValueArr[] = {
"1"
};
getContentResolver().update(contentUri, contentValues, whereClause , placeHolderValueArr);
刪除
Uri contentUri = Uri.parse(
"content://"
?+ authority +?
"/"
?+ table_name);
String whereClause =?
"id = ?"
;
String placeHolderValueArr[] = {
"1"
}
getContentResolver().delete(contentUri, whereClause , placeHolderValueArr);
異步操作
在Activity和Fragment中可以使用LoaderManager和CursorLoader異步訪問ContentProvider。當(dāng)LoaderManager獲取到Provider的所有數(shù)據(jù)后,會通過LoaderCallbacks進(jìn)行回調(diào)。當(dāng) Provider 數(shù)據(jù)由于添加、刪除、更新等發(fā)生變化時,它也會回調(diào)。