A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

本帖最后由 王震阳老师 于 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就是联系人的内容提供者。
  • 打开清单文件,寻找联系人的内容提供者对应的是哪个java文件
  • 打开ContactsProvider2.java文件,查看此内容提供者的uri路径信息
  • 根据源码,确定内容提供者的Uri信息为:
操作raw_contacts表的Uri:
操作data表的Uri:
  • 操作数据库表时:由于contacts2.db数据库使用了视图,所以操作数据库表时,表结构有所改变,注意操作时要操纵的列的列名已经改变
比如:data表在查询的时候没有mimetype_id,取代的是mimetype
3.2操作系统联系人
步骤:
  • 操作raw_contacts表,获取全部的id
  • 根据获取到的每一条id去查询data表中的数据
  • 将查询到的展示是用户界面
  • 通过代码给系统联系人插入一条联系人信息
新建一个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的步骤我这里总结如下:
  • 首先创建一个ContentObserver的子类,然后实现里面的onChange方法,监听的Uri中的数据发生变化的时候,会调用onChange方法。
  • 注册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
北京市海淀区东北旺中路东馨园


134 个回复

倒序浏览
pdf 终于有了  前面的不知道有没有
回复 使用道具 举报
yh903450130 发表于 2015-3-23 21:53
pdf 终于有了  前面的不知道有没有

前面的也有pdf,可能部分没有上传。我在下一篇把前面的补上。
回复 使用道具 举报
学习了,这个必须得顶。
回复 使用道具 举报
看的头晕   
回复 使用道具 举报

学习了,这个必须得顶
回复 使用道具 举报

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

嗯嗯 大概多久更新一次啊  感觉在这个上面能学到好多 ,也下载了apk  每天晚上没开电脑也可以在手机上看看 不过手机上面多些吧
回复 使用道具 举报
顶一个。
回复 使用道具 举报
收藏先,非常感谢
回复 使用道具 举报
来学习了
回复 使用道具 举报
谢谢阳哥:lol
回复 使用道具 举报
手机版的返回笔记,现在变成乱码字了
回复 使用道具 举报
{:3_52:}JAVASE还没自学完,先收藏了,顶阳哥!{:3_67:}
回复 使用道具 举报
顶一顶。。。支持一下
回复 使用道具 举报
王震阳老师 发表于 2015-3-23 22:32
哈哈,习惯就好了,你可知道这都是一个一个字的手打出来的。汇总贴:http://bbs.itheima.com/thread-1801 ...

真是辛苦啦
回复 使用道具 举报
Dawn3 中级黑马 2015-3-24 22:34:49
18#
学习中。。。。
回复 使用道具 举报
mayor125 发表于 2015-3-24 09:54
顶一顶。。。支持一下

感谢支持。
回复 使用道具 举报
itheima_llt 发表于 2015-3-24 09:49
JAVASE还没自学完,先收藏了,顶阳哥!

加油。
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马