内容提供者
- Android四大组件之一
- 应用的数据库是不允许其他应用访问的
- 内容提供者的作用就是让别的应用访问到你的私有数据
- 自定义内容提供者,继承ContentProvider类,重写增删改查方法,在方法中写增删改查数据库的代码,举例增方法
一般不需要自定义,原因是我们一般是拿第三方提供的数据,跟广播类似
@Override
public Uri insert(Uri uri, ContentValues values) {db.insert("person", null, values);return uri;
}
- 在清单文件中定义内容提供者的标签,注意必须要有authorities属性,这是内容提供者的主机名,功能类似地址
<provider android:name&#61;"com.xxx.contentprovider.PersonProvider"android:authorities&#61;"com.xxx.person"android:exported&#61;"true">provider>
- 创建一个其他应用&#xff0c;访问自定义的内容提供者&#xff0c;实现对数据库的插入操作
public void click(View v){ContentResolver cr &#61; getContentResolver();ContentValues cv &#61; new ContentValues();cv.put("name", "小方");cv.put("phone", 138856);cv.put("money", 3000);cr.insert(Uri.parse("content://com.xxx.person"), cv);
}
UriMatcher
- 用于判断一条uri跟指定的多条uri中的哪条匹配
- 添加匹配规则
UriMatcher um &#61; new UriMatcher(UriMatcher.NO_MATCH);{
um.addURI("com.xxx.person", "person", PERSON_CODE);
um.addURI("com.xxx.person", "company", COMPANY_CODE);
um.addURI("com.xxx.person", "person/#", QUERY_ONE_PERSON_CODE);
* 通过Uri匹配器可以实现操作不同的表
}&#64;Override
public Uri insert(Uri uri, ContentValues values) {if(um.match(uri) &#61;&#61; PERSON_CODE){db.insert("person", null, values);}else if(um.match(uri) &#61;&#61; COMPANY_CODE){db.insert("company", null, values);}else{throw new IllegalArgumentException();}return uri;
}
- 如果路径中带有数字&#xff0c;把数字提取出来的api
int id &#61; (int) ContentUris.parseId(uri);
短信数据库
- 只需要关注sms表
- 只需要关注4个字段
- body&#xff1a;短信内容
- address:短信的发件人或收件人号码&#xff08;跟你聊天那哥们的号码&#xff09;
- date&#xff1a;短信时间
- type&#xff1a;1为收到&#xff0c;2为发送
读取系统短信&#xff0c;首先查询源码获得短信数据库内容提供者的主机名和路径&#xff0c;然后访问内容提供者
ContentResolver cr &#61; getContentResolver();
Cursor c &#61; cr.query(Uri.parse("content://sms"), new String[]{"body", "date", "address", "type"}, null, null, null);
while(c.moveToNext()){String body &#61; c.getString(0);String date &#61; c.getString(1);String address &#61; c.getString(2);String type &#61; c.getString(3);System.out.println(body&#43;";" &#43; date &#43; ";" &#43; address &#43; ";" &#43; type);
}
插入系统短信
ContentResolver cr &#61; getContentResolver()
ContentValues cv &#61; new ContentValues()
cv.put("body", "您尾号为XXXX的招行储蓄卡收到转账1,000,000人民币")
cv.put("address", 95555)
cv.put("type", 1)
cv.put("date", System.currentTimeMillis())
cr.insert(Uri.parse("content://sms"), cv)
联系人数据库
- raw_contacts表&#xff1a;
- data表&#xff1a;联系人的具体信息&#xff0c;一个信息占一行
- data1&#xff1a;信息的具体内容
- raw_contact_id&#xff1a;联系人id&#xff0c;描述信息属于哪个联系人
- mimetype_id&#xff1a;描述信息是属于什么类型
- mimetypes表&#xff1a;通过mimetype_id到该表查看具体类型
读取联系人
Cursor cursor &#61; cr.query(Uri.parse("content://com.android.contacts/raw_contacts"), new String[]{"contact_id"}, null, null, null);
- 然后拿着联系人id去data表查询属于该联系人的信息
Cursor c &#61; cr.query(Uri.parse("content://com.android.contacts/data"), new String[]{"data1", "mimetype"}, "raw_contact_id &#61; ?", new String[]{contactId}, null);
- 得到data1字段的值&#xff0c;就是联系人的信息&#xff0c;通过mimetype判断是什么类型的信息
while(c.moveToNext()){String data1 &#61; c.getString(0);String mimetype &#61; c.getString(1);if("vnd.android.cursor.item/email_v2".equals(mimetype)){contact.setEmail(data1);}else if("vnd.android.cursor.item/name".equals(mimetype)){contact.setName(data1);}else if("vnd.android.cursor.item/phone_v2".equals(mimetype)){contact.setPhone(data1);}
}
插入联系人
- 先查询raw_contacts表&#xff0c;确定新的联系人的id应该是多少
- 把确定的联系人id插入raw_contacts表
cv.put("contact_id", _id)
cr.insert(Uri.parse("content://com.android.contacts/raw_contacts"), cv)
- 在data表插入数据
- 插3个字段&#xff1a;data1、mimetype、raw_contact_id
cv &#61; new ContentValues()
cv.put("data1", "赵六")
cv.put("mimetype", "vnd.android.cursor.item/name")
cv.put("raw_contact_id", _id)
cr.insert(Uri.parse("content://com.android.contacts/data"), cv)cv &#61; new ContentValues()
cv.put("data1", "1596874")
cv.put("mimetype", "vnd.android.cursor.item/phone_v2")
cv.put("raw_contact_id", _id)
cr.insert(Uri.parse("content://com.android.contacts/data"), cv)
内容观察者
- 当数据库数据改变时&#xff0c;内容提供者会发出通知&#xff0c;在内容提供者的uri上注册一个内容观察者&#xff0c;就可以收到数据改变的通知
cr.registerContentObserver(Uri.parse("content://sms"), true, new MyObserver(new Handler()));class MyObserver extends ContentObserver{public MyObserver(Handler handler) {super(handler);}&#64;Overridepublic void onChange(boolean selfChange) {}}
ContentResolver cr &#61; getContext().getContentResolver();
cr.notifyChange(uri, null);