ContentProvider向我们提供了我们在应用程序之间共享数据的一种机制,分为系统的和自定义的,系统的也就是例如联系人,图片等数据。

使用方式:一个应用实现ContentProvider来提供内容给别的应用来操作,一个应用通过ContentResolver来操作别的应用数据,当然在自己的应用中也可以。

  内容提供者将一些特定的应用程序数据供给其它应用程序使用。内容提供者继承于ContentProvider 基类,为其它应用程序取用和存储它管理的数据实现了一套标准方法。然而,应用程序并不直接调用这些方法,而是使用一个 ContentResolver 对象,调用它的方法作为替代。ContentResolver可以与任意内容提供者进行会话,与其合作来对所有相关交互通讯进行管理。

使用ContentProvider共享数据

1ContentProvider类主要方法的作用:

  public boolean onCreate():ContentProvider在其它应用第一次访问它时才会被创建,创建后就调用该方法

  public Uri insert(Uri uri, ContentValues values):该方法用于供外部应用往ContentProvider添加数据。

  public int delete(Uri uri, String selection, String[] selectionArgs):该方法用于供外部应用从ContentProvider删除数据。

  public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs):更新ContentProvider中的数据。

  public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder):获取数据。

  public String getType(Uri uri):该方法用于返回当前Url所代表数据的MIME类型。

2如果操作的数据属于集合类型,那么MIME类型字符串应该以vnd.android.cursor.dir/开头

  例如:要得到所有person记录的Uri为content://com.bing.provider.personprovider/person,那么返回的MIME类型字符串应该为:"vnd.android.cursor.dir/person"

3如果要操作的数据属于非集合类型数据,那么MIME类型字符串应该以vnd.android.cursor.item/开头,

  例如:得到id为10的person记录,Uri为content://com.bing.provider.personprovider/person/10,那么返回的MIME类型字符串为:"vnd.android.cursor.item/person"。

ContentResolver操作数据

  1使用ContentResolver 类来完成对ContentProvider中的数据进行增删改查操作时。要获取ContentResolver 对象,可以使用Activity提供的getContentResolver()方法。

  2ContentResolver 类提供了与ContentProvider类相同签名的四个方法:

    public Uri insert(Uri uri, ContentValues values):该方法用于往ContentProvider添加数据。

    public int delete(Uri uri, String selection, String[] selectionArgs):该方法用于从ContentProvider删除数据。

    public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs):更新ContentProvider中的数据。

    public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder):获取数据。

  这些方法的第一个参数为Uri,代表要操作的ContentProvider和对其中的什么数据进行操作,其实和ContentProvider里面的方法是一样的。他们所对应的数据,最终是会被传到我们在之前程序里面定义的那个ContentProvider类的方法,假设给定的是:Uri.parse("content://com.bing.providers.personprovider/person/10"),那么将会对主机名为com.bing.providers.personprovider的ContentProvider进行操作,操作的数据为person表中id为10的记录。

使用ContentResolverContentProvider中的数据进行添加、删除、修改和查询操作:

ContentResolver resolver =  getContentResolver();

Uri uri = Uri.parse("content://com.bing.provider.personprovider/person");

//添加一条记录

ContentValues values = new ContentValues();

values.put("name", "bingxin");

values.put("age", 25);

resolver.insert(uri, values);  //链接到à ContentProvider.instert(uri,values)

//获取person表中所有记录

Cursor cursor = resolver.query(uri, null, null, null, "personid desc");

while(cursor.moveToNext()){

Log.i("ContentTest", "personid="+ cursor.getInt(0)+ ",name="+ cursor.getString(1));

}

//把id为1的记录的name字段值更改新为zhangsan

ContentValues updateValues = new ContentValues();

updateValues.put("name", "zhangsan");

Uri updateIdUri = ContentUris.withAppendedId(uri, 2);

resolver.update(updateIdUri, updateValues, null, null);

//删除id为2的记录

Uri deleteIdUri = ContentUris.withAppendedId(uri, 2);

resolver.delete(deleteIdUri, null, null);

监听ContentProvider中数据的变化

  如果ContentProvider的访问者需要知道ContentProvider中的数据发生变化,可以在ContentProvider发生数据变化时调 用getContentResolver().notifyChange(uri, null)来通知注册在此URI上的访问者,例子如下:

  1) 发送通知

