Android应用程序开发技术 课件 第8章 ContentProvider数据共享_第1页
Android应用程序开发技术 课件 第8章 ContentProvider数据共享_第2页
Android应用程序开发技术 课件 第8章 ContentProvider数据共享_第3页
Android应用程序开发技术 课件 第8章 ContentProvider数据共享_第4页
Android应用程序开发技术 课件 第8章 ContentProvider数据共享_第5页
已阅读5页,还剩53页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

Android应用程序开发技术第8章ContentProvider数据共享为了更加安全便捷的在不同应用之间共享数据,Android提供了ContentProvider组件,它是不同应用程序之间进行数据交换的标准API,当一个应用中的数据被其他应用所需要的时候,该应用就可以提供ContentProvider暴露自己的数据,其他应用程序可以通过ContentResolver来操作ContentProvider暴露的数据,包括增加数据、删除数据、修改数据、查询数据等。Android内置的许多数据都是使用ContentProvider形式,供开发者调用(如视频,音频,图片,通讯录等)。章节概述8.1ContentProvider简介8.2

开发ContentProvider程序8.3

本章总结8.4

习题8.5上机目

录ContentProvider可以选择对部分数据进行分享,保证数据安全,是Android提供的四大组件之一,主要用于不同应用程序之间实现数据共享。ContentProvider以Uri的形式对外提供数据,允许其他应用访问和修改数据;其它应用使用ContentResolver根据Uri进行访问操作指定的数据。ContentProvider内部保存数据的方式由其设计者决定。所有的ContentProvider都实现一组通用的方法用来提供数据的增、删、改、查功能。客户端通常不会直接使用这些方法,大多数是通过ContentResolver对象实现对ContentProvider的操作。开发人员可以通过调用Activity或者其它应用程序组件的实现类中,getContentResolver()方法来获得ContentResolver对象,例如:ContentResolvercr=getContentResolver();使用ContentResolver提供的方法可以获得ContentProvider中任何感兴趣的数据。8.1ContentProvider简介

8.1.1ContentProvider基本概念组织数据方式ContentProvider向其它应用提供数据有两种基本形式:文件形式和表格形式。在需要对大量的数据进行修改和查询操作时,将数据以一个表或多个表(与在关系型数据库中的表类似)的形式呈现给外部应用更加便于操作。其中,每一行表示一条记录,而每一列代表特定类型和含义的数据,并且其中每一条数据记录都包含一个名为“_ID”的字段类标识每条数据。【例】联系人的信息可以如下表所示。每条记录包含一个数值型的_ID字段,用于在表格中唯一标识该记录。ID能用于匹配相关表格中的记录,例如,在一个表格中查询联系人的电话,在另一表格中查询其照片。_IDNAMENUMBEREMAIL001张××123*****123**@002王××134*****134**@003李××145*****145***@004赵××156*****156***@8.1.1ContentProvider基本概念组织数据方式8.1.1ContentProvider基本概念URI统一资源标识符(UniformResourceIdentifier,URI)是一个用于标识某一互联网资源名称的字符串。该种标识允许用户对任何(包括本地和互联网)的资源通过特定的协议进行交互操作。ContentProvider提供公共的URI来唯一标识其数据集。管理多个数据集的ContentProvider为每个数据集提供了单独的URI。URI主要包含两部分信息:需要操作的ContentProvider和ContentProvider中需要进行操作的数据。8.1.1ContentProvider基本概念URI一个URI由以下几部分组成:自定义URI=content://vider/User/ID主题名授权信息表名记录主题名(Schema):用于标识该数据由ContentProvider管理,无需修改。授权信息(authority):URI的authority部分,ContentProvider的唯一标识符,外部调用者可以根据这个标识来找到它。表名(Path):ContentProvider的路径部分,用于决定哪类数据被请求。如果ContentProvider提供一种数据类型,可以省略该部分;如果提供几种类型,包括子类型,这部分可以由几部分组成。记录(ID):被请求记录的ID值。若无指定,则返回全部记录。8.1.1ContentProvider基本概念URI【例】

1.//设置URI2.Uriuri=Uri.parse("content://vider/User/1")3.//上述URI指向的资源是:名为`vider`的`ContentProvider`中表名

