1 为什么需要内容提供者
[1]在Android下如何创建一个数据库? 定义一个类继承SqliteOpenHelper
[2]sqlite3 命令行工具 打开一个数据库
[3]chcp 936把当前dos窗体编码方式变成gbk 如果变成utf-8 写chcp 65001
[4]必须拿到哪个类 才能操作数据库 slitedatabase
[5]chmod 可以改变文件权限 chmod 777 Account.db
[6]内容提供者可以把私有的数据库内容暴露出来
2 内容提供者原理
3 实现内容提供者步骤
[1]定义内容提供者 定义一个类继承contentProvider
[2]在清单文件里面配置一下 学霸 定义一些规则 a呀 d
[3] 定义一个urimatcher
[4]写一个静态代码块 添加匹配规则
[5]按照我们添加的匹配规则 暴露想暴露的方法
[6]如果你发现如下log日志 就说明内容提供者写的没有问题
09-11 02:02:31.142: I/ActivityThread(16636): Pub com.itheima.provider: com.itheima.db.AccountProvider
[7]只要是通过内容提供者暴露出来的数据 其他应用访问的方式都是一样的 就是通过内容解析者
4 备份短信案例
** 由于短信的数据库已经通过内容提供者暴露出来 所以我们直接通过内容的解析者去查询数据库
** 由于短信的数据库已经通过内容提供者暴露出来 所以我们直接通过内容的解析者去查询数据库
try { //[1]获取XmlSerializer的实例 XmlSerializer serializer = Xml.newSerializer(); //[2]设置序列化器参数 File file = new File(Environment.getExternalStorageDirectory().getPath(),"smsbackup.xml"); FileOutputStream fos = new FileOutputStream(file); serializer.setOutput(fos, "utf-8"); //[3]写xml文档开头 serializer.startDocument("utf-8", true); //[4]写xml的根节点 serializer.startTag(null, "smss"); //[5]构造uri Uri uri = Uri.parse("content://sms/"); //[6]由于短信的数据库已经通过内容提供者暴露出来 所以我们直接通过内容解析者查询 Cursor cursor = getContentResolver().query(uri, new String[]{"address","date","body"}, null, null, null); while(cursor.moveToNext()){ String address = cursor.getString(0); String date = cursor.getString(1); String body = cursor.getString(2); //[7]写sms节点 serializer.startTag(null, "sms"); //[8]写address节点 serializer.startTag(null, "address"); serializer.text(address); serializer.endTag(null, "address"); //[9]写date节点 serializer.startTag(null, "date"); serializer.text(date); serializer.endTag(null, "date"); //[10]写body节点 serializer.startTag(null, "body"); serializer.text(body); serializer.endTag(null, "body"); serializer.endTag(null, "sms"); } serializer.endTag(null, "smss"); serializer.endDocument(); fos.close(); } catch (Exception e) { e.printStackTrace(); }
关键一点
Uri uri =Uri.parse("content://sms/");
sms一定的知道是怎么来的 是通过查看系统短信的源码 smsProvider 得知
5 利用内容提供者插入短信
6 读取联系人案例
QQ 微信 陌陌等
[1]data表 data1列里面存的是所有联系人的信息 raw_contact_id 列是用来区分一共有几条联系人信息 mimetype_id 列是用来区分数据类型
[2]row_contacts表 中contact_id就是data表的
raw_contact_id
查询联系人的步骤
[1]先查询row_contacts表 的contact_id列 我们就知道一共有几条联系人
[2]我根据
contact_id去查询data表 查询data1列和mimetype
[3]view_data 是由data表和mimetype表的组合
7 插入联系人
插入联系人的步骤
[1]先往
row_contacts表插入数据
contact_id
[2]在往data表里面插入数据 data1
//点击按钮 插入一条联系人信息 public void click(View v) { Uri uri = Uri.parse("content://com.android.contacts/raw_contacts"); Uri dataUri = Uri.parse("content://com.android.contacts/data"); //[2]获取name phone email Textutils String name = et_name.getText().toString().trim(); String phone = et_phone.getText().toString().trim(); String email = et_email.getText().toString().trim(); //[2.1]在插入联系人id的时候 先查询一下 row_contact 一共有几条数据 加+1就是联系人的id Cursor cursor = getContentResolver().query(uri, null, null, null, null); int count = cursor.getCount(); int contact_id = count +1; //[3] 先往row_contact表 插入联系人的id (contact_id) ContentValues values = new ContentValues(); values.put("contact_id", contact_id); getContentResolver().insert(uri,values); //[4]在把name phone email 插入到data表 ContentValues nameValues = new ContentValues(); nameValues.put("data1", name); //☆ ☆ ☆ ☆ ☆ 插入的数据要告诉数据库 属于第几条联系人 和 数据类型 nameValues.put("raw_contact_id", contact_id); nameValues.put("mimetype", "vnd.android.cursor.item/name"); getContentResolver().insert(dataUri, nameValues); //[5]把phone号码 插入到data表 ContentValues phoneValues = new ContentValues(); phoneValues.put("data1", phone); phoneValues.put("mimetype", "vnd.android.cursor.item/phone_v2"); phoneValues.put("raw_contact_id", contact_id); getContentResolver().insert(dataUri, phoneValues); //[5]把phone号码 插入到data表 ContentValues emailValues = new ContentValues(); emailValues.put("data1", email); emailValues.put("mimetype", "vnd.android.cursor.item/email_v2"); emailValues.put("raw_contact_id", contact_id); getContentResolver().insert(dataUri, emailValues); }
8 内容观察者
(1)内容观察不是四大组件 他不需要在清单文件里配置
(2)定义内容观察者
9内容观察者应用场景
短信监听器