四大组件之ContentProvider(一)-使用系统提供的ContentProvider

来源:互联网 发布:unity3d asset store 编辑:程序博客网 时间:2024/06/04 00:04
更新时间 修改意见 2016-08-02 陈敏

第1节 ContentProvider介绍

ContentProvider是安卓系统的四大组件之一,可以向其他组件提供数据访问的能力。它就像是一个网站,其他组件(或者其他应用)可以通过“网址”访问它,获取需要的信息。因此它可以作为不同应用之间共享数据的一种方式。

1.1 基础功能

我们操作一个应用的数据,无外乎四种操作方式,

  • 增:添加新的数据;
  • 删:删除已有的数据;
  • 改:修改已经的数据;
  • 查:查询已有的数据;

所以一个ContentProvider要对外提供这四种最基础的功能至少一种。

1.2 操作的对象

对数据的操作范围无外乎,

  • 单条数据的操作:每一次操作增加一条数据,删除一条数据,修改一条数据,查询特定一条数据的详细内容;
  • 多条数据的操作:每一次操作增加多条数据,删除多条数据,修改多条数据,查询符合某个特征的多条数据;

例如,我们可能会向书架上“一次放一本书”-单条增,“一次取下一本书”-单条删,“一次问书架上有多少书”-多条查。

因此,仿照网站地址的设计方式,我们可以用如下的“网络地址”来表达我们希望进行的操作是针对单一一条数据还是同时多条数据:

  • xxx.xxx.xxx/items/1:针对单一一条数据,最后的数字代表特定一本书的编号(也可以使用书的名字来代替);
  • xxx.xxx.xxx/items:针对多条数据;

“网站”只要看到以上的格式就知道,要操作的是一条数据还是多条数据了。

每个ContentProvider就是一个“网站”,每个网站都有自己的“网址”。安卓系统为这个“网址”设计了如下的结构,

scheme://authority/path
  1. scheme:固定为“content”,相当于一个网址的“http”;
  2. authority:由开发者自己确定,通常把它写成这个ContentProvider的包名,例如“com.anddle.mycontentprovider”,它就相当于网址的地址“www.google.com”;
  3. path:根据查询内容的逻辑,由开发者自己决定,通常要分成多条数据和单一数据两类;

典型的例子就像这样,

多条数据content://com.anddle.mycontentprovider/items单一数据content://com.anddle.mycontentprovider/items/1

这里面,
scheme:“content”
authority:“com.anddle.mycontentprovider”
path:“items”或者“items/1”

只要定义好了前面两种原则,外界(其他组件或者其他应用)就可以获取到ContentProvider中的内容了。


/*******************************************************************/
* 版权声明
* 本教程只在CSDN和安豆网发布,其他网站出现本教程均属侵权。
/*******************************************************************/

第2节 使用ContentProvider

安卓系统上,提供了很多系统级的ContentProvider,我们可以直接使用。例如,

  1. Media Provider:用来查询磁盘上多媒体文件;
  2. Contacts Provider:用来查询联系人信息;
  3. Calendar Provider:用来提供日历相关信息的查询;
  4. Bookmark Provider:用来提供书签信息的查询;

它们的用法大同小异,只要使用它们对应的Uri地址就可以进行增删改查的操作了。

这里我们就用Media Provider来讲解。

2.1 MediaProvider

Media Provider作为系统级别的应用程序在系统上运行,专门负责收集多媒体文件(音频、视频、文件)相关的信息。

Media Provider在开机启动后,会在后台“监听”磁盘上文件的变化,特定情况下,会自动更新媒体文件的信息,例如磁盘上是否增加了媒体文件,是否被删除了媒体文件,有的媒体文件名称是否发生了修改等等。

所以当任何应用想获取这类文件相关的信息时,就可以向Media Provider发起查询的请求。Media Provider帮我们完成了媒体文件信息的收集。因此,当我们要查询磁盘上的多媒体信息时,就不用自己去遍历磁盘上的文件进行收集和整理了。

2.2 Media Provider查询视频文件

  1. 确定向Media Provider发出查询请求的地址-uri,我们要查询的视频文件都是存放在外部存储地址上的,就使用指向外部存储的uri;

    //uri就是:content://media/external/video/media"Uri uri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
  2. 确定要请求的视频文件信息。我们需要查询视频的标题、创建时间,还需要播放它时使用的文件所在地址。这些信息在Media Provider中都对应着查询它们使用的字段名称;

    String[] searchKey = new String[] {MediaStore.Video.Media.TITLE, -->对应文件的标题MediaStore.Images.Media.DATA, -->对应文件的存放位置MediaStore.Images.Media.DATE_ADDED -->对应文件的创建时间};
  3. 确定查询的条件。这个条件参数的写法就和SQL数据库语言的语法一样。这里我们不打算讲SQL语法,需要各位自己去学习了;设置成空,表示查询所有数据项,

    String where = null;
  4. 设定查询结果的排序方式,使用默认的排序方式就可以了,

    String sortOrder = MediaStore.Video.Media.DEFAULT_SORT_ORDER;
  5. 获取ContentResolver对象,让它使用前面的参数向Media Provider发起查询请求;查询的结果存放在Cursor--游标当中;

    ContentResolver resolver = getContentResolver();Cursor cursor = resolver.query(                uri,                searchKey,                 where,                 null,                 sortOrder);
  6. 遍历Cursor,得到它指向的每一条查询到的信息;当Cursor指向某条数据的时候,我们就获取它携带的每个字段的值;

    while(cursor.moveToNext()){    String path = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA));    String name = cursor.getString(cursor.getColumnIndex(MediaStore.Video.Media.TITLE));    String createdTime = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATE_ADDED));    ......  }
  7. Cursor使用完了之后要把它关闭掉,

    cursor.close();

整理一下前面的各个步骤,获取外部存储上的视频资源,方式如下,

Uri uri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;String[] searchKey = new String[] {    MediaStore.Video.Media.TITLE,    MediaStore.Images.Media.DATA,    MediaStore.Images.Media.DATE_ADDED};String [] keywords = null;String where = null;String sortOrder = MediaStore.Video.Media.DEFAULT_SORT_ORDER;ContentResolver resolver = getContentResolver();Cursor cursor = resolver.query(                    uri,                    searchKey,                     where,                     keywords,                     sortOrder);if(cursor != null){    while(cursor.moveToNext())    {        String path = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA));        String name = cursor.getString(cursor.getColumnIndex(MediaStore.Video.Media.TITLE));        String createdTime = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATE_ADDED));        ......      }    cursor.close();}

最后一点千万不要忘记,因为视频文件存放在外部存储器中,所以要在应用的AndroidManifest.xml文件中,添加读取外部存储器的权限,

<manifest xmlns:android="http://schemas.android.com/apk/res/android"    package="com.anddle.anddleplayer">    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />    ......</manifest>

/*******************************************************************/
* 版权声明
* 本教程只在CSDN和安豆网发布,其他网站出现本教程均属侵权。

*另外,我们还推出了Arduino智能硬件相关的教程,您可以在我们的网店跟我学Arduino编程中购买相关硬件。同时也感谢大家对我们这些码农的支持。

*最后再次感谢各位读者对安豆的支持,谢谢:)
/*******************************************************************/

2 0
原创粉丝点击