Content Provider是Android系统四大组件之一:

官方的定义是:A Content Provider manages access to a central repository of data.

那么Android系统为什么要提供这样一个组件呢?

个人觉得至少有如下两点:

首先,Android是一个很重视安全性的系统(貌似Android系统的漏洞最多~~~),一个应用的数据对于其他应用来说私有的,除非你把数据存储在SD卡上。但很多时候我们需要在程序之间共享数据,比如我们想获取联系人的信息之类的。这时Content Provider就提供了一个很好的解决方案,将数据的存储、读取细节隐藏,提供一个统一的接口供其它应用访问,并且还可以做到权限控制,在一定程度上保证数据的安全性。

其次就是进程间通信(inter-process communication IPC)的问题,如果让开发者自己来处理这些细节无疑会加大开发的难度。而Content Provider提供了类似于b/s结构的模式,b与c之间是以一种什么方式去实现我们并不关心,就像我们大部分时候不用去关心网络到底是怎么连接的。开发者应该关心的是怎么去实现一个Content Provider或去调用一个Content Provider。

URI(Uniform Resource Identifier)统一资源标识符

URI和URL(Unifrom Resource Locator)很像,但两者并不是同一个东西,不过可以拿来做类推。

对于一个content URI的一般形式是这样子的:

content://user_dictionary/words

其中“content://”称为scheme,类似于http://或ftp://,表示这个URI的类型。

“user_dictionary”就类似于域名,但在这里应该叫做authority(这个怎么翻译呢?)。它是一个用来标识不同content provider的名称。

“words”这里用于表示对哪一个表进行操作。注意,这里这么说是不准确的!

首先content provider的数据源不一定就是关系型数据库,可以是xml,数据文件甚至是网络数据。

其次,就算是SQLite之类的数据库,这一部分也不一定就真的是一个真实存在的表,它可能就是某个视图而已,这里说它是某一个表只是方便理解,切记!

如何创建一个Uri呢?

第一种:可以用Uri.Builder来创建:

Uri.Builder builder = new Uri.Builder();

builder.scheme("content");

builder.authority("user_dictionary");

builder.path("words");

Uri uri = builder.build();

还有一种更简单的方法,就是使用Uri.Parse()方法:

Uri uri = Uri.parse("content://user_dictionary/words");

显然,第二种要简洁得多了。

有些content provider支持直接查询到某一条记录,就是在上面提到Uri的末尾再加上一个id如:

content://user_dictionary/words/2

就表示直接定位到某一个记录上。构建这种Uri有一个简单的方法

Uri uri = Uri.parse("content://user_dictionary/words");

Uri singleUri = ContentUris.withAppendedId(uri, 4);

从content provider中检索数据:

使用一个content provider主要有如下几个步骤:

在AndroidManifest.xml文件中添加相应的权限。

如,想要查看系统的通话记录应该添加

<uses-permission android:name="android.permission.READ_CALL_LOG" />

要注意,content provider读写权限是分开的,读就只能读,写就只能写(不像写外部存储卡那个权限,它其实还含有读的权限)。比如同时还要修改通话记录的话,还应该添加这个权限:

<uses-permission android:name="android.permission.WRITE_CALL_LOG" />

使用ContentResolver的query方法。该方法的签名是这样的:

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

如果比较熟悉SQLite的应该对这些参数相当熟悉。不就是把一个SQL语句分成几个部分嘛。

这个方法将返回一个Cursor,通过这个“游标”我们就可以得到我们想要的数据了。

下面给一个获取通话记录的例子:

    public void getData() {

        String[] projection = {
Calls.NUMBER,
Calls.DATE,
Calls.DURATION,
Calls.TYPE
};
Cursor cursor = getContentResolver().query(Calls.CONTENT_URI, projection, null, null, null);
while (cursor.moveToNext()) {
for (int i = 0; i < cursor.getColumnCount(); i++) {
System.out.println(cursor.getColumnName(i) + "--->" + cursor.getString(i));
}
System.out.println("~~~~~~~~~~~~~~~~");
}
cursor.close();
}

其他方法其实也都是差不多的,看看文档可以掌握了,如果还觉得比较难懂,建议先学一下SQLite的使用。

