收藏 分享(赏)

Android四大组件 之ContentProvider.ppt

上传人:weiwoduzun 文档编号:5712768 上传时间:2019-03-14 格式:PPT 页数:33 大小:511.50KB
下载 相关 举报
Android四大组件 之ContentProvider.ppt_第1页
第1页 / 共33页
Android四大组件 之ContentProvider.ppt_第2页
第2页 / 共33页
Android四大组件 之ContentProvider.ppt_第3页
第3页 / 共33页
Android四大组件 之ContentProvider.ppt_第4页
第4页 / 共33页
Android四大组件 之ContentProvider.ppt_第5页
第5页 / 共33页
点击查看更多>>
资源描述

1、跨应用数据源,ContentProvider,目录,1、数据共享2、系统 中的ContentProvider3、自定义ContentProvider4、监听ContentProvider 的数据,数据共享, Android中存在多个应用程序,应用程序间的数据如何共享呢?,联系人数据,数据共享,为了在应用程序之间共享数据,Android提供了ContentProvider,这是一种不同应用之间共享数据的标API: 当应用希望提供数据时,就提供Contentprovider 其他应用通过ContentResolver来操作 注意: ContentProvider需要在AndroidManifest

2、.xml中注册 一旦应用提供CP,不论应用启动与否,都可被操作,数据共享标准与结构,ContentProvider是不用应用间共享数据的标准,它以Uri的形式对外提供数据,其他应用程序使用ContentResolver根据Uri去访问指定数据。ContentProvider是单例模式的,多个ContentResolver请求数据时,是委托给同一个CP来操作的。,ContentProvider,ContentResolver,ContentResolver,ContentResolver,Uri,Uri,Uri,ContentProvider与ContentResolver,可以把Content

3、Provider当成Android系统内部的“网站”,这个网站以固定的Uri对外提供服务。ContentResolver则可以当成Android系统内部的HttpClient,它可以向指定Uri发送请求(实际上是调用ContentResolver的方法)。这种请求最后委托给ContentProvider处理,从而实现对“网站”(即ContentProvider)内部数据进行操作。,ContentProvider的使用,1、定义自己的类继承ContentProvider类 boolean onCreate() Uri insert(uri, values) int delete(uri, sel

4、ection, selectionargs) int update(uri, values, selection, selectionargs) Cursor query(uri, values,selection,selectionargs,sortorder) String getType(uri) 2、在AndroidManifest.xml文件中注册,为ContentProvider指定Uri。在中配置标签。android:name属性:ContentProvider的类名android:authorities属性:用于访问ContentProvider的名称 3、其他应用程序使用Co

5、ntentResolver通过ContentProvider的Uri访问开放的数据。,URI(统一资源标识符),Android 所提供的 ContentProvider 都存放在 android.provider 包中。 将其分为 A,B,C,D 4 个部分: (如下图所示)主要分三个部分:scheme(协议), authority and path A部分:表示是一个Android内容URI,说明由ContentProvider控制数据,该部分是固定形式,不可更改的。 B部分:是URI的授权部分,是唯一标识符,用来定位ContentProvider。格式一般是自定义ContentProvid

6、er类的完全限定名称,注册时需要用到,如:com.alexzhou.provider.NoteProvider C部分和D部分:是每个ContentProvider内部的路径部分,C和D部分称为路径片段,C部分指向一个对象集合,一般用表的名字,如:/notes表示一个笔记集合;D部分指向特定的记录,如:/notes/1表示id为1的笔记,如果没有指定D部分,则返回全部记录。,URI,例如以下是系统的一些 URI: content:/media/internal/images (该 URI 返回设备上存储的所有图片) content:/contacts/people/5 (联系人信息中 ID 为

7、 5 的联系人记录) content:/contacts/people (该 URI 返回设备上的所有联系人信息),ContentResolver的使用,ContentResolver对象通过Context提供的方法 getContentResolver来获得。ContentResolver提供了以下方法来操作:insert(Uri url,ContentValues values) 在Uri对应的ContentProvider中插入values对应的数据delete(Uri url,String where, String selectionArgs) 删除Uri对应的ContentProv

8、ider中where提交匹配的数据update(Uri url, ContentValues values , String where, String selectionArgs) 更新Uri对应的ContentProvider中where提交匹配的数据)query(Uri url , String projections,String selection,String selectionArgs, String sortOrder) 查询Uri对应的ContentProvider中where提交匹配的数据)这些方法分别会调用ContentProvider中对应的方法,并得到放回结果。,Co

9、ntentResolver的使用,projection这个参数告诉Provider要返回的内容(列Column),用null表示返回Provider的所有内容(列Column)。 selection,设置条件,相当于SQL语句中的where。null表示不进行筛选。selectionArgs,这个参数是要配合第三个参数使用的,如果你在第三个参数里面有?,那么你在selectionArgs写的数据就会替换掉?。sortOrder,按照什么进行排序,相当于SQL语句中的Order by。如果想要结果按照ID的降序排列: android.provider.ContactsContract.Conta

