黑马程序员技术交流社区

标题: 【阳哥专栏】黑马Android教程-Android基础09ContentProvider [打印本页]

作者: 王震阳老师    时间: 2015-3-23 21:47
标题: 【阳哥专栏】黑马Android教程-Android基础09ContentProvider
本帖最后由 王震阳老师 于 2015-3-23 21:50 编辑


黑马程序员上海校区招生火爆开启!阳哥约你在上海!









pdf附件回复可下载:

1. ContentProvider简介(★★★
ContentProvider即内容提供者,是Android的四大组件之一。内容提供者是应用程序之间共享数据的接口,Android系统将这种机制应用到方方面面。比如:联系人Provider专为不同应用程序提供联系人数据;设置Provider专为不同应用程序提供系统配置信息,包括内置的设置应用程序等。当应用继承ContentProvider类,并重写该类用于提供数据和存储数据的方法,就可以向其他应用共享其数据。虽然使用其他方法也可以对外共享数据,但数据访问方式会因数据存储的方式而不同,如:采用文件方式对外共享数据,需要进行文件操作读写数据;采用SharedPreferences共享数据,需要使用SharedPreferences API读写数据。而使用ContentProvider共享数据的好处是统一了数据访问方式。
1.1创建一个ContentProvider
:为了方便演示ContentProvider的使用,我们下面将编写一个案例,跟着案例一点点学习ContentProvider的用法,相信当大家能独自把该案例写出来的时候也是我们基本掌握ContentProvider使用方法的时候。
:在本应用下创建一个person数据库,对外提供一个ContentProvider接口,使外部程序可以通过我们提供的ContentProvider接口对我们的person数据库进行增删改查操作。
新创建一个Android工程,工程名《MyContentProvider》,包名:com.itheima.provider。
在com.itheima.provider.dao包下新建一个PersonOpenHelper类继承SQLiteOpenHelper类,该类用于创建数据库。
在com.itheima.contenProvider.provider包中创建,PersonContentProvider类继承ContentProvider类。同时将该Provider在AndroidManifest.xml中注册。
PersonContentProvider类是核心业务代码,也是本文档的重要内容,代码清单如下:
1.2访问ContentProvider
外部程序只需知道内容提供者的Uri路径信息,通过ContentResolver即可调用内容提供者。

Uri的组成:
schema,用来说明一个ContentProvider控制这些数据。 "content://"
主机名或授权Authority:它定义了是哪个ContentProvider提供这些数据。
path:路径,URI下的某一个Item。
ID:通常定义Uri时使用”#”号占位符代替, 使用时替换成对应的数字
content://com.itheima.provider/person/#:#表示数据id(#代表任意数字)
        content://com.itheima.provider/person/*:*来匹配任意文本。
:为了演示如何调用ContentProvider,我们新建一个Android测试工程,访问本文档1.1章节中提供的数据。
新创建一个Android工程,工程名《TestContentProvider》,包名:com.itheima.contentProviderTest。
在AndroidManifest.xml中添加instrumentation和uses-library。
:其中instrumentation放在清单文件的manifest节点下,uses-library放在application节点下。
在com.itheima.contentProviderTest包下,新建TestContentProvider类,在该类中实现核心方法,调用1.1章节中ContentProvider。
测试insert方法
:在我第一次做测试时报了如下图表中的异常,意思就是我没有权限访问com.itheima.contenProvider包中提供的ContentProvider,原因是我忘记了在1.1章节中AndroidManifest.xml文件中给provider标签添加 android:exported="true" 属性,该属性的意思是是否对外发布,系统默认为false,这里一定记住要设置为true。
测试update方法
测试delete方法
测试query(单个)方法
测试query(多个)方法

2. 案例-短信的备份和恢复(★★★★
Android系统中提供了一系列的内容提供者,通过调用他们,可以获取一些系统的信息,比如:短信信息,联系人信息等。
:在应用界面有备份短信、恢复短信两个按钮,点击该按钮会将当前短信备份到XML文件中,同时XML文件被存储在存储卡中。点击恢复短信按钮,程序会将XML文件中的短信插入到手机中存储短信的数据库中。在备份和恢复的过程中有进度条显示完成情况。
2.1准备知识
打开Android源码,查看packages\providers\路径下的工程,这些就是Android系统中的内容提供者,其中TelephonyProvider就是短信的内容提供者文件。
打开TelephonyProvider下的src文件,查看java文件,其中的SmsProvider.java即短信息内容提供者逻辑代码。UriMatcher一般在静态代码块中进行初始化操作,查找静态代码块,找到的逻辑代码如下:
在数据库中sms表就是用于存储短信的,所以通过查找系统源码,可以确定短信息内容提供者的Uri应该为:”content://sms”
查看Android模拟器下的com.android.providers.telephony,查看其mmssms.db文件
打开数据库,其中sms表存储的就是短信的数据,其存储格式如下:
其中,address存储的是联系人号码,date是发送日期,type对应短信的类型(发送/接收),body是短信的主体内容,准备备份这四项。
2.2实现步骤
新创建一个新的Android工程《短信备份And恢复》,包名:com.itheima.smsbackup。在com.itheima.smsbackup.bean包中创建Sms类,用于封装短信数据。
创建XML工具类,用于生成XML和解析XML。
编写界面布局文件,这里使用默认生成的布局文件activity_main.xml
编写默认的MainActivity类,实现核心方法。
备份短信功能代码清单
恢复短信功能代码清单
为当前工程添加权限。在AndroidManifest.xml中添加权限声明。
将本工程部署到模拟器上,运行,并测试。发现我们成功将短信备份到了存储卡中。通过DDMS,我们可以看到在mnt/sdcard/smsbackup目录下多了sms.xml文件。
程序运行界面比较简单,效果如下图:
:在该工程中,短信的恢复逻辑比较简单,只是把sms.xml文件中的所有短信插入到短信数据库中,其实如果短信数据库中还有相同的短信的时候我们这样处理的结果是数据库中有了2份相同的短信,因此比较好的做法是在插入数据库之前先判断该短信是否存在,如果存在则不插入。
3. 操作系统联系人(★★★★3.1准备知识
通过DDMS,查看Android模拟器下的com.android.providers.contacts包下的数据库,查看其contact2.db数据库的内容。
查看数据库,其中raw_contacts表存放的是联系人条数信息,data表中存放的是raw_contacts中的每一条id对应的具体信息,不同类型的信息由mimetype_id来标识。
raw_contacts表:
data表:
mimetypes表:
打开Android源码,查看packages\providers\路径下的文件,其中ContactsProvider就是联系人的内容提供者。
操作raw_contacts表的Uri:
操作data表的Uri:
比如:data表在查询的时候没有mimetype_id,取代的是mimetype
3.2操作系统联系人
步骤:
新建一个Android工程《操作系统联系人》。包名:com.itheima.contacts。
使用默认生成的布局文件和MainActivity类。在布局文件里将用户联系人展示在ListView中,因此我们需要为ListView的Item创建一个布局文件,由于该布局文件比较简单,因此我们只给出效果图,布局文件清单就不再给出。activity_main.xml文件清单:
想想还是将list_item.xml的布局给出吧,哎,任性了。

编写MainActivity类代码,在这里我们用到了自定义的Contact对象,用于封装属性,比较简单因此就不再给出Contact类代码清单。



在AndroidManifest.xml中添加添加如下权限:
部署该工程于模拟器。点击获取联系人,然后在点击插入联系人,然后在点击获取联系人。发现我们不仅成功的将所有的联系人读取出来了同时也将新联系人插入到了数据库中。
运行效果图如下:

4. ContentObserver简介(★★★
ContentObserver——内容观察者,目的是观察(捕捉)特定Uri引起的数据库的变化,继而做一些相应的处理,它类似于数据库技术中的触发器(Trigger),当ContentObserver所观察的Uri发生变化时,便会触发它。触发器分为表触发器、行触发器,相应地ContentObserver也分为“表“ContentObserver、“行”ContentObserver,当然这是与它所监听的Uri MIME Type有关的。
学习过Content Provider(内容提供者)的我们都知道,可以通过UriMatcher类注册不同类型的Uri,可以通过这些不同的Uri来查询不同的结果。根据Uri返回的结果,Uri Type可以分为:返回多条数据的Uri、返回单条数据的Uri。
使用ContentObserver的步骤我这里总结如下:
在下面第5章节中,我将用一个案例来演示ContentObserver的用法。
5. 案例-短信窃听(★★★★
用户使用系统自带的短信程序发送短信,程序会通过ContentProvider把短信保存进数据库,并且发出一个数据变化通知,使用ContentObserver对数据变化进行监听,在用户发送短信时,就会被ContentObserver窃听到短信。
发出的短信有这样几个过程:草稿箱->发件箱->已发送。所以只需查询发件箱中的信息即可,处于正在发送状态的短信放在发送箱中。
:创建一个应用程序,监听用户发送的短信。
新创建一个Android工程《短信窃听》,包名:com.itheima.contentObserver。
新创建一个SmsContentObserver类继承ContentObserver类,覆写onChange方法。在该方法中实现核心业务逻辑。
在MainActivity类中注册SmsContentObserver。
因为我们读取系统短信了,因此需要在AndroidManifest.xml中添加权限。
将该工程部署在模拟器上并运行,然后打开短息功能,给5557模拟器(可以随意指定个号码,不需要启动5557模拟器)发送一条短信。观察LogCat发现,我们的ContentObserver成功监听到了短信内容。
6. 使用ContentObserver监听自定义的ContentProvider(★★★
在第5章节中,我们通过ContentObserver实现了对系统发送短信的监听。这是因为系统短信数据数据库中插入新的短信的时候通过ContentResolver调用了notifyChange方法,正是该方法对外发出了消息,这样我们的ContentObserver才监听到了短信的发送。
那么我们也可以自定义我们的ContentProvider,在ContentProvider中发送消息,被我们的ContentObserver监听到。
为了方便演示,我们直接使用该文档1.1章节中创建的工程《MyContentProvider》。我们修改PersonContentProvider类中的insert方法,当有新用户插入数据库的时候发出消息以被ContentObserver监听。
同样的,接下来同监听短信一样,我们已经可以通过自定义ContentObserver对我们的person数据库的添加动作进行监听了。由于监听的原理跟第5章完成一样,因此这里就不再给出详细的代码。

至此,本文档完!


2014年12月17日星期三 1:31:44
北京市海淀区东北旺中路东馨园



作者: yh903450130    时间: 2015-3-23 21:53
pdf 终于有了  前面的不知道有没有
作者: 王震阳老师    时间: 2015-3-23 21:56
yh903450130 发表于 2015-3-23 21:53
pdf 终于有了  前面的不知道有没有

前面的也有pdf,可能部分没有上传。我在下一篇把前面的补上。
作者: 虚谷    时间: 2015-3-23 21:59
学习了,这个必须得顶。
作者: 没劲睡觉    时间: 2015-3-23 22:11
看的头晕   
作者: 青岛_黑马    时间: 2015-3-23 22:32

学习了,这个必须得顶
作者: 王震阳老师    时间: 2015-3-23 22:32
没劲睡觉 发表于 2015-3-23 22:11
看的头晕

哈哈,习惯就好了,你可知道这都是一个一个字的手打出来的。汇总贴:http://bbs.itheima.com/thread-180149-1-1.html
作者: 中华小便当    时间: 2015-3-23 22:45
回复看帖
作者: yh903450130    时间: 2015-3-23 22:54
王震阳老师 发表于 2015-3-23 21:56
前面的也有pdf,可能部分没有上传。我在下一篇把前面的补上。

嗯嗯 大概多久更新一次啊  感觉在这个上面能学到好多 ,也下载了apk  每天晚上没开电脑也可以在手机上看看 不过手机上面多些吧

作者: challenge    时间: 2015-3-23 22:54
顶一个。
作者: macover    时间: 2015-3-23 22:55
收藏先,非常感谢
作者: tubao1991    时间: 2015-3-23 23:30
来学习了
作者: 萍水相逢    时间: 2015-3-24 07:56
谢谢阳哥:lol
作者: 邓士林    时间: 2015-3-24 08:29
手机版的返回笔记,现在变成乱码字了
作者: itheima_llt    时间: 2015-3-24 09:49
{:3_52:}JAVASE还没自学完,先收藏了,顶阳哥!{:3_67:}
作者: mayor125    时间: 2015-3-24 09:54
顶一顶。。。支持一下
作者: 没劲睡觉    时间: 2015-3-24 21:28
王震阳老师 发表于 2015-3-23 22:32
哈哈,习惯就好了,你可知道这都是一个一个字的手打出来的。汇总贴:http://bbs.itheima.com/thread-1801 ...

真是辛苦啦
作者: Dawn3    时间: 2015-3-24 22:34
学习中。。。。
作者: 王震阳老师    时间: 2015-3-24 23:42
mayor125 发表于 2015-3-24 09:54
顶一顶。。。支持一下

感谢支持。
作者: 王震阳老师    时间: 2015-3-24 23:42
itheima_llt 发表于 2015-3-24 09:49
JAVASE还没自学完,先收藏了,顶阳哥!

加油。
作者: 王震阳老师    时间: 2015-3-24 23:43
邓士林 发表于 2015-3-24 08:29
手机版的返回笔记,现在变成乱码字了

我已经把公布出来的pdf附件全部贴出来了。
作者: 邓士林    时间: 2015-3-24 23:49
王震阳老师 发表于 2015-3-24 23:43
我已经把公布出来的pdf附件全部贴出来了。

辛苦了,老师。谢谢
作者: 落雪    时间: 2015-3-25 09:34
java基础还没看完,先收藏着
作者: mengxiang1993    时间: 2015-3-25 10:47
加油,支持老师
作者: 执笔画梦    时间: 2015-3-25 13:36
阳哥辛苦了
作者: wwwlcy    时间: 2015-3-25 19:34
支持!!!
作者: 朱令娟    时间: 2015-3-26 00:24
我好想成为大牛,我要努力。我要努力
作者: 王震阳老师    时间: 2015-3-26 00:49
朱令娟 发表于 2015-3-26 00:24
我好想成为大牛,我要努力。我要努力

加油。你肯定行的。
作者: 王震阳老师    时间: 2015-3-26 00:49
mengxiang1993 发表于 2015-3-25 10:47
加油,支持老师

感谢支持。
作者: 王震阳老师    时间: 2015-3-26 00:49
执笔画梦 发表于 2015-3-25 13:36
阳哥辛苦了

哈哈,还行吧。
作者: onlybin2015    时间: 2015-3-26 21:44
支持啊,来顶一下
作者: 脚踏实地2015    时间: 2015-3-26 22:06
haohaoxuexi thanks
作者: ellisontu    时间: 2015-3-27 21:05
Come on                        
作者: psttt    时间: 2015-3-28 01:10
mark、mark
作者: smartisan    时间: 2015-3-28 09:52
谢谢谢谢!!
作者: 179407246    时间: 2015-3-28 21:09
阳哥好帅!
作者: 小亮smile    时间: 2015-3-28 21:37
非常赞,  阳哥的帖子都是精品帖
作者: 刘大志    时间: 2015-3-28 21:58
有多少人报

作者: 守护莹到老    时间: 2015-3-28 22:35
学习了,这个必须得顶。
作者: 奔跑的孙莹    时间: 2015-3-29 00:49
阳哥 我要把你的资料都下载啦 你写的太好了!
作者: 花独恋水    时间: 2015-3-31 22:59
23楼
java基础还没看完,先收藏着23楼
java基础还没看完,先收藏着
作者: li子文    时间: 2015-4-1 18:15
黑马程序员棒棒哒
作者: Mr.Kaizhei    时间: 2015-4-2 00:40
必须支持!!!!:loveliness:
作者: 缤纷落叶    时间: 2015-4-2 12:36
这就是黑客技术啊
作者: 邓士林    时间: 2015-4-2 21:41
我今天遇到个问题,请教下。ContentProvider的生命周期问题,比如我们在静态代码块中定义的URI,我们通过ContentResolver对象去操作,这是如何怎么的流程,是不是我们只要在清单文件中注册了这个ConetntProvider,就相当于已经形成这些uri了
作者: 猴子1888    时间: 2015-4-2 22:07
学习了,好棒:lol
作者: ROFFY    时间: 2015-4-2 23:14
顶  一个哈。。
作者: 陈佳    时间: 2015-4-3 08:23
学习了~:handshake
作者: 剑雨飘扬    时间: 2015-4-9 18:26
不知道什么时候能看完。。
作者: z47057554    时间: 2015-4-13 00:18
:)谢谢分享:D
作者: Doug    时间: 2015-4-13 19:06
回帖领pdf
作者: lbl624    时间: 2015-4-13 22:13
谢谢分享啊,非常有用
作者: 鲁柯    时间: 2015-4-15 20:41
9  继续继续   
作者: sinbad88    时间: 2015-4-15 21:30
感谢老师的分享,收藏了
作者: Hosing    时间: 2015-4-15 23:24
Thanks for Yang Brother's Note!
作者: 福禄娃    时间: 2015-4-18 10:05
多谢阳哥分享的笔记。很有用 :)
作者: 彭春晓    时间: 2015-4-19 15:12
ndroid教程-Android基础05网络编程&消息处... [修改]
作者: 时间都去哪了    时间: 2015-4-23 07:50
啦啦啦德玛西亚
作者: 枪杆不如笔杆    时间: 2015-4-24 10:29
喜闻乐见!!!
作者: Catface    时间: 2015-4-28 10:28
前来学习一下
作者: caoyang521    时间: 2015-5-2 14:32
谢谢老师, 很不错的笔记,学习之
作者: godmmm    时间: 2015-5-9 14:37
顶顶顶。。。。。
作者: abc1190@126.com    时间: 2015-5-16 21:41
这么详细!
作者: abc1190@126.com    时间: 2015-5-16 21:44
非常之实用
作者: 徐文豪    时间: 2015-5-17 14:31
分享了  希望自己以后有这个水平
作者: 笑爷    时间: 2015-5-20 22:01
感谢分享
作者: 396460221    时间: 2015-5-20 22:07
有啥附件,这里的现在还有很多看不懂的
作者: leeshaodong    时间: 2015-5-20 22:07
是不是要马克一个,一边上就业班翻阅啊。
作者: 疯狂小白    时间: 2015-5-20 23:29
是什么我都看看
作者: 董小姐    时间: 2015-5-21 09:59
好厉害啊        晕了                 
作者: 武召胜    时间: 2015-5-21 18:15
阳哥v587
作者: 纯情花心男    时间: 2015-5-21 18:23
每日一顶......................
作者: lanbo    时间: 2015-5-21 20:51
阳哥,真心厉害
作者: xiaoxu    时间: 2015-5-24 22:22
复习资料必备!!!!!
作者: yjsf216    时间: 2015-5-25 21:00
9了 快下快下
作者: 739262720    时间: 2015-5-27 00:30
谢谢杨哥,
作者: play1369    时间: 2015-5-28 00:45
多谢分享!
作者: 海行者    时间: 2015-6-1 20:10
先跟着阳哥学好Android基础,并做好一个APP作为铺垫,然后去黑马好好学习
作者: 想不到了解    时间: 2015-6-3 00:05
一页一页的下, 还有60秒回复限制....好:dizzy:呀
作者: 执梦而行    时间: 2015-6-7 23:55
正需要长度奋斗的
作者: zhenxing133    时间: 2015-6-8 00:27
正在学习中
作者: DxxD    时间: 2015-6-8 18:36
看一看。。。瞧一瞧:lol
作者: 油炸电视剧    时间: 2015-6-11 14:25
资料在手,天下我有。
作者: showdy    时间: 2015-6-25 00:14
看看看我顶顶啊
作者: 为了理想而奋斗    时间: 2015-6-25 06:16
加油,自免力中
作者: 杰可可    时间: 2015-6-25 13:09
学习进行时...感谢阳哥!
作者: DAN66    时间: 2015-7-2 18:23
感谢阳哥分享
作者: 展展    时间: 2015-7-13 22:12
学习分享,下载学习了,谢谢老师!
作者: kissfrd    时间: 2015-7-13 22:20
这个好,收藏了!
作者: rzb2010    时间: 2015-7-20 00:27
好东西,下载了好东西,下载了学习,谢谢
作者: xiao7181jun    时间: 2015-7-25 02:00
感谢分享,太棒了!!!
作者: zuoyou    时间: 2015-7-26 22:14
学习,,,,,,,,,,,,
作者: 天人之珠    时间: 2015-7-26 22:19

谢谢分享
作者: weiyuning    时间: 2015-7-28 22:40
感谢分享,十分有帮助
作者: mortonnnn    时间: 2015-7-31 11:20
顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶
作者: as604049322    时间: 2015-7-31 19:53
Android基础09ContentProvider [修改]
作者: zzlin    时间: 2015-8-5 07:45
经典之作,太强悍了,赞赞
作者: T-l-H、小生    时间: 2015-8-7 22:57
收藏啦,赞赞赞赞赞赞
作者: wangkai    时间: 2015-8-10 00:27
一直在看阳哥的笔记,赞一个。
作者: java梦想    时间: 2015-8-17 00:49
学习一下,好人一生平安




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2