Android学习笔记——Content Provider(一)的更多相关文章

  1. Android学习总结——Content Provider

    原文地址:http://www.cnblogs.com/bravestarrhu/archive/2012/05/02/2479461.html Content Provider内容提供者 : and ...

  2. 【转】Pro Android学习笔记(七):了解Content Provider(下上)

    我们通过一个Content Provider小例子进行详细说明.数据源是一个SQLite数据库,名字为books.db,该数据库只含有一个表格,名字为books.表格中含有name,isbn,auth ...

  3. 【转】Pro Android学习笔记(五):了解Content Provider(上)

    Content Provider是抽象数据封装和数据访问机制,例如SQLite是Android设备带有的数据源,可以封装到一个content provider中.要通过content provider ...

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

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

  5. udacity android 学习笔记: lesson 4 part b

    udacity android 学习笔记: lesson 4 part b 作者:干货店打杂的 /titer1 /Archimedes 出处:https://code.csdn.net/titer1 ...

  6. 【转】 Pro Android学习笔记(七五):HTTP服务(9):DownloadManager

    目录(?)[-] 小例子 保存在哪里下载文件信息设置和读取 查看下载状态和取消下载 文章转载只能用于非商业性质,且不能带有虚拟货币.积分.注册等附加条件,转载须注明出处:http://blog.csd ...

  7. 【转】 Pro Android学习笔记(五五):调试和分析(3):adb命令、模拟器控制台和StrictMode

    目录(?)[-] adb命令 模拟器Console StrictMode adb命令 我们在学习SQLite的使用,介绍过部分adb命令的使用,见Pro Android学习笔记(五):了解Conten ...

  8. 【转】 Pro Android学习笔记(五六):配置变化

    目录(?)[-] Activity的destorycreate过程 Fragment的destorycreate过程 onSaveInstanceState saveFragmentInstanceS ...

  9. 【转】 Pro Android学习笔记(二二):用户界面和控制(10):自定义Adapter

    目录(?)[-] 设计Adapter的布局 代码部分 Activity的代码 MyAdapter的代码数据源和构造函数 MyAdapter的代码实现自定义的adapter MyAdapter的代码继续 ...

随机推荐

  1. python之pygal:掷一个骰子统计次数并以直方图形式显示

    源码如下: # pygal包:生成可缩放的矢量图形文件,可自适应不同尺寸的屏幕显示 # 安装:python -m pip intall pygal-2.4.0-py2.py3-none-any.whl ...

  2. 华为5G在印度被禁

    前段时间,澳大利亚政府以“担心外国渗透”为由,决定禁止华为为建设新的5G网络提供设备.这让大家不禁猜测,难道华为的5G真的被国外市场禁入了? 对此,华为表达出了极大的失落感,并在一份声明中称,“政府告 ...

  3. C++拷贝构造函数与 = 重载

    调用拷贝构造函数进行初始化的时候,是不会调用=重载的. // test.cpp : 定义控制台应用程序的入口点. // //#include "stdafx.h" #include ...

  4. BZOJ3419[POI2013]taxis——贪心

    题目大意: 一条线段有三个点,0为初始位置,d为出租车总部位置,m为家的位置,人要叫车,有n辆车可以提供,每辆车有一个路程上限,并且都从车站出发,叫的车行驶之后不必须回到车站,问最少叫几辆车. 一定能 ...

  5. BZOJ5371[Pkusc2018]星际穿越——可持久化线段树+DP

    题目描述 有n个星球,它们的编号是1到n,它们坐落在同一个星系内,这个星系可以抽象为一条数轴,每个星球都是数轴上的一个点, 特别地,编号为i的星球的坐标是i. 一开始,由于科技上的原因,这n个星球的居 ...

  6. echarts之简单的入门——【二】再增加一个柱状图和图例组件

    echarts之简单的入门——[一]做个带时间轴的柱状统计图 现在需求说,我需要知道日答题总次数和活跃人数,那么我们如何在上面的图表中增加一个柱状图呢? 如果你看过简单入门中的配置项手册中series ...

  7. CQOI2009叶子的染色

    叶子的染色 题目描述 给一棵m个结点的无根树,你可以选择一个度数大于1的结点作为根,然后给一些结点(根.内部结点和叶子均可)着以黑色或白色.你的着色方案应该保证根结点到每个叶子的简单路径上都至少包含一 ...

  8. 洛谷P4072 [SDOI2016]征途(带权二分,斜率优化)

    洛谷题目传送门 一开始肯定要把题目要求的式子给写出来 我们知道方差的公式\(s^2=\frac{\sum\limits_{i=1}^{m}(x_i-\overline x)^2}{m}\) 题目要乘\ ...

  9. luogu3320 寻宝游戏 (dfs序+倍增lca+set)

    一定是从随便某个点开始,然后按着dfs序的顺序跑一圈是最好的 所以说,新加一个点x,就减少了dis(pre,next),增加了dis(pre,x),dis(x,nxt) 删掉一个点同理 这个可以用se ...

  10. ubuntu 13.04 开发环境搭建

    install ubuntu1, mysql serversudo apt-get install mysql-server2, ssh sudo apt-get install openssh-se ...