为`User`中的`id`为1的数据4.//特别注意:URI模式存在匹配通配符*&#5.//*:匹配任意长度的任何有效字符的字符串6.//以下的URI表示

匹配provider的任何内容7.content://vider/*8.//#:匹配任意长度的数字字符的字符串9.//以下的URI表示

匹配provider中的table表的所有行10.content://vider/table/#8.1.1ContentProvider基本概念URI通常解析URI使用Android系统提供的操作URI工具类:UriMatcher。UriMatcher类用来匹配URI,对匹配结果返回对应的匹配码。UriMatcher使用addURI()方法注册需要匹配的URI。addURI()方法原型是:publicvoidaddURI(Stringauthority,Stringpath,intcode)注册完成之后可以使用UriMatcher类的match()方法匹配URI,如果匹配成功就返回相应的匹配码,匹配码是使用addURI()注册URI时传入的第3个参数,注册时传入的匹配码需要唯一。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对应的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系统提供了一些定义好的URI。例如,手机短信的信息、图库数据、联系人信息等操作系统均提供相应的URI。知道对应的URI后,就可以通过ContentResolver对象,根据URI进行数据访问。Android系统用于管理联系人的ContentProvider的几个URI如下:ContactsContract.Contacts.CONTENT_URI:管理联系人的URI。ContactsContract.CommonDataKinds.Phone.CONTENT_URI:管理联系人电话的URI。ContactsContract.CommonDataKinds.Email.CONTENT_URI:管理联系人E-mail的URI。8.1.1ContentProvider基本概念URIAndroid系统用于管理多媒体的ContentProvider的几个URI如下:MediaStore.Audio.Media.EXTERNAL_CONTENT_URI:存储在外部存储器(SD卡)上的音频文件内容的ContentProvider的URI。MediaStore.Audio.Media.INTERNAL_CONTENT_URI:存储在手机内部存储器上的音频文件内容的ContentProvider的URI。MediaStore.Images.Media.EXTERNAL_CONTENT_URI:存储在外部存储器(SD卡)上的图片文件内容的ContentProvider的URI。MediaStore.Images.Media.INTERNAL_CONTENT_URI:存储在手机内部存储器上的图片文件内容的ContentProvider的URI。MediaStore.Video.Media.EXTERNAL_CONTENT_URI:存储在外部存储器(SD卡)上的视频文件内容的ContentProvider的URI。MediaStore.Video.Media.INTERNAL_CONTENT_URI:存储在手机内部存储器上的视频文件内容的ContentProvider的URI。8.1.1ContentProvider基本概念.MIME数据类型多功能Internet邮件扩充服务(MIME:MultipurposeInternetMailExtensions)是一种多用途网际邮件扩充协议。该服务于1992年最早应用于电子邮件系统,后来也应用到浏览器。MIME类型就是设定某种扩展名的文件用一种应用程序来打开的方式类型。当该扩展名文件被访问的时候,浏览器会自动使用指定应用程序打开,多用于指定一些客户端自定义的文件名,以及一些媒体文件打开方式。在Android中MIME数据类型的作用是指定应用程序打开特定扩展名的文件。URI里面提供给provider所支持的MIME数据类型,provider根据web中MIME标准返回一个由两个字符串组成的MIME类型识别。8.1.1ContentProvider基本概念.MIME数据类型每种MIME数据类型由两部分组成:一个类型和一个子类型。MIME类型是一个包含两部分的字符串。这里有些熟知的MIME类型对:text/htmltext/csstext/xmltext/vnd.curl8.1.1ContentProvider基本概念.MIME数据类型MIME类型在Android里面得到了大规模的应用,特别是在intent里,系统根据MIME数据的类型来决定调用哪个activity。MIME类型始终通过contentproviders继承自它们的URIs。在使用MIME类型的时候要记住三点:基本类型和子类型代表的东西要唯一。如果是非标准的,专有的类型和子类型,前面需要加vnd。对于特定的需求,注意名字空间。在ContentProvider中使用getType()方法返回当前Uri所代表数据的MIME类型。8.1.2ContentProvider常用操作ContentProvider类提供了以下六个方法:onCreate()方法:用来执行一些初始化的工作query()方法:用来返回数据给调用者Insert()方法:用来插入新的数据update()方法:用来更新已有的数据delete()方法:用来删除数据getType()方法:用来返回数据的MIME类型8.1.2ContentProvider常用操作onCreate()方法用来执行一些初始化的工作。其函数原型为:publicbooleanonCreate()该方法在ContentProvider创建后被调用。onCreate()方法返回一个boolean类型的值,初始化操作成功时返回true,否则返回false,具体代码如下所示。

