ContentProvider主要用于在不同的应用程序之间实现数据共享,它提供了一套完整的机制,允许一个程序访问另一个程序中的数据,同时还能保证被访问数据的安全性,目前内容提供其实android实现跨进程共享数据的标准方式。

ContentProvider的用法一般有两种,一种是使用ContentResolver来读取和操作应用程序中ContentProvider共享的数据,另一种就是创建自己的ContentProvider子类给我们的程序提供外部访问的接口。

其中ContentProvider负责

  • 组织应用程序的数据;
  • 向其他应用程序提供数据;

ContentResolver则负责

  • 获取ContentProvider提供的数据;
  • 修改/添加/删除更新数据等;

一、ContentResolver访问应用中ContentProvider的共享数据:

(1)获取ContentResolver对象:

可以使用Context中的getContentResolver()方法来获取ContentResolver对象。

(2)使用ContentResolver对象提供一系列方法对数据进行CRUD等操作:

主要使用的方法就是关于数据的增删改查方法:

Uri insert(Uri url, ContentValues values)

int delete(Uri url, String where, String[] selectionArgs)

int update(Uri uri, ContentValues values, String where, String[] selectionArgs)

Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder)

不同于SQLiteDatabase,ContentResolver中的增删改查方法都是不接收表名参数的,而是使用一个Uri参数代替,这个参数被称为内容URI。

内容URI给ContentProvider中的数据建立提供了唯一标示。

ContentResolver中的增删改查方法都接收内容URI作为参数,使用内容URI可以清楚的表名当前的ContentResolver要访问的是哪一个应用了程序中的哪一个数据表。

内容URI由两部分组成:权限(用来对不同的应用程序作区分,一般为了避免冲突,都会采用应用包名的方式来进行命名)和路径(为了对一应用程序中的不同表来作区分)

eg:com.example.app为应用包名,table为应用中表名

权限可命名为:com.example.app.provider;路径可命名为:/table

完整的内容URI字符串还需要在权限和路径组成的字符串头部加上协议声明,那么完整的URI写法为:

           content://com.example.app.provider/table/id [还可以在末尾加上一个id值,表示为table表中id值为指定值的数据]

           得到URI字符串后还需要将其转化为URI对象才能被ContentResolver中的方法使用:

           Uri uri=Uri.parse("content://com.example.app.provider/table");

           CotentResolver中对数据的操作除了操作的数据源的写法与SQLite中不一致外,其他参数的使用均与SQLite中的写法大体相同,故不再一一赘述。

二、使用ContentProvider向外提供数据访问的接口

1、新建ContentProvider的实现类重写其中的六个方法。

2、CpntentProvider中使用的内容URI的格式主要有两种,以路径结尾表示查询表中全部数据,以id结尾表示希望访问表中指定id值的数据。

可以使用通配符来分别匹配这两种格式的内容URI,规则如下:

1、*表示匹配任意长度的任意字符

表示匹配任意表的内容URI格式可以写成:content://com.example.app.provider/*

2、#表示匹配任意长度的字符

表示匹配table表中任意一行数据的内容URI格式可以写成:content://com.example.app.provider/table/#

使用UriMatcher这个类就可以实现内容URI的匹配功能

UriMatcher中提供了addURI(String authority, String path, int code)方法可以将权限、路径和一个自定的代码传进去,这样当调用UriMatcher的match(Uri Uri)方法时就可以将Uri与一个自定义的代码对应起来,利用这个代码我们就可以判断出外部应用期望访问的是哪一张表中的数据了,之后就可以对数据表中的数据进行操作并返回操作结构给外部应用请求的ContentResolver了。

  1. static{
  2. urimatcher=new UriMatcher(UriMatcher.NO_MATCH);
  3. urimatcher.addURI("com.example.app.provider", "table1", TABLE1_DIR);
  4. urimatcher.addURI("com.example.app.provider", "table1/#", TABLE1_DIR);
  5. }
  6.  
  7. @Override
  8. public Cursor query(Uri uri, String[] projection, String selection,
  9. String[] selectionArgs, String sortOrder) {
  10. // TODO Auto-generated method stub
  11. switch (urimatcher.match(uri)) {
  12. case TABLE1_DIR:
  13. //查询table1中所有数据
  14. break;
  15.  
  16. case TABLE1_ITEM:
  17. //查询table1中单条数据
  18. break;
  19. }
  20. return null;
  21. }

3.ContentProvider中的getType(Uri Uri)方法,用于获取Uri对象对应的MIME类型。

一个内容URI所对应的MIME类型字符串主要有三部分组成,Android对这三部分做了如下规定:

(1)必须以vnd开头;

