Android應(yīng)用程序開發(fā)技術(shù) 課件 第8章 ContentProvider數(shù)據(jù)共享_第1頁
Android應(yīng)用程序開發(fā)技術(shù) 課件 第8章 ContentProvider數(shù)據(jù)共享_第2頁
Android應(yīng)用程序開發(fā)技術(shù) 課件 第8章 ContentProvider數(shù)據(jù)共享_第3頁
Android應(yīng)用程序開發(fā)技術(shù) 課件 第8章 ContentProvider數(shù)據(jù)共享_第4頁
Android應(yīng)用程序開發(fā)技術(shù) 課件 第8章 ContentProvider數(shù)據(jù)共享_第5頁
已閱讀5頁,還剩53頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(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)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論