1.onCreate()方法1.@Override

2.public

boolean

onCreate()

{

3.

//初始化数据库

4.

String

sql

=

"create

table

if

not

exists

t1("

+

"id

integer

primary

key,

name

text,

phone

text);";5.//在content.db数据库中创建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()方法用来返回数据给调用者。其函数原型为:publicCursorquery(Uriuri,String[]projection,Stringselection,String[]

selectionArgs,StringsortOrder)该方法用于供外部应用从ContentProvider中获取数据。根据Uri查询出selection条件所匹配的全部记录,其中projection表明选择出指定的数据列,最终查询结果保存在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()方法用来插入新的数据。其函数原型为:publicUriinsert(Uri

uri,

ContenrValues

values)该方法用于供外部应用往ContentProvider添加数据。该方法需要两个参数,第一个参数是使用资源的Uri对象,第二个参数为需要添加的数据。添加成功则返回新数据的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.

//插入数据并返回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()方法用来更新已有的数据。其函数原型为:publicintupdate(Uriuri,ContentValuesvalues,Stringselection,String[]selectionArgs)该方法用于供外部应用更新ContentProvider中的数据。根据Uri修改selection条件所匹配的全部记录,最终返回值表示更新操作影响的记录数量,具体代码如下所示。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()方法用来删除数据。其函数原型为:publicintdelete(Uri

uri,

String

selection,

String[]

selectionArgs)该方法用于供外部应用从ContentProvider删除数据。根据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()方法用来返回数据的MIME类型。其函数原型为:publicStringgetType(Uriuri)该方法用于返回当前Uri所代表数据的MIME类型。如果该Uri对应的数据可能包含多条记录,那么MIME类型字符串应该以vnd.android.cursor.dir/开头;如果该Uri对应的数据只包含一条记录,那么MIME类型字符串应该以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常用操作如果访问内容提供器ContentProvider中的数据,则需要使用ContentResolver类。ContentResolver类的功能就是通过标准接口统一管理不同

ContentProvider间的操作。该类实例可以通过Context的getContentResolver()方法获得ContentResolver中提供了insert()、update()、delete()、query()等方法对数据进行CRUD操作。常见的,ContentProvider是单例模式的,当多个应用程序通过ContentResolver来操作ContentProvider提供的数据时,ContentResolver调用的数据操作将会委托给同一个ContentProvider处理。8.1.2ContentProvider常用操作1.insert()方法insert()方法用于向Uri对应ContentProvider中插入对应的数据。其函数原型为: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对应的ContentProvider中的数据。其函数原型为: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对应的ContentProvider中的数据。其函数原型为: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对应的ContentProvider中的数据。其函数原型为: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开发ContentProvider程序8.3

本章总结8.4

习题8.5上机目

录8.2开发ContentProvider程序8.2.1派生ContentProvider子类定义自己的ContentProvider类,该类需要继承Android提供的ContentProvider基类。该子类需要实现query()、insert()、update()和delete()等方法。这些方法并不是给该应用本身调用的,而是供其它应用来调用。当其它应用通过ContentResolver调用query()、insert()、update()和delete()方法执行数据访问时,实际上就是调用指定URI对应的ContentProvider中的这些方法。8.2开发ContentProvider程序8.2.1派生ContentProvider子类以【例8-1】共享单词数据存储为例。派生的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开发ContentProvider程序8.2.1派生ContentProvider子类29.

//执行查询方法,该方法返回查询得到的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参数代表操作全部数据项

36.

case

WORDS:

37.

//执行查询

38.

return

db.query("dict",

projection,

selection,

selectionArgs,

null,

null,

sortOrder);

39.

//如果URI参数代表操作指定数据项

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开发ContentProvider程序8.2.1派生ContentProvider子类59.

@Nullable

60.

//该方法的返回值代表了该contentProvider所提供数据的MIME类型

61.

@Override

62.

public

String

getType(@NonNull

Uri

uri)