(2)如果内容URI以路径结尾,则后接android.cursor.dir/,如果内容URI以id结尾则后接android.cursor.item/;

(3)最后接上vnd.<authority>.<path>;

eg:content://com.example.app.provider/table这样的内容URI,对应MIME类型字符串为:

vnd.android.cursor.dir/vnd.com.example.app.provider.table

那么ContentProvider中的getType()写法如下:

  1. @Override
  2. public String getType(Uri uri) {
  3. // TODO Auto-generated method stub
  4. switch (urimatcher.match(uri)) {
  5. case TABLE1_DIR:
  6. return "vnd.android.cursor.dir/vnd.com.example.app.provider.table1";
  7. break;
  8.  
  9. case TABLE1_ITEM:
  10. return "vnd.android.cursor.item/vnd.com.example.app.provider.table1";
  11. break;
  12. }
  13.  
  14. }

4、在AndroidManifest.xml文件中加入<provider>标签

  1. <provider
  2. android:name="com.example.app.myProvider"
  3. android:authorities="com.example.app.provider"
  4. android:exported="true">
  5. </provider>

 name:ContentProvider子类的完整包名

authorities:指定此ContentProvider的权限名

exported:指定此ContentProvider是可以被其他程序引用的

完整的Contentprovider写法:

  1.  
  1. class myProvider extends ContentProvider{
  2. //访问table1中的全部数据
  3. public static final int TABLE1_DIR=0;
  4. //访问table1中的单条数据
  5. public static final int TABLE1_ITEM=1;
  6. private static UriMatcher urimatcher;
  7. static{
  8. urimatcher=new UriMatcher(UriMatcher.NO_MATCH);
  9. urimatcher.addURI("com.example.app.provider", "table1", TABLE1_DIR);
  10. urimatcher.addURI("com.example.app.provider", "table1/#", TABLE1_DIR);
  11. }
  12. /**
  13. *初始化ContentProvider时使用
  14. *通常会在这里完成对数据库的创建和升级等操作
  15. *只有当存在ContentResolver尝试访问我们程序中的数据时,ContentProvider才会被初始化
  16. **/
  17.  
  18. @Override
  19. public boolean onCreate() {
  20. // TODO Auto-generated method stub
  21. return false;
  22. }
  23. /**
  24. * 提供的数据查询接口
  25. */
  26. @Override
  27. public Cursor query(Uri uri, String[] projection, String selection,
  28. String[] selectionArgs, String sortOrder) {
  29. // TODO Auto-generated method stub
  30. switch (urimatcher.match(uri)) {
  31. case TABLE1_DIR:
  32. //查询table1中所有数据
  33. break;
  34.  
  35. case TABLE1_ITEM:
  36. //查询table1中单条数据
  37. break;
  38. }
  39. return null;
  40. }
  41. /**
  42. * 提供的数据插入接口
  43. */
  44. @Override
  45. public Uri insert(Uri uri, ContentValues values) {
  46. // TODO Auto-generated method stub
  47. return null;
  48. }
  49. /**
  50. * 提供的数据删除接口
  51. */
  52. @Override
  53. public int delete(Uri uri, String selection, String[] selectionArgs) {
  54. // TODO Auto-generated method stub
  55. return 0;
  56. }
  57. /**
  58. * 提供的更新接口
  59. */
  60. @Override
  61. public int update(Uri uri, ContentValues values, String selection,
  62. String[] selectionArgs) {
  63. // TODO Auto-generated method stub
  64. return 0;
  65. }
  66. /**
  67. * 根据ContentResolver传入的URI来返回相应的MIME类型
  68. */
  69. @Override
  70. public String getType(Uri uri) {
  71. // TODO Auto-generated method stub
  72. switch (urimatcher.match(uri)) {
  73. case TABLE1_DIR:
  74. return "vnd.android.cursor.dir/vnd.com.example.app.provider.table1";
  75. break;
  76.  
  77. case TABLE1_ITEM:
  78. return "vnd.android.cursor.item/vnd.com.example.app.provider.table1";
  79. break;
  80. }
  81.  
  82. }
  83.  
  84. }