10、cts._ID + “ DESC“,ContentProvider的使用,contentResolver.update(Words.Word.DICT_CONTENT_URI, values,“word = ?“, new Stringword);contentResolver.query(Words.Word.DICT_CONTENT_URI, null, “word = ?“, newStringkey, null);,获得系统的CP 的数据, Android系统中会给应用提供一些开放的系统数据,当然它是采用CP的这种形式。 通过ContentResolver访问系统CP的步骤: 调用Ac

11、tivity的ContentResolver获取CR对象 调用CR中的insert,delete,update,query方法获得系统CP提供的数据 注意: 要获得系统CP提供的数据,必须要了解该CP的Uri。,使用CP 管理联系人, Android系统中Contacts应用来管理联系人,而且暴露相应CP。 此CP支持的Uri如下: ContactsContract.Contacts.CONTENT_URI:管理联系人的Uri ContactsContract.CommonDataKinds.Phone.CONTENT_URI:管理联系人的电话的UriContactsContract.Comm

12、onDataKinds.Email.CONTENT_URI:管理联系人的Email的Uri,使用CP管理多媒体内容, Android提供了Camera程序来支持拍照、视频,用户的多媒体信息都存放在固定的位置,并且提供了CP。 此CP支持的Uri如下: MediaStore.Audio.Media.EXTERNAL_CONTENT_URI MediaStore.Audio.Media.INTERNAL_CONTENT_URI MediaStore.Images.Media.EXTERNAL_CONTENT_URI MediaStore.Images.Media.INTERNAL_CONTENT_

13、URI MediaStore.Video.Media.EXTERNAL_CONTENT_URI MediaStore.Video.Media.INTERNAL_CONTENT_URI,自定义ContentProvider,1、编写一个ContentProvider的子类,该子类根据需要实现增、删、改、查等方法。2、必须在AndroidManifest.xml文件中注册自定义的ContentProvider3、 为了确定ContentProvider匹配的Uri,使用UriMatcher工具类: void addURI(authority, path , code) int match(uri)

14、4、 为了操作Uri,Android使用ContentUris工具类: withAppendedId(uri,id) -parseId(uri),工具类UriMather和ContentUris,android系统提供了两个用于操作Uri的工具类 1、ContentUris1)、withAppendedId(uri,id)/用于为路径加上id部分 Uri uri = Uri.parse(“content:/com.yfz.Lesson/people“) Uri resultUri = ContentUris.withAppendedId(uri, 10) /最后resultUri为: cont

15、ent:/com.yfz.Lesson/people/102)、parseId(uri)/用于从指定uri中解析出所包含的id的值 Uri uri = Uri.parse(“content:/com.yfz.Lesson/people/10“) long personid = ContentUris.parseId(uri); 最后personid 为 :10 2、UriMatcher主要用于匹配uri1)、void addUri(String authority, String path , String code)/用于向UriMatcher注册一个Uri,authority和path组成