{

63.

switch

(matcher.match(uri))

{

64.

//如果操作的数据为多项记录

65.

case

WORDS:

66.

return

"vnd:android.cursor.dir/org.crazyit.dict";

67.

//如果操作的数据为单项记录

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开发ContentProvider程序8.2.1派生ContentProvider子类80.

//实现插入的方法,该方法返回新插入的记录的uri

81.

@Nullable

82.

@Override

83.

public

Uri

insert(@NonNull

Uri

uri,

@Nullable

ContentValues

values)

{

84.

//获得数据库实例

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.

//通知数据已经改变

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开发ContentProvider程序8.2.1派生ContentProvider子类108.

//实现删除方法,该方法返回被删除的记录条数

109.

@Override

110.

public

int

delete(@NonNull

Uri

uri,

@Nullable

String

selection,

@Nullable

String[]

selectionArgs)

{

111.

SQLiteDatabase

db

=

dbOpenHelper.getReadableDatabase();

112.

//记录删除的数据行数

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开发ContentProvider程序8.2.1派生ContentProvider子类138.

//实现更新方法,该方法应该返回被更新的记录条数

139.

@Override

140.

public

int

update(@NonNull

Uri

uri,

@Nullable

ContentValues

values,

@Nullable

String

selection,

@Nullable

String[]

selectionArgs)

{

141.

SQLiteDatabase

db

=

dbOpenHelper.getReadableDatabase();

142.

//记录修改的数据数

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.

//通知数据已经改变

165.

getContext().getContentResolver().notifyChange(uri,

null);

166.

return

num;

167.

}

168.}

8.2开发ContentProvider程序8.2.2注册ContentProviderAndroidManifest.xml使用<provider>对该ContentProvider进行配置。为便于其它应用查找该ContentProvider,ContentProvider采用了authorities(主机名/域名)对它进行唯一标识。可以把ContentProvider看作是一个网站,authorities就是它的域名,配置ContentProvider时通常指定如下属性:name:指定该ContentProvider的实现类的类名。authorities:指定该ContentProvider对应的Uri(相当于为该ContentProvider分配一个域名)。android:exported:指定该ContentProvider是否允许其它应用调用。如果将该属性设为false,那么该ContentProvider将不允许其他应用调用。8.2开发ContentProvider程序8.2.2注册ContentProvider以【例8-1】共享单词数据存储为例。注册ContentProvider示例代码如下。

1.<provider

2.

android:authorities="com.myapplication.dictprovider"

3.

android:name=".DictProvider"

4.

android:exported="true"/>

8.2开发ContentProvider程序8.2.3使用ContentProvider当外部应用需要对ContentProvider中的数据进行添加、删除、修改和查询操作时,可以使用ContentResolver类来完成。要获取ContentResolver对象,可以使用Context提供的getContentResolver()方法。ContentResolver调用方法时参数将会传给该ContentProvider的query()、insert()、update()和delete()方法,同时ContentResolver调用方法的返回值,也就是ContentProvider执行这些方法的返回值。ContentResolver类提供了与ContentProvider类相同的四个方法。以【例8-1】共享单词数据存储为例。使用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开发ContentProvider程序8.2.4使用ContentProvider实现共享单词数据存储示例【例8-1】创建Android项目,使用ContentProvider实现共享单词数据存储。在res/layout包中创建dict.xml、result.xml及line.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开发ContentProvider程序8.2.4使用ContentProvider实现共享单词数据存储示例以下为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开发ContentProvider程序8.2.4使用ContentProvider实现共享单词数据存储示例以下为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开发ContentProvider程序8.2.4使用ContentProvider实现共享单词数据存储示例定义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.

//定义一个静态类,定义该ContentProvider所包含数据列的列名

9.

public

static

final

class

Word

implements

BaseColumns

{

10.

//定义Content所允许操作的三个数据列

11.

public

final

static

String

_ID

=

"_id";

12.

public

final

static

String

WORD

=

"word";

13.

public

final

static

String

DETAILL

=

"detaill";

14.

//定义该Content提供服务的两个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开发ContentProvider程序8.2.4使用ContentProvider实现共享单词数据存储示例继承ContentProvider基类DictProvider提供词典,重写其中的增、删、改、查等方法,以下为代码实现: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. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论