内容提供者
用内容提供者操作短信、通讯录
内容提供者操作私有数据
- 四大组件之一
1 内容提供者的概念
- 把应用程序的私有数据暴露出去给其他应用程序使用。
- 私有数据:数据库、sp、文件、图片、音乐
2 内容提供者编写步骤
- 写一个类继承系统的ContentProvider
在清单文件中注册
<provider android:name="cn.itcast.bankdb.SpyProvider" android:authorities="tian.wan.gai.di.hu" > </provider>
写出暗号的下半句,写一个UriMatcher,匹配URI
static UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH); static{ //添加URI的匹配规则 matcher.addURI("tian.wan.gai.di.hu", "bao.ta.zhen.he.yao", URI_SUCC); }
往银行数据库插入数据
content://tian.wan.gai.di.hu/bao.ta.zhen.he.yao @Override public Uri insert(Uri uri, ContentValues values) { int code = matcher.match(uri); if (code == URI_SUCC) {//URI匹配成功 /* *table :表名 *nullColumnHack :null *values :contentvalus,类似HashMap */ long id = db.insert("account", null, values); return Uri.parse("id"); }else { throw new IllegalArgumentException("对不起,根据相关的法律规定,您无权操作数据库。"); } }
3 调用另一个工程中内容提供者的步骤
创建内容解析器
ContentResolver resolver = this.getContentResolver();
设置URI
Uri uri = Uri.parse("content://tian.wang.gai.di.hu/bao.ta.zhen.he.yao");
做增删改查
ContentValues values = new ContentValues(); values.put("name", "达摩"); values.put("money", 100000000); Uri id = resolver.insert(uri, values); "content://tian.wang.gai.di.hu/bao.ta.zhen.he.yao"
4 内容提供者删改查的实现
/**
* 1. 内容提供者继承ContentProvider
* 内线
*/
public class BankProvider extends ContentProvider {
private static final int CODE_SUCC = 0;
private static final int CODE_SUCC_UPDATE = 1;
private static final int CODE_SUCC_ACCOUNT = 2;
private static final int CODE_SUCC_BLACK = 3;
private MyOpenHelper helper;
// 3.创建UriMatcher
static UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH);
// 训练内线
static {
// content://tian.wang.gai.di.hu/bao.ta.zhen.he.yao
matcher.addURI("tian.wang.gai.di.hu", "bao.ta.zhen.he.yao", CODE_SUCC);
// content://tian.wang.gai.di.hu/update
matcher.addURI("tian.wang.gai.di.hu", "update", CODE_SUCC_UPDATE);
// content://tian.wang.gai.di.hu/account 主机名+path(账户表名)
matcher.addURI("tian.wang.gai.di.hu", "account", CODE_SUCC_ACCOUNT);
// content://tian.wang.gai.di.hu/black 主机名+path(黑名单表表名)
matcher.addURI("tian.wang.gai.di.hu", "black", CODE_SUCC_BLACK);
// content://tian.wang.gai.di.hu/account/2 主机名+path(表名)
matcher.addURI("tian.wang.gai.di.hu", "account/2", CODE_SUCC_ACCOUNT);
// content://tian.wang.gai.di.hu/account/# 主机名+path(表名)
matcher.addURI("tian.wang.gai.di.hu", "account/#", CODE_SUCC_ACCOUNT);
}
/**
* 初始化内容提供者
*/
@Override
public boolean onCreate() {
helper = new MyOpenHelper(getContext());
return false;
}
@Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
int code = matcher.match(uri);
if (code == CODE_SUCC_ACCOUNT) {//账户表
SQLiteDatabase db = helper.getWritableDatabase();
Cursor cursor = db.query("account", projection, selection,
selectionArgs, null, null, sortOrder);
return cursor;
} else if(code == CODE_SUCC_BLACK){//黑名单表
SQLiteDatabase db = helper.getWritableDatabase();
Cursor cursor = db.query("black", projection, selection,
selectionArgs, null, null, sortOrder);
return cursor;
}else {
throw new IllegalArgumentException("sorry,根据相关的法律规定,您无权操作银行数据库!");
}
}
/**
* 4. 实现往数据库插入数据 itcast://xian08/班长
* content://tian.wang.gai.di.hu/bao.ta.zhen.he.yao/account
* content://tian.wang.gai.di.hu/bao.ta.zhen.he.yao/black
*/
@Override
public Uri insert(Uri uri, ContentValues values) {
System.out.println("2. 内容提供者插入数据");
int code = matcher.match(uri);
if (code == CODE_SUCC) {// 暗号匹配成功
SQLiteDatabase db = helper.getWritableDatabase();
long id = db.insert("account", null, values);
return Uri.parse(id + "");
}else if(code == CODE_SUCC_BLACK){//黑名单表
SQLiteDatabase db = helper.getWritableDatabase();
long id = db.insert("black", null, values);
return Uri.parse(id + "");
}else {
throw new IllegalArgumentException("sorry,根据相关的法律规定,您无权操作银行数据库!");
}
}
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
int code = matcher.match(uri);
if (code == CODE_SUCC_ACCOUNT) {
SQLiteDatabase db = helper.getWritableDatabase();
int id = db.delete("account", selection, selectionArgs);
return id;
} else if(code == CODE_SUCC_BLACK){//黑名单表
SQLiteDatabase db = helper.getWritableDatabase();
int id = db.delete("black", selection, selectionArgs);
return id;
}else {
throw new IllegalArgumentException("sorry,根据相关的法律规定,您无权操作银行数据库!");
}
}
@Override
public int update(Uri uri, ContentValues values, String selection,
String[] selectionArgs) {
int code = matcher.match(uri);
if (code == CODE_SUCC_UPDATE) {
SQLiteDatabase db = helper.getWritableDatabase();
int id = db.update("account", values, selection, selectionArgs);
return id;
} else if(code == CODE_SUCC_BLACK){//黑名单表
SQLiteDatabase db = helper.getWritableDatabase();
int id = db.update("black", values, selection, selectionArgs);
return id;
}else {
throw new IllegalArgumentException("sorry,根据相关的法律规定,您无权操作银行数据库!");
}
}}
5 学习内容提供者的目的
- 阅读android系统源码
- 给其他程序员用的
- 理解系统的短信、通讯录通过内容提供者暴露数据
Android系统短信应用
6 短信的内容提供者Uri和短信表结构
sms表
- address :手机号码
- date :收发短信到时间
- read :短信阅读状态 0未读,1已读
- type :短信的首发状态 1 收到,2发出
- body :短信内容
sms表的URI : content://sms/
7 短信的备份 (重要)
- 利用内容提供者获取系统的短信数据
- 将短信数据备份到SD
8 往短信数据库插入短信 (重要)
ContentResolver resolver = getContentResolver();
Uri uri = Uri.parse("content://sms");
ContentValues values = new ContentValues();
values.put("address", "95588");
values.put("date", System.currentTimeMillis());
values.put("type", 1);
values.put("read", 0);
values.put("body", "尊敬的用户,你的卡尾号是4325,已打入年终奖人民币¥100000000.00[招商银行]");
resolver.insert(uri, values);
Android系统通讯录应用
9 通讯录数据库的表结构
raw_contacts表
- contact_id 联系人的id
data表
- raw_contact_id 和raw_contacts表里的contact_id 一 一对应
- data1 联系人的数据姓名、邮箱、电话号码
- mimetype_id 联系人的数据类型(代码里用 mimetype)
mimetypes表
- mimetype 联系人的数据类型
rawc_contacts : content://com.android.contacts/raw_contacts
data表的URI: content://com.android.contacts/data
10 获取系统通讯录信息(重要)
- 利用内容提供者查询通讯录数据
- 查询raw_contacts表里的contact_id,获取联系人的id
- 查询data表里的联系人数据
- 根据mimetype数据类型区别数据
11 插入联系人到通讯录 (重要)
- 查询raw_contacts表里的contact_id,获取最大的id,给其 +1
- 给raw_contacts表插入最新的id
- 给data表插入联系人姓名、邮箱、电话号码
内容观察者
12 内容观察者
- 当数据库的URI发生变化时,通知所有在这个URI上面注册里的内容观察者。
13 短信窃听器
//注册短信数据库表变化的内容观察者
getContentResolver().registerContentObserver(Uri.parse("content://sms/"), true,
new ContentObserver(new Handler()) {
@Override
public void onChange(boolean selfChange) {
super.onChange(selfChange);
System.out.println("短信数据库变化楼。。。");
}
});