16、一个Uri,code代表该Uri对应的标识码,2)、int match(Uri uri)/根据前面注册的uri用于判定制定uri对应的标识码,如果找不到,返回-1 UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH); matcher.addUri(“content:/org.crazyit.providers.dictprovider“, “words“, 1) matcher.addUri(“content:/org.crazyit.providers.dictprovider“, “word#“, 2) matcher.matc

17、h(Uri.parse(“content:/org.crazyit.providers.dictprovider/words/) /返回标识码1 matcher.match(Uri.parse(“content:/org.crazyit.providers.dictprovider/word/2) /返回标识码2 matcher.match(Uri.parse(“content:/org.crazyit.providers.dictprovider/word/10)/返回标识码2,插入数据INSERT,public Uri insert(Uri uri, ContentValues value

18、s) /获得数据库实例SQLiteDatabase db = dbOpenHelper.getReadableDatabase();/插入数据,返回行IDlong rowId = db.insert(“dict“, Words.Word._ID, values);/如果插入成功,返回uriif(rowId0) /在已有的Uri后面追加ID数据Uri wordUri = ContentUris.withAppendedId(uri, rowId);/通知数据已经改变getContext().getContentResolver().notifyChange(wordUri, null);retu

19、rn wordUri;return null; ,删除数据DELETE,public int delete(Uri uri, String selection, String selectionArgs) SQLiteDatabase db = dbOpenHelper.getReadableDatabase();/ 记录所删除的记录数int num = 0;/ 对于uri进行匹配。switch (matcher.match(uri) case WORDS:num = db.delete(“dict“, selection, selectionArgs);break;case WORD:/ 解

20、析出所需要删除的记录IDlong id = ContentUris.parseId(uri);String where = Words.Word._ID + “=“ + id;,/ 如果原来的where子句存在,拼接where子句 if (selection != null ,修改数据UPDATE,public int update(Uri uri, ContentValues values, String selection, String selectionArgs) / TODO Auto-generated method stubSQLiteDatabase db = dbOpenHe

21、lper.getWritableDatabase();/ 记录所修改的记录数int num = 0;switch (matcher.match(uri)case WORDS:num = db.update(“dict“, values, selection, selectionArgs);break;case WORD:/ 解析出想修改的记录ID,long id = ContentUris.parseId(uri);String where = Words.Word._ID + “=“ + id;/ 如果原来的where子句存在,拼接where子句if (selection != null ,

22、查询数据QUERY,public Cursor query(Uri uri, String projection, String selection, String selectionArgs, String sortOrder) SQLiteDatabase db = dbOpenHelper.getReadableDatabase();switch (matcher.match(uri)case WORDS:/ 执行查询return db.query(“dict“, projection, selection, selectionArgs,null, null, sortOrder);ca

23、se WORD:/ 解析出想查询的记录IDlong id = ContentUris.parseId(uri);,String where = Words.Word._ID + “=“ + id;/ 如果原来的where子句存在,拼接where子句if (selection != null ,GETTYPE,/返回指定uri参数对应的数据的MIME类型 public String getType(Uri uri) switch(matcher.match(uri) / 如果操作的数据是多项记录case WORDS:return “vnd.android.cursor.dir/com.examp

24、le.dict“;/ 如果操作的数据是单项记录case WORD:return “vnd.android.cursor.item/com.example.dict“;default:throw new IllegalArgumentException(“未知Uri:“ + uri); 如果操作的数据属于集合类型,那么MIME类型字符串应该以vnd.android.cursor.dir/开头,否则以vnd.android.cursor.item/开头,监听ContentProvider的数据,1、如果CP的数据进行了修改,程序会调用如下代码: getContext().getContentRes

25、olver().notifyChange() 作用:通知所有Uri的监听者,CP数据发生改变2、通过ContentObserver进行CP数据修改的监听。 自定义类继承ContentObserver类,重写onChange方法,也就是当CP数据改变后的回调方法 通过ContentResolver向Uri注册ContentObserver registerContentObserver(,) Uri:该监听器所监听的CP的Uri notifyForDescendents:子Uri数据改变时是否出发 observer:监听器实例,使用ContentProvider共享生词本数据,1、设计单词本的工

26、具类 Words.java ,类中通常会把 ContentProvider 的 Uri、数据列等数据信息以常量的形式开放,方便访问,这个工具类的主要作用是提供了其他应用程序可以访问ContentProvider 的常用入口。2. 创建 SQLiteOpenHelper 的子类来管理数据库连接。定义 MyDatabaseHelper,继承自SQLiteOpenHelper。该类的主要作用是管理数据库的初始化, 允许应用程序通过该类获取SQLiteDatabase 对象,并利用获取的数据库对象操作数据库。3、实现自己的 ContentProvider(DictProvider) ,继承 Conte

27、ntProvider。需要重写其增、删、改、查等方法。4. 建立生词本应用程序,使用ContentProvider共享生词本数据,读写SD卡上的文件,步骤:(1)调用Environment的getExternalStorageState()方法判断手机上是否插入sd卡,并且具有读写sd卡的权限。eg:Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)(2)Environment的getExternalStorageDirectory()获取外部存储器,也就是SD卡的目录。(3)使用FileInputSt

28、ream, FileOutputStream, FileReader, FileWriter读写SD卡里的文件。,注意:(1)为了读写SD卡上的数据。必须在应用程序的清单文件(AndoidManifest.xml)添加读写SD卡的权限,如下:(2)还可以使用/mnt/sdcard来代表sdcard的路径,然后程序可以通过判断/mnt/sdcard路径是否存在就可以知道手机是否插入sdcard。但是Genymotion模拟器SD卡对应的路径是/mnt/shell/emulated/0。(3)Cursor musicCursor = musicResolver.query(MediaStore.A

29、udio.Media.EXTERNAL_CONTENT_URI, null, null, null, null);(音乐播放器),private String read()try/ 如果手机插入了SD卡,而且应用程序具有访问SD的权限if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)/media_mounted/ 获取SD卡对应的存储目录File sdCardDir = Environment.getExternalStorageDirectory();/ 获取指定文件对应的输入流FileInp

30、utStream fis = new FileInputStream(sdCardDir.getCanonicalPath() + FILE_NAME);/ 将指定输入流包装成BufferedReaderBufferedReader br = new BufferedReader(new InputStreamReader(fis);StringBuilder sb = new StringBuilder(“);,String line = null;/ 循环读取文件内容 while (line = br.readLine() != null)sb.append(line);/ 关闭资源br.close();return sb.toString();catch (Exception e)e.printStackTrace();return null;,

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 企业管理 > 经营企划

本站链接:文库   一言   我酷   合作


客服QQ:2549714901微博号:道客多多官方知乎号:道客多多

经营许可证编号: 粤ICP备2021046453号世界地图

道客多多©版权所有2020-2025营业执照举报