public class PersonContentProvider extends ContentProvider {

public Uri insert(Uri uri, ContentValues values) {

db.insert("person", "personid", values);

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

}

}

  2) 注册监听:使用ContentObserver对数据(数据采用uri描述)进行监听,当监听到数据变化通知时,系统就会调用ContentObserver的onChange()方法:

  getContentResolver().registerContentObserver(

                Uri.parse("content://com.ljq.providers.personprovider/person"),

                true,

                new PersonObserver(new Handler()));

  public class PersonObserver extends ContentObserver{

    public PersonObserver(Handler handler) {

      super(handler);

    }

    public void onChange(boolean selfChange) {

      //此处可以进行相应的业务处理

    }

  }

 

  • Uri介绍

  为系统的每一个资源给起一个名字,如:

  Uri uri = Uri.parse("content://com.changcheng.provider.contactprovider/contact")

  content://media/internal/images  //这个URI将返回设备上存储的所有图片

  content://contacts/people/               //这个URI将返回设备上的所有联系人信息

  content://contacts/people/45     //这个URI返回单个结果(联系人信息中ID为45的联系人记录)

  1)每一个ContentProvider都拥有一个公共的URI,这个URI用于表示这个ContentProvider所提供的数据。

  2)Android所提供的ContentProvider都存放在android.provider包中。 将其分为4个部分:

     A:标准前缀(”content://”),,用来说明一个Content Provider控制这些数据,无法改变的

B:URI 的标识(“com.changcheng.provider.contactprovider”),用于唯一标识这个ContentProvider,外部调用者可以根据这个标识来找到它。它定义了是哪个Content Provider提供这些数据。对于第三方应用程序,为了保证URI标识的唯一性,它必须是一个完整的、小写的类名。这个标识在元素的 authorities属性中说明:一般是定义该ContentProvider的包.类的名称。

  C:路径(”contact”),通俗的讲就是你要操作的数据库中的名字,或者你也可以自己定义,记得在使用的时候保持一致就可以了。

  D:(可选)如果URI中包含表示需要获取的记录的ID,则就返回该id对应的数据;如果没有ID,就表示返回全部。

PS路径可以用来表示我们要操作的数据,路径的构建应根据业务而定,如下:1、要操作person表中id为10的记录的name字段, person/10/name;2、要操作xxx表中的记录,可以构建这样的路径:/xxx;3、当然要操作的数据不一定来自数据库,也可以是文件、xml或网络等其他存储方式,如下:要操作xml文件中person节点下的name节点,可以构建这样的路径:/person/name

  因为Uri代表了要操作的数据,所以我们经常需要解析Uri,并从Uri中获取数据。Android系统提供了两个用于操作Uri的工具类,分别为UriMatcherContentUris

  • ContentUris类使用介绍

  ContentUris类用于操作Uri路径后面的ID部分,它有两个比较实用的方法:

  1. withAppendedId(uri, id)用于为路径加上ID部分:

Uri uri = Uri.parse("content://com.bing.provider.personprovider/person")

Uri resultUri = ContentUris.withAppendedId(uri, 10);

//生成后的Uri为:content://com.bing.provider.personprovider/person/10

  1. parseId(uri)方法用于从路径中获取ID部分

Uri uri = Uri.parse("content://com.ljq.provider.personprovider/person/10")

long personid = ContentUris.parseId(uri);//获取的结果为:10

  • UriMatcher类使用介绍

  UriMatcher类用于匹配Uri,它的用法如下:

//常量UriMatcher.NO_MATCH表示不匹配任何路径的返回码

UriMatcher  sMatcher = new UriMatcher(UriMatcher.NO_MATCH);

//如果match()方法匹配content://com.bing.procvide.personprovider/person路径,返回匹配码为1

sMatcher.addURI("com.bing.procvide.personprovider", "person", 1);//添加需要匹配uri,如果匹配就会返回匹配码

//如果match()方法匹配content://com.bing.provider.personprovider/person/230路径,返回匹配码为2

sMatcher.addURI("com.bing.provider.personprovider", "person/#", 2);//#号为通配符

switch (sMatcher.match(Uri.parse("content://com.ljq.provider.personprovider/person/10"))) {

case 1:  // persion dir

break;

case 2:  // persion item

break;

default: //不匹配

break;

}

  注册完需要匹配的Uri后,就可以使用sMatcher.match(uri)方法对输入的Uri进行匹配,如果匹配就返回匹配码,匹配码是调用addURI()方法传入的第三个参数。

  假设匹配content://com.ljq.provider.personprovider/person路径,返回的匹配码为1。

1.3 Content Provider的更多相关文章

  1. Android Content Provider Guides

    Android Content Provider Guides Content Providers管理对结构化数据集的访问.它们包装数据,并且提供一种定义数据安全的机制. Content provid ...

  2. Android Content Provider基础

    Android Content Provider基础 Content Providers Content providers管理对一个结构化的数据集合的访问.它们封装了数据,并且提供了保护数据安全性的 ...

  3. Android 内容提供器(Content Provider)介绍

    内容提供器(Content Provider)主要用于在不同的应用程序之间实现数据共享的功能,它提供了一套完整的机制,允许一个程序访问另一个程序中的数据,同时还能保证被访问数据的安全性.目前,使用内容 ...

  4. Android学习五:Content Provider 使用

    1ContentProvider相关知识1.1在安卓应用中,通过文件方式对外共享数据,需要进行文件操作读写数据:采用sharedpreferences共享数据,需要使用sharedpreference ...

  5. Android应用安全之Content Provider安全

    android平台提供了Content Provider,将一个应用程序的指定数据集提供给其它应用程序.这些数据可以存储在文件系统.SQLite数据库中,或以任何其它合理的方式存储.其他应用可以通过C ...

  6. Android数据的四种存储方式SharedPreferences、SQLite、Content Provider和File (一) —— 总览

    Android数据的四种存储方式SharedPreferences.SQLite.Content Provider和File (一) —— 总览   作为一个完成的应用程序,数据存储操作是必不可少的. ...

  7. ContentProvider官方教程(1)何时用content provider

    Content Providers Content providers manage access to a structured set of data. They encapsulate the ...

  8. Android Contacts (android通讯录读取)-content provider

    Content Provider 在数据处理中,Android通常使用Content Provider的方式.Content Provider使用Uri实例作为句柄的数据封装的,很方便地访问地进行数据 ...

  9. Android开发-API指南-创建 Content Provider

    Creating a Content Provider 英文原文:http://developer.android.com/guide/topics/providers/content-provide ...

随机推荐

  1. MVC 自定义IModelBinder实现json参数转Dictionary<string, string>

    IModelBinder的学习不算深入,现在用它来实现一个json转Dictionary<string, string> 一.原始json转Dictionary<string, st ...

  2. ASP.NET 操作Cookie详解 增加,修改,删除

    ASP.NET 操作Cookie详解 增加,修改,删除 Cookie,有时也用其复数形式Cookies,指某些网站为了辨别用户身份而储存在用户本地终端上的数据(通常经过加密).定义于RFC2109.它 ...

  3. Junit测试中的setup和teardown 和 @before 和 @After 方法

    这几天做Junit测试接触到了setup和teardown两个方法,简单的可以这样理解它们,setup主要实现测试前的初始化工作,而teardown则主要实现测试完成后的垃圾回收等工作. 需要注意的是 ...

  4. 网络存储技术介绍(2) ( based on zt)

    http://www.educity.cn/tx/429084.html 互联网技术DAS.NAS和SAN存储方案的比较 按照设备位置和接入方式,磁盘存储可以分为内置存储和外挂存储,外挂存储又分为直连 ...

  5. HDOJ(1242)BFS+优先队列

    Rescue http://acm.hdu.edu.cn/showproblem.php?pid=1242 题意:"#"是墙,"."是路,"a&quo ...

  6. MySql中的tinying,smallint,int,bigint的类型介绍——转载

    tinyint 从 0 到 255 的整型数据.存储大小为 1 字节. smallint 从 -2^15 (-32,768) 到 2^15 – 1 (32,767) 的整型数据.存储大小为 2 个字节 ...

  7. VC MFC在CMFCToolBar工具栏中加入组合框

    如何在CMFCToolBar工具栏中加入组合框等控件,且先看在线MSDN上怎么说的: 要增加一个组合框,需要完成以下步骤: 1.在工具栏资源中,增加一个对应ID资源号的按钮. 2.在主框架(mainf ...

  8. 使用CocoaPods配置工程

    1.首先搭建环境,配置CocoaPods,具体请参考 http://code4app.com/article/cocoapods-install-usage 2.打开终端,输入 cd 空格 把工程拖入 ...

  9. makefile多目录的.c 格式.cpp混合编译

    # # c.cpp混合编译的makefile模板 # # BIN = test.exe CC = gcc CPP = g++ #这里只加入库头文件路径及库路径 INCS = -I"c:/mi ...

  10. JS出现illegal character非法字符提示

    引用js文件,js文件内的汉字在页面显示乱码 解决方式: a. 保持js文件编码与jsp页面编码格式一致: b. 在引入js文件时,在script中添加charset=""属性,指 ...