android基础(三)ContentProvider的更多相关文章

  1. <Android基础>(三) UI开发 Part 3 RecyclerView

    RecyclerView 1)RecyclerView的基本用法 2)横向滚动和瀑布流滚动 3)注册点击事件 3.6 强大的滚动控件 RecyclerView ListView缺点: 1.不使用技巧优 ...

  2. <Android基础>(三) UI开发 Part 2 ListView

    ListView 1)ListView的简单用法 2)定制ListView界面 3)提升ListView的运行效率 4)ListView的点击事件 3.5 ListView 3.5.1 ListVie ...

  3. <Android基础>(三) UI开发 Part 1

    1.常用控件 1)TextView 2)Button 3)EditText 4)ImageView 5)ProgressBar 6)AlertDialog 7)ProgressDialog 2.四种布 ...

  4. Android基础新手教程——4.4.1 ContentProvider初探

    Android基础新手教程--4.4.1 ContentProvider初探 标签(空格分隔): Android基础新手教程 本节引言: 本节给大家带来的是Android四大组件中的最后一个--Con ...

  5. Android基础夯实--重温动画(三)之初识Property Animation

    每个人都有一定的理想,这种理想决定着他的努力和判断的方向.就在这个意义上,我从来不把安逸和快乐看作生活目的的本身--这种伦理基础,我叫它猪栏的理想.--爱因斯坦 一.摘要 Property Anima ...

  6. Android基础——项目的文件结构(三)

    Android基础--项目的文件结构(三) 代码源文件夹与资源文件夹 [注]此项目文件结构仅限于Android Studio下的Android项目!!! 在一个Android项目中,代码源文件夹有4个 ...

  7. 基础4 Android基础

    基础4 Android基础 1. Activity与Fragment的生命周期. Activity生命周期 打开应用 onCreate()->onStart()->onResume 按BA ...

  8. Android开发面试经——2.常见Android基础笔试题

     标签: androidAndroid基础Android面试题Android笔试题 2015-03-12 15:04 3361人阅读 评论(3) 收藏 举报  分类: Android开发(29)  版 ...

  9. Android采访开发——2.通用Android基础笔试题

    注意finddreams博客: http://blog.csdn.net/finddreams/article/details/44219231 正值跳槽的热季.整理一下Android面试中最常考的笔 ...

  10. android四大组件--ContentProvider具体解释

    一.相关ContentProvider概念解析: 1.ContentProvider简单介绍 在Android官方指出的Android的数据存储方式总共同拥有五种,各自是:Shared Prefere ...

随机推荐

  1. MySQL配置文件mysql.ini参数详解

    my.ini(Linux系统下是my.cnf),当mysql服务器启动时它会读取这个文件,设置相关的运行环境参数. my.ini分为两块:Client Section和Server Section. ...

  2. Android自定义View (二) 进阶

    转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/24300125 继续自定义View之旅,前面已经介绍过一个自定义View的基础的例 ...

  3. WebForm水印照片

    水印照片需要的元素 绘制:1.画布2.画笔 样式 粗细 颜色3.画什么东西4.用什么字体画 大小5.位置 展示页面 <%@ Page Language="C#" AutoEv ...

  4. [问题2014A10] 复旦高等代数 I(14级)每周一题(第十二教学周)

    [问题2014A10]  设 \(A\) 为 \(n\) 阶实方阵满足 \(AA'=I_n\) (即 \(A\) 为 \(n\) 阶正交阵), 证明: \[\mathrm{rank}(I_n-A)=\ ...

  5. MAC地址泛洪攻击测试

    测试环境:kali系统(2个kali分别作攻击人和目标用户) win7系统(主机) 1.步配置FTP设置用户名密码 2.在攻击kali端测试网络的连通性 3.测试tpf是否正常 开始泛洪 4.开始抓包 ...

  6. 解决GitLab提交MergeRequest时,提示502 GitLab is not responding.的问题

    最近使用GitLab提交MergeRequest时,提示502 GitLab is not responding. 使用gitlab-ctl tail查看错误信息如下: 2014/10/28 11:5 ...

  7. linux权限,所有者、所在组、其他组(其他人员),chmod,chown

    用户组 在linux中的每个用户必须属于一个组,不能独立于组外.在linux中每个文件有所有者.所在组.其它组的概念 - 所有者 - 所在组 - 其它组 - 改变用户所在的组 所有者 一般为文件的创建 ...

  8. Linux命令基本格式及目录处理命令

    命令提示符 [root@localhost ~]# root:当前登录用户 localhost:主机名 ~:当前所在的目录,此处为"家"目录 #:root超级用户的提示符,如果是普 ...

  9. WPF+WEB+WinForm->>表现层共用类

    首先在解决方案里新建一个类库,然后在解决方案里新建三个项目,WPF,WEB,WinForm,但是这三个项目都需要一个计算类进行计算,那么就在新建的类库Calculator里面放一个Calculat.c ...

  10. zookeeper第二课 客户端的简单命令

    zookeeper的每个节点既可以是目录也可以是文件,节点上只存一些协调数据(状态.配置.位置),单位一般是KB,大部分数据用sdfs上 只有持久化的节点才可以有子节点,临时节点不可以有自子节点. 客 ...