




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認(rèn)領(lǐng)
文檔簡介
Android應(yīng)用程序開發(fā)技術(shù)第8章ContentProvider數(shù)據(jù)共享為了更加安全便捷的在不同應(yīng)用之間共享數(shù)據(jù),Android提供了ContentProvider組件,它是不同應(yīng)用程序之間進行數(shù)據(jù)交換的標(biāo)準(zhǔn)API,當(dāng)一個應(yīng)用中的數(shù)據(jù)被其他應(yīng)用所需要的時候,該應(yīng)用就可以提供ContentProvider暴露自己的數(shù)據(jù),其他應(yīng)用程序可以通過ContentResolver來操作ContentProvider暴露的數(shù)據(jù),包括增加數(shù)據(jù)、刪除數(shù)據(jù)、修改數(shù)據(jù)、查詢數(shù)據(jù)等。Android內(nèi)置的許多數(shù)據(jù)都是使用ContentProvider形式,供開發(fā)者調(diào)用(如視頻,音頻,圖片,通訊錄等)。章節(jié)概述8.1ContentProvider簡介8.2
開發(fā)ContentProvider程序8.3
本章總結(jié)8.4
習(xí)題8.5上機目
錄ContentProvider可以選擇對部分?jǐn)?shù)據(jù)進行分享,保證數(shù)據(jù)安全,是Android提供的四大組件之一,主要用于不同應(yīng)用程序之間實現(xiàn)數(shù)據(jù)共享。ContentProvider以Uri的形式對外提供數(shù)據(jù),允許其他應(yīng)用訪問和修改數(shù)據(jù);其它應(yīng)用使用ContentResolver根據(jù)Uri進行訪問操作指定的數(shù)據(jù)。ContentProvider內(nèi)部保存數(shù)據(jù)的方式由其設(shè)計者決定。所有的ContentProvider都實現(xiàn)一組通用的方法用來提供數(shù)據(jù)的增、刪、改、查功能??蛻舳送ǔ2粫苯邮褂眠@些方法,大多數(shù)是通過ContentResolver對象實現(xiàn)對ContentProvider的操作。開發(fā)人員可以通過調(diào)用Activity或者其它應(yīng)用程序組件的實現(xiàn)類中,getContentResolver()方法來獲得ContentResolver對象,例如:ContentResolvercr=getContentResolver();使用ContentResolver提供的方法可以獲得ContentProvider中任何感興趣的數(shù)據(jù)。8.1ContentProvider簡介
8.1.1ContentProvider基本概念組織數(shù)據(jù)方式ContentProvider向其它應(yīng)用提供數(shù)據(jù)有兩種基本形式:文件形式和表格形式。在需要對大量的數(shù)據(jù)進行修改和查詢操作時,將數(shù)據(jù)以一個表或多個表(與在關(guān)系型數(shù)據(jù)庫中的表類似)的形式呈現(xiàn)給外部應(yīng)用更加便于操作。其中,每一行表示一條記錄,而每一列代表特定類型和含義的數(shù)據(jù),并且其中每一條數(shù)據(jù)記錄都包含一個名為“_ID”的字段類標(biāo)識每條數(shù)據(jù)?!纠柯?lián)系人的信息可以如下表所示。每條記錄包含一個數(shù)值型的_ID字段,用于在表格中唯一標(biāo)識該記錄。ID能用于匹配相關(guān)表格中的記錄,例如,在一個表格中查詢聯(lián)系人的電話,在另一表格中查詢其照片。_IDNAMENUMBEREMAIL001張××123*****123**@002王××134*****134**@003李××145*****145***@004趙××156*****156***@8.1.1ContentProvider基本概念組織數(shù)據(jù)方式8.1.1ContentProvider基本概念URI統(tǒng)一資源標(biāo)識符(UniformResourceIdentifier,URI)是一個用于標(biāo)識某一互聯(lián)網(wǎng)資源名稱的字符串。該種標(biāo)識允許用戶對任何(包括本地和互聯(lián)網(wǎng))的資源通過特定的協(xié)議進行交互操作。ContentProvider提供公共的URI來唯一標(biāo)識其數(shù)據(jù)集。管理多個數(shù)據(jù)集的ContentProvider為每個數(shù)據(jù)集提供了單獨的URI。URI主要包含兩部分信息:需要操作的ContentProvider和ContentProvider中需要進行操作的數(shù)據(jù)。8.1.1ContentProvider基本概念URI一個URI由以下幾部分組成:自定義URI=content://vider/User/ID主題名授權(quán)信息表名記錄主題名(Schema):用于標(biāo)識該數(shù)據(jù)由ContentProvider管理,無需修改。授權(quán)信息(authority):URI的authority部分,ContentProvider的唯一標(biāo)識符,外部調(diào)用者可以根據(jù)這個標(biāo)識來找到它。表名(Path):ContentProvider的路徑部分,用于決定哪類數(shù)據(jù)被請求。如果ContentProvider提供一種數(shù)據(jù)類型,可以省略該部分;如果提供幾種類型,包括子類型,這部分可以由幾部分組成。記錄(ID):被請求記錄的ID值。若無指定,則返回全部記錄。8.1.1ContentProvider基本概念URI【例】
1.//設(shè)置URI2.Uriuri=Uri.parse("content://vider/User/1")3.//上述URI指向的資源是:名為`vider`的`ContentProvider`中表名
為`User`中的`id`為1的數(shù)據(jù)4.//特別注意:URI模式存在匹配通配符*&#5.//*:匹配任意長度的任何有效字符的字符串6.//以下的URI表示
匹配provider的任何內(nèi)容7.content://vider/*8.//#:匹配任意長度的數(shù)字字符的字符串9.//以下的URI表示
匹配provider中的table表的所有行10.content://vider/table/#8.1.1ContentProvider基本概念URI通常解析URI使用Android系統(tǒng)提供的操作URI工具類:UriMatcher。UriMatcher類用來匹配URI,對匹配結(jié)果返回對應(yīng)的匹配碼。UriMatcher使用addURI()方法注冊需要匹配的URI。addURI()方法原型是:publicvoidaddURI(Stringauthority,Stringpath,intcode)注冊完成之后可以使用UriMatcher類的match()方法匹配URI,如果匹配成功就返回相應(yīng)的匹配碼,匹配碼是使用addURI()注冊URI時傳入的第3個參數(shù),注冊時傳入的匹配碼需要唯一。8.1.1ContentProvider基本概念URI【例】1.publicstaticfinalintBOOK_DIR=0;2.publicstaticfinalintBOOK_ITEM=1;3.//第一步,初始化4.UriMatchermatcher=newUriMatcher(UriMatcher.NO_MATCH);5.//第二步,注冊待匹配的Uri6.matcher.addURI(AUTHORITY,"book",BOOK_DIR);7.matcher.addURI(AUTHORITY,"book/#",BOOK_ITEM);8.//第三步,進行匹配9.Uriuri=Uri.parse("content://"+"com.example.yy"+"/book");10.intmatch=matcher.match(uri);11.switch(match){12.caseBOOK_DIR:13.return"vnd.android.cursor.dir/book";14.caseBOOK_ITEM:15.return"vnd.android.cursor.item/book";16.default:17.returnnull;18.}//上面返回的是Uri對應(yīng)的MIME8.1.1ContentProvider基本概念URI操作URI的工具類還有一個ContentUris類,用于操作UriURI路徑后面的Id。ContentUris處理URI有兩個作用:為路徑加上ID和從URI路徑中獲取ID。8.1.1ContentProvider基本概念URI具體代碼如下。為URI路徑加上ID:withAppendedId(uri,id);19.//比如有這樣一個URI20.Uriuri=Uri.parse("content://com.example.yy/book");21.22.//通過ContentUris的withAppendedId()方法,為該Uri加上ID23.UriresultUri=ContentUris.withAppendedId(uri,10);24.//最后resultUri為:25.//content://com.example.yy/book/1026.從Uri路徑中獲取ID—parseId(uri);27.Uriuri=Uri.parse("content://com.example.yy/book/10")28.longbookId=ContentUris.parseId(uri);
8.1.1ContentProvider基本概念URIAndroid系統(tǒng)提供了一些定義好的URI。例如,手機短信的信息、圖庫數(shù)據(jù)、聯(lián)系人信息等操作系統(tǒng)均提供相應(yīng)的URI。知道對應(yīng)的URI后,就可以通過ContentResolver對象,根據(jù)URI進行數(shù)據(jù)訪問。Android系統(tǒng)用于管理聯(lián)系人的ContentProvider的幾個URI如下:ContactsContract.Contacts.CONTENT_URI:管理聯(lián)系人的URI。ContactsContract.CommonDataKinds.Phone.CONTENT_URI:管理聯(lián)系人電話的URI。ContactsContract.CommonDataKinds.Email.CONTENT_URI:管理聯(lián)系人E-mail的URI。8.1.1ContentProvider基本概念URIAndroid系統(tǒng)用于管理多媒體的ContentProvider的幾個URI如下:MediaStore.Audio.Media.EXTERNAL_CONTENT_URI:存儲在外部存儲器(SD卡)上的音頻文件內(nèi)容的ContentProvider的URI。MediaStore.Audio.Media.INTERNAL_CONTENT_URI:存儲在手機內(nèi)部存儲器上的音頻文件內(nèi)容的ContentProvider的URI。MediaStore.Images.Media.EXTERNAL_CONTENT_URI:存儲在外部存儲器(SD卡)上的圖片文件內(nèi)容的ContentProvider的URI。MediaStore.Images.Media.INTERNAL_CONTENT_URI:存儲在手機內(nèi)部存儲器上的圖片文件內(nèi)容的ContentProvider的URI。MediaStore.Video.Media.EXTERNAL_CONTENT_URI:存儲在外部存儲器(SD卡)上的視頻文件內(nèi)容的ContentProvider的URI。MediaStore.Video.Media.INTERNAL_CONTENT_URI:存儲在手機內(nèi)部存儲器上的視頻文件內(nèi)容的ContentProvider的URI。8.1.1ContentProvider基本概念.MIME數(shù)據(jù)類型多功能Internet郵件擴充服務(wù)(MIME:MultipurposeInternetMailExtensions)是一種多用途網(wǎng)際郵件擴充協(xié)議。該服務(wù)于1992年最早應(yīng)用于電子郵件系統(tǒng),后來也應(yīng)用到瀏覽器。MIME類型就是設(shè)定某種擴展名的文件用一種應(yīng)用程序來打開的方式類型。當(dāng)該擴展名文件被訪問的時候,瀏覽器會自動使用指定應(yīng)用程序打開,多用于指定一些客戶端自定義的文件名,以及一些媒體文件打開方式。在Android中MIME數(shù)據(jù)類型的作用是指定應(yīng)用程序打開特定擴展名的文件。URI里面提供給provider所支持的MIME數(shù)據(jù)類型,provider根據(jù)web中MIME標(biāo)準(zhǔn)返回一個由兩個字符串組成的MIME類型識別。8.1.1ContentProvider基本概念.MIME數(shù)據(jù)類型每種MIME數(shù)據(jù)類型由兩部分組成:一個類型和一個子類型。MIME類型是一個包含兩部分的字符串。這里有些熟知的MIME類型對:text/htmltext/csstext/xmltext/vnd.curl8.1.1ContentProvider基本概念.MIME數(shù)據(jù)類型MIME類型在Android里面得到了大規(guī)模的應(yīng)用,特別是在intent里,系統(tǒng)根據(jù)MIME數(shù)據(jù)的類型來決定調(diào)用哪個activity。MIME類型始終通過contentproviders繼承自它們的URIs。在使用MIME類型的時候要記住三點:基本類型和子類型代表的東西要唯一。如果是非標(biāo)準(zhǔn)的,專有的類型和子類型,前面需要加vnd。對于特定的需求,注意名字空間。在ContentProvider中使用getType()方法返回當(dāng)前Uri所代表數(shù)據(jù)的MIME類型。8.1.2ContentProvider常用操作ContentProvider類提供了以下六個方法:onCreate()方法:用來執(zhí)行一些初始化的工作query()方法:用來返回數(shù)據(jù)給調(diào)用者Insert()方法:用來插入新的數(shù)據(jù)update()方法:用來更新已有的數(shù)據(jù)delete()方法:用來刪除數(shù)據(jù)getType()方法:用來返回數(shù)據(jù)的MIME類型8.1.2ContentProvider常用操作onCreate()方法用來執(zhí)行一些初始化的工作。其函數(shù)原型為:publicbooleanonCreate()該方法在ContentProvider創(chuàng)建后被調(diào)用。onCreate()方法返回一個boolean類型的值,初始化操作成功時返回true,否則返回false,具體代碼如下所示。
1.onCreate()方法1.@Override
2.public
boolean
onCreate()
{
3.
//初始化數(shù)據(jù)庫
4.
String
sql
=
"create
table
if
not
exists
t1("
+
"id
integer
primary
key,
name
text,
phone
text);";5.//在content.db數(shù)據(jù)庫中創(chuàng)建t1表
6.
SQLiteDatabase
db
=
getContext().openOrCreateDatabase("content.db",
0,
null);
7.
db.execSQL(sql);
8.
db.close();
9.
return
true;
10.}
8.1.2ContentProvider常用操作2.query()方法query()方法用來返回數(shù)據(jù)給調(diào)用者。其函數(shù)原型為:publicCursorquery(Uriuri,String[]projection,Stringselection,String[]
selectionArgs,StringsortOrder)該方法用于供外部應(yīng)用從ContentProvider中獲取數(shù)據(jù)。根據(jù)Uri查詢出selection條件所匹配的全部記錄,其中projection表明選擇出指定的數(shù)據(jù)列,最終查詢結(jié)果保存在Cursor對象中并返回,具體代碼如下所示。1.@Override
2.public
Cursor
query(Uri
uri,
String[]
projection,
String
selection,
String[]
selectionArgs,
String
sortOrder)
{
3.
Cursor
result
=
null;
4.
SQLiteDatabase
db
=
getContext().openOrCreateDatabase("content.db",
0,
null);
5.
int
matchResult
=
matcher.match(uri);
6.
if
(matchReuslt
==
T1_DIR)
{
7.
result
=
db.query("t1",
projection,
selection,
selectionArgs,
null,
null,
sortOrder);
8.
}
9.
else
if(matchResult
==
T1_ITEM)
{
10.
String
id
=
uri.getPathSegments().get(1);
11.
result
=
db.query("t1",
projection,
"id
=
"
+
id,
null,
null,
null,
sortOrder);
12.
}
13.
return
result;
14.}
8.1.2ContentProvider常用操作3.Insert()方法Insert()方法用來插入新的數(shù)據(jù)。其函數(shù)原型為:publicUriinsert(Uri
uri,
ContenrValues
values)該方法用于供外部應(yīng)用往ContentProvider添加數(shù)據(jù)。該方法需要兩個參數(shù),第一個參數(shù)是使用資源的Uri對象,第二個參數(shù)為需要添加的數(shù)據(jù)。添加成功則返回新數(shù)據(jù)的Uri對象;操作失敗則返回null,具體代碼如下所示。1.@Override
2.public
Uri
insert(Uri
uri,
ContenrValues
values)
{
3.
int
matchResult
=
matcher.match(uri);
4.
if(matchResult
==
T1_DIR
||
matchResult
==
T1_ITEM)
{
5.
//插入數(shù)據(jù)并返回Uri
6.
SQLiteDatabase
db
=
getContext().openOrCreateDatabase("content.db",
0,
null);
7.
long
newId
=
db.insert("t1",
null,
values);
8.
db.close();
9.
return
Uri.parse("content://vider/t1/"
+
newId);
10.
}
11.
else
{
12.
return
null;
13.
}
14.}
8.1.2ContentProvider常用操作4.update()方法update()方法用來更新已有的數(shù)據(jù)。其函數(shù)原型為:publicintupdate(Uriuri,ContentValuesvalues,Stringselection,String[]selectionArgs)該方法用于供外部應(yīng)用更新ContentProvider中的數(shù)據(jù)。根據(jù)Uri修改selection條件所匹配的全部記錄,最終返回值表示更新操作影響的記錄數(shù)量,具體代碼如下所示。1.@Override
2.public
int
update(Uri
uri,
ContentValues
values,
String
selection,
String[]
selectionArgs)
{
3.
SQLiteDatabase
db
=
getContext().openOrCreateDatabase("content.db",
0,
null);
4.
int
result
=
0;
5.
int
matchResult
=
matcher.match(uri);
6.
if
(matchResult
==
T1_DIR)
{
7.
result
=
db.update("t1",
values,
selection,
selectionArgs);
8.
}
9.
else
if
(matchResult
==
T1_ITEM)
{
10.
String
id
=
uri.getPathSegments().get(1);
11.
result
=
db.update("t1",
values,
"id
=
"
+
id,
null);
12.
}
13.
db.close();
14.
return
result;
15.}
8.1.2ContentProvider常用操作5.delete()方法delete()方法用來刪除數(shù)據(jù)。其函數(shù)原型為:publicintdelete(Uri
uri,
String
selection,
String[]
selectionArgs)該方法用于供外部應(yīng)用從ContentProvider刪除數(shù)據(jù)。根據(jù)Uri刪除selection條件所匹配的全部記錄,具體代碼如下所示。1.@Override
2.public
int
delete(Uri
uri,
String
selection,
String[]
selectionArgs)
{
3.
SQLiteDatabase
db
=
getContext().openOrCreateDatabase("content.db",
0,
null);
4.
int
result
=
0;
5.
int
matchResult
=
matcher.match(uri);
6.
if
(matchResult
==
T1_DIR)
{
7.
result
=
db.delete("t1",
selection,
selectionArgs);
8.
}
9.
else
if
(matchResult
==
T1_ITEM)
{
10.
String
id
=
uri.getPathSegments().get(1);
11.
result
=
db.delete("t1",
"id
=
"
+
id,
null);
12.
}
13.
db.close();
14.
return
result;
15.}
8.1.2ContentProvider常用操作6.getType()方法getType()方法用來返回數(shù)據(jù)的MIME類型。其函數(shù)原型為:publicStringgetType(Uriuri)該方法用于返回當(dāng)前Uri所代表數(shù)據(jù)的MIME類型。如果該Uri對應(yīng)的數(shù)據(jù)可能包含多條記錄,那么MIME類型字符串應(yīng)該以vnd.android.cursor.dir/開頭;如果該Uri對應(yīng)的數(shù)據(jù)只包含一條記錄,那么MIME類型字符串應(yīng)該以vnd.android.cursor.item/開頭,具體代碼如下所示。1.@Override
2.public
String
getType(Uri
uri)
{
3.
int
matchResult
=
matcher.match(uri);
4.
if
(matchResult
==
T1_DIR)
{
5.
return
"vnd.android.cursor.dir/vider.t1";
6.
}
7.
else
if
(matchResult
==
T1_ITEM)
{
8.
return
"vnd.android.cursor.item/vider.t1";
9.
}
10.
else
{
11.
return
null;
12.
}
13.}
8.1.3ContentResolver常用操作如果訪問內(nèi)容提供器ContentProvider中的數(shù)據(jù),則需要使用ContentResolver類。ContentResolver類的功能就是通過標(biāo)準(zhǔn)接口統(tǒng)一管理不同
ContentProvider間的操作。該類實例可以通過Context的getContentResolver()方法獲得ContentResolver中提供了insert()、update()、delete()、query()等方法對數(shù)據(jù)進行CRUD操作。常見的,ContentProvider是單例模式的,當(dāng)多個應(yīng)用程序通過ContentResolver來操作ContentProvider提供的數(shù)據(jù)時,ContentResolver調(diào)用的數(shù)據(jù)操作將會委托給同一個ContentProvider處理。8.1.2ContentProvider常用操作1.insert()方法insert()方法用于向Uri對應(yīng)ContentProvider中插入對應(yīng)的數(shù)據(jù)。其函數(shù)原型為:publicUriinsert(Uriuri,ContentValuesvalues)1.//添加一條記錄2.ContentValuesvalues=newContentValues();3.values.put("name","itcast");4.values.put("age",25);5.resolver.insert(uri,values);13.
db.close();
14.
return
result;
15.}
8.1.2ContentProvider常用操作2.delete()方法delete()方法用于刪除Uri對應(yīng)的ContentProvider中的數(shù)據(jù)。其函數(shù)原型為:publicintupdate(Uriuri,ContentValuesvalues,Stringselection,String[]selectionArgs)8.//刪除id為2的記錄9.UrideleteIdUri=ContentUris.withAppendedId(uri,2);10.resolver.delete(deleteIdUri,null,null);8.1.2ContentProvider常用操作3.update()方法update()方法用于更新Uri對應(yīng)的ContentProvider中的數(shù)據(jù)。其函數(shù)原型為:publicintupdate(Uriuri,ContentValuesvalues,Stringselection,String[]selectionArgs)13.//把id為1的記錄的name字段值更改新為liming14.ContentValuesupdateValues=newContentValues();15.updateValues.put("name","liming");16.UriupdateIdUri=ContentUris.withAppendedId(uri,2);17.resolver.update(updateIdUri,updateValues,null,null);8.1.2ContentProvider常用操作4.query()方法query()方法用于查詢Uri對應(yīng)的ContentProvider中的數(shù)據(jù)。其函數(shù)原型為:publicCursorquery(Uriuri,String[]projection,Stringselection,String[]selectionArgs,StringsortOrder)18.//獲取person表中所有記錄19.Cursorcursor=resolver.query(uri,null,null,null,"personiddesc");20.while(cursor.moveToNext()){21.Log.i("ContentTest","personid="+cursor.getInt(0)+",name="+cursor.getString(1));22.}8.1ContentProvider簡介8.2開發(fā)ContentProvider程序8.3
本章總結(jié)8.4
習(xí)題8.5上機目
錄8.2開發(fā)ContentProvider程序8.2.1派生ContentProvider子類定義自己的ContentProvider類,該類需要繼承Android提供的ContentProvider基類。該子類需要實現(xiàn)query()、insert()、update()和delete()等方法。這些方法并不是給該應(yīng)用本身調(diào)用的,而是供其它應(yīng)用來調(diào)用。當(dāng)其它應(yīng)用通過ContentResolver調(diào)用query()、insert()、update()和delete()方法執(zhí)行數(shù)據(jù)訪問時,實際上就是調(diào)用指定URI對應(yīng)的ContentProvider中的這些方法。8.2開發(fā)ContentProvider程序8.2.1派生ContentProvider子類以【例8-1】共享單詞數(shù)據(jù)存儲為例。派生的ContentProvider子類示例代碼如下。1.import
android.content.ContentProvider;
2.import
android.content.ContentUris;
3.import
android.content.ContentValues;
4.import
android.content.UriMatcher;
5.import
android.database.Cursor;
6.import
android.database.sqlite.SQLiteDatabase;
7.import
.Uri;
8.import
androidx.annotation.NonNull;
9.import
androidx.annotation.Nullable;
10.
11.public
class
DictProvider
extends
ContentProvider
{
12.
private
static
UriMatcher
matcher
=
new
UriMatcher(UriMatcher.NO_MATCH);
13.
private
static
final
int
WORDS
=
1;
14.
private
static
final
int
WORD
=
2;
15.
private
MyDatabaseHelper
dbOpenHelper;
16.
17.
static
{
18.
//為UriMatcher注冊兩個Uri
19.
matcher.addURI(Words.AUTHORITY,
"words",
WORDS);
20.
matcher.addURI(Words.AUTHORITY,
"word/#",
WORD);
21.
}
22.
23.
@Override
24.
public
boolean
onCreate()
{
25.
dbOpenHelper
=
new
MyDatabaseHelper(this.getContext(),
"myDict.db3",
1);
26.
return
true;
27.
}
28.
8.2開發(fā)ContentProvider程序8.2.1派生ContentProvider子類29.
//執(zhí)行查詢方法,該方法返回查詢得到的cursor的值
30.
@Nullable
31.
@Override
32.
public
Cursor
query(@NonNull
Uri
uri,
@Nullable
String[]
projection,
@Nullable
String
selection,
@Nullable
String[]
selectionArgs,
@Nullable
String
sortOrder)
{
33.
SQLiteDatabase
db
=
dbOpenHelper.getReadableDatabase();
34.
switch
(matcher.match(uri))
{
35.
//如果URI參數(shù)代表操作全部數(shù)據(jù)項
36.
case
WORDS:
37.
//執(zhí)行查詢
38.
return
db.query("dict",
projection,
selection,
selectionArgs,
null,
null,
sortOrder);
39.
//如果URI參數(shù)代表操作指定數(shù)據(jù)項
40.
case
WORD:
41.
//解析出想查詢的記錄ID
42.
long
id
=
ContentUris.parseId(uri);
43.
String
whereClause
=
Words.Word._ID
+
"="
+
id;
44.
//如果原來的where子句存在,拼接where子句
45.
if
(selection
!=
null
&&
!"".equals(selection))
{
46.
whereClause
=
whereClause
+
"and"
+
selection;
47.
}
48.
return
db.query("dict",
projection,
whereClause,
selectionArgs,
null,
null,
sortOrder);
49.
default:
50.
try
{
51.
throw
new
IllegalAccessException("未知uri:"
+
uri);
52.
}
catch
(IllegalAccessException
e)
{
53.
e.printStackTrace();
54.
}
55.
}
56.
return
null;
57.
}
58.
8.2開發(fā)ContentProvider程序8.2.1派生ContentProvider子類59.
@Nullable
60.
//該方法的返回值代表了該contentProvider所提供數(shù)據(jù)的MIME類型
61.
@Override
62.
public
String
getType(@NonNull
Uri
uri)
{
63.
switch
(matcher.match(uri))
{
64.
//如果操作的數(shù)據(jù)為多項記錄
65.
case
WORDS:
66.
return
"vnd:android.cursor.dir/org.crazyit.dict";
67.
//如果操作的數(shù)據(jù)為單項記錄
68.
case
WORD:
69.
return
"vnd:android.cursor.item/org.crazyit.dict";
70.
default:
71.
try
{
72.
throw
new
IllegalAccessException("未知URI:"
+
uri);
73.
}
catch
(IllegalAccessException
e)
{
74.
e.printStackTrace();
75.
}
76.
}
77.
return
null;
78.
}
79.
8.2開發(fā)ContentProvider程序8.2.1派生ContentProvider子類80.
//實現(xiàn)插入的方法,該方法返回新插入的記錄的uri
81.
@Nullable
82.
@Override
83.
public
Uri
insert(@NonNull
Uri
uri,
@Nullable
ContentValues
values)
{
84.
//獲得數(shù)據(jù)庫實例
85.
SQLiteDatabase
db
=
dbOpenHelper.getReadableDatabase();
86.
switch
(matcher.match(uri))
{
87.
case
WORDS:
88.
long
rowId
=
db.insert("dict",
Words.Word._ID,
values);
89.
//如果成功插入返回uri
90.
if
(rowId
>
0)
{
91.
//在已有的uri后面追加id
92.
Uri
wordUri
=
ContentUris.withAppendedId(uri,
rowId);
93.
//通知數(shù)據(jù)已經(jīng)改變
94.
getContext().getContentResolver().notifyChange(wordUri,
null);
95.
return
wordUri;
96.
}
97.
break;
98.
default:
99.
try
{
100.
throw
new
IllegalAccessException("未知URI:"
+
uri);
101.
}
catch
(IllegalAccessException
e)
{
102.
e.printStackTrace();
103.
}
104.
}
105.
return
null;
106.
}
107.
8.2開發(fā)ContentProvider程序8.2.1派生ContentProvider子類108.
//實現(xiàn)刪除方法,該方法返回被刪除的記錄條數(shù)
109.
@Override
110.
public
int
delete(@NonNull
Uri
uri,
@Nullable
String
selection,
@Nullable
String[]
selectionArgs)
{
111.
SQLiteDatabase
db
=
dbOpenHelper.getReadableDatabase();
112.
//記錄刪除的數(shù)據(jù)行數(shù)
113.
int
num
=
0;
114.
switch
(matcher.match(uri))
{
115.
case
WORDS:
116.
num
=
db.delete("dict",
selection,
selectionArgs);
117.
break;
118.
case
WORD:
119.
long
id
=
ContentUris.parseId(uri);
120.
String
whereClause
=
Words.Word._ID
+
"="
+
id;
121.
//如果原來的where子句存在,拼接where子句
122.
if
(selection
!=
null
&&
!"".equals(selection))
{
123.
whereClause
=
whereClause
+
"and"
+
selection;
124.
}
125.
num
=
db.delete("dict",
whereClause,
selectionArgs);
126.
break;
127.
default:
128.
try
{
129.
throw
new
IllegalAccessException("未知URI:"
+
uri);
130.
}
catch
(IllegalAccessException
e)
{
131.
e.printStackTrace();
132.
}
133.
}
134.
getContext().getContentResolver().notifyChange(uri,
null);
135.
return
num;
136.
}
137.
8.2開發(fā)ContentProvider程序8.2.1派生ContentProvider子類138.
//實現(xiàn)更新方法,該方法應(yīng)該返回被更新的記錄條數(shù)
139.
@Override
140.
public
int
update(@NonNull
Uri
uri,
@Nullable
ContentValues
values,
@Nullable
String
selection,
@Nullable
String[]
selectionArgs)
{
141.
SQLiteDatabase
db
=
dbOpenHelper.getReadableDatabase();
142.
//記錄修改的數(shù)據(jù)數(shù)
143.
int
num
=
0;
144.
switch
(matcher.match(uri))
{
145.
case
WORDS:
146.
num
=
db.update("dict",
values,
selection,
selectionArgs);
147.
break;
148.
case
WORD:
149.
long
id
=
ContentUris.parseId(uri);
150.
String
whereClause
=
Words.Word._ID
+
"="
+
id;
151.
//如果原來的where子句存在,拼接where子句
152.
if
(selection
!=
null
&&
!"".equals(selection))
{
153.
whereClause
=
whereClause
+
"and"
+
selection;
154.
}
155.
num
=
db.update("dict",
values,
whereClause,
selectionArgs);
156.
break;
157.
default:
158.
try
{
159.
throw
new
IllegalAccessException("未知URI:"
+
uri);
160.
}
catch
(IllegalAccessException
e)
{
161.
e.printStackTrace();
162.
}
163.
}
164.
//通知數(shù)據(jù)已經(jīng)改變
165.
getContext().getContentResolver().notifyChange(uri,
null);
166.
return
num;
167.
}
168.}
8.2開發(fā)ContentProvider程序8.2.2注冊ContentProviderAndroidManifest.xml使用<provider>對該ContentProvider進行配置。為便于其它應(yīng)用查找該ContentProvider,ContentProvider采用了authorities(主機名/域名)對它進行唯一標(biāo)識。可以把ContentProvider看作是一個網(wǎng)站,authorities就是它的域名,配置ContentProvider時通常指定如下屬性:name:指定該ContentProvider的實現(xiàn)類的類名。authorities:指定該ContentProvider對應(yīng)的Uri(相當(dāng)于為該ContentProvider分配一個域名)。android:exported:指定該ContentProvider是否允許其它應(yīng)用調(diào)用。如果將該屬性設(shè)為false,那么該ContentProvider將不允許其他應(yīng)用調(diào)用。8.2開發(fā)ContentProvider程序8.2.2注冊ContentProvider以【例8-1】共享單詞數(shù)據(jù)存儲為例。注冊ContentProvider示例代碼如下。
1.<provider
2.
android:authorities="com.myapplication.dictprovider"
3.
android:name=".DictProvider"
4.
android:exported="true"/>
8.2開發(fā)ContentProvider程序8.2.3使用ContentProvider當(dāng)外部應(yīng)用需要對ContentProvider中的數(shù)據(jù)進行添加、刪除、修改和查詢操作時,可以使用ContentResolver類來完成。要獲取ContentResolver對象,可以使用Context提供的getContentResolver()方法。ContentResolver調(diào)用方法時參數(shù)將會傳給該ContentProvider的query()、insert()、update()和delete()方法,同時ContentResolver調(diào)用方法的返回值,也就是ContentProvider執(zhí)行這些方法的返回值。ContentResolver類提供了與ContentProvider類相同的四個方法。以【例8-1】共享單詞數(shù)據(jù)存儲為例。使用ContentResolver的insert()方法示例代碼如下。1.import
android.app.Activity;
2.import
android.content.ContentResolver;
3.import
android.content.ContentValues;
4.import
android.content.Intent;
5.import
android.database.Cursor;
6.import
android.os.Bundle;
7.import
android.view.View;
8.import
android.widget.Button;
9.import
android.widget.EditText;
10.import
android.widget.Toast;
11.import
androidx.annotation.Nullable;
12.import
java.util.ArrayList;
13.import
java.util.HashMap;
14.import
java.util.Map;
15.
16.public
class
DictResolver
extends
Activity
{
17.
ContentResolver
contentResolver;
18.
Button
insert=null;
19.
Button
search=null;
20.
21.
@Override
22.
protected
void
onCreate(@Nullable
Bundle
savedInstanceState)
{
23.
super.onCreate(savedInstanceState);
24.
setContentView(R.layout.dict);
25.
contentResolver=getContentResolver();
26.
insert=(Button)
findViewById(R.id.insert);
27.
search=(Button)
findViewById(R.id.search);
28.
insert.setOnClickListener(new
View.OnClickListener()
{
29.
@Override
30.
public
void
onClick(View
v)
{
31.
String
word=((EditText)findViewById(R.id.word)).getText().toString();
32.
String
detail=((EditText)findViewById(R.id.detail)).getText().toString();
33.
//插入生詞記錄
34.
ContentValues
values=new
ContentValues();
35.
values.put(Words.Word.WORD,word);
36.
values.put(Words.Word.DETAIL,detail);
37.
contentResolver.insert(Words.Word.DICT_CONTENT_URI,values);
8.2開發(fā)ContentProvider程序8.2.4使用ContentProvider實現(xiàn)共享單詞數(shù)據(jù)存儲示例【例8-1】創(chuàng)建Android項目,使用ContentProvider實現(xiàn)共享單詞數(shù)據(jù)存儲。在res/layout包中創(chuàng)建dict.xml、result.xml及l(fā)ine.xml文件,代碼如下:以下為dict.xml1.<?xml
version="1.0"
encoding="utf-8"?>
2.<LinearLayout
xmlns:android="/apk/res/android"
3.
android:layout_width="match_parent"
4.
android:layout_height="match_parent"
5.
android:orientation="vertical">
6.
<EditText
7.
android:id="@+id/word"
8.
android:layout_width="match_parent"
9.
android:layout_height="wrap_content"
/>
10.
<EditText
11.
android:id="@+id/detail"
12.
android:layout_width="match_parent"
13.
android:layout_height="wrap_content"
/>
14.
<Button
15.
android:id="@+id/insert"
16.
android:layout_width="wrap_content"
17.
android:layout_height="wrap_content"
18.
android:text="插入"
/>
19.
<EditText
20.
android:id="@+id/key"
21.
android:layout_width="match_parent"
22.
android:layout_height="wrap_content"
/>
23.
<Button
24.
android:id="@+id/search"
25.
android:layout_width="wrap_content"
26.
android:layout_height="wrap_content"
27.
android:text="查詢"
/>
28.</LinearLayout>8.2開發(fā)ContentProvider程序8.2.4使用ContentProvider實現(xiàn)共享單詞數(shù)據(jù)存儲示例以下為result.xml1.<?xml
version="1.0"
encoding="utf-8"?>
2.<LinearLayout
xmlns:android="/apk/res/android"
3.
android:orientation="vertical"
android:layout_width="match_parent"
4.
android:layout_height="match_parent">
5.
<ListView
6.
android:layout_width="wrap_content"
7.
android:layout_height="wrap_content"
8.
android:id="@+id/show"/>
9.</LinearLayout>
8.2開發(fā)ContentProvider程序8.2.4使用ContentProvider實現(xiàn)共享單詞數(shù)據(jù)存儲示例以下為line.xml1.<?xml
version="1.0"
encoding="utf-8"?>
2.<LinearLayout
xmlns:android="/apk/res/android"
3.
android:layout_width="match_parent"
4.
android:layout_height="match_parent"
5.
android:orientation="vertical">
6.
<EditText
7.
android:id="@+id/my_title"
8.
android:layout_width="wrap_content"
9.
android:layout_height="wrap_content"
/>
10.
<EditText
11.
android:id="@+id/my_content"
12.
android:layout_width="wrap_content"
13.
android:layout_height="wrap_content"
/>
14.</LinearLayout>8.2開發(fā)ContentProvider程序8.2.4使用ContentProvider實現(xiàn)共享單詞數(shù)據(jù)存儲示例定義ContentProvider所需的Uri及常量。代碼如下:1.import
.Uri;
2.import
vider.BaseColumns;
3.
4.public
final
class
Words
{
5.
//定義該ContentProvider的Authorities
6.
public
static
final
String
AUTHORITY
=
"com.myapplication.dictprovider";
7.
8.
//定義一個靜態(tài)類,定義該ContentProvider所包含數(shù)據(jù)列的列名
9.
public
static
final
class
Word
implements
BaseColumns
{
10.
//定義Content所允許操作的三個數(shù)據(jù)列
11.
public
final
static
String
_ID
=
"_id";
12.
public
final
static
String
WORD
=
"word";
13.
public
final
static
String
DETAILL
=
"detaill";
14.
//定義該Content提供服務(wù)的兩個uri
15.
public
final
static
Uri
DICT_CONTENT_URI
=
Uri.parse("content://"
+
AUTHORITY
+
"/words");
16.
public
final
static
Uri
WORD_CONTENT_URI
=
Uri.parse("content://"
+
AUTHORITY
+
"/word");
17.
}
18.}
8.2開發(fā)ContentProvider程序8.2.4使用ContentProvider實現(xiàn)共享單詞數(shù)據(jù)存儲示例繼承ContentProvider基類DictProvider提供詞典,重寫其中的增、刪、改、查等方法,以下為代碼實現(xiàn):1.import
android.content.ContentProvider;
2.import
android.content.ContentUris;
3.import
android.content.ContentValues;
4.import
android.content.UriMatcher;
5.import
android.database.Cursor;
6.import
android.database.sqlite.SQLiteDatabase;
7.import
.Uri;
8.import
androidx.annotation.NonNull;
9.import
androidx.annotation.Nullable;
10.
11.public
class
DictProvider
extends
ContentProvider
{
12.
private
static
UriMatcher
matcher
=
new
UriMatcher(UriMatcher.NO_MATCH);
13.
private
static
final
int
WORDS
=
1;
14.
private
static
final
int
WORD
=
2;
15.
private
MyDatabaseHelper
dbOpenHelper;
16.
17.
static
{
18.
//為UriMatcher注冊兩個Uri
19.
matcher.addURI(Words.AUTHORITY,
"words",
WORDS);
20.
matcher.addURI(Words.AUTHORITY,
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 訂貨合同協(xié)議書范本圖片
- 天氣預(yù)報課件
- 戰(zhàn)略合同協(xié)議書模板下載
- 物資合同封賬協(xié)議書
- 托管課程合同協(xié)議書范文
- 服務(wù)機器人項目商業(yè)計劃書
- 百合汁行業(yè)深度研究分析報告(2024-2030版)
- 浙江省第七屆創(chuàng)新創(chuàng)業(yè)大賽結(jié)果
- 創(chuàng)業(yè)計劃書范文15-20250205-205107
- 簡約美縫施工合同協(xié)議書
- 養(yǎng)老護理員培訓(xùn)課程內(nèi)容(范本)
- 大模型原理與技術(shù)-課件 chap10 多模態(tài)大模型
- 工地司機安全培訓(xùn)
- 高教版2023年中職教科書《語文》(基礎(chǔ)模塊)下冊教案全冊
- 義務(wù)教育版(2024)四年級全一冊-第三單元第11課-嘀嘀嗒嗒的秘密-教案
- 《采氣樹基礎(chǔ)知識》課件
- 北交所開戶測試題20題
- 學(xué)校安全風(fēng)險分級管控清單
- 近五年云南省中考數(shù)學(xué)真題及答案
- 綠色施工管理辦法
- 2024年安徽省中考物理試卷真題(含答案解析)+2023年中考物理試卷及答案
評論
0/150
提交評論