ContentProvider 内容提供者
ContentProvider(内容提供者) :: 提供数据/函数,供其它APP使用
ContentResolver(内容解析者) :: 根据Uri 调用/解析 内容提供者提供的数据/函数
ContentObserver(内容观察者) :: 观察内容提供者 用来监视内容提供者暴露的数据
清单文件中注册
<application 层中
<provider android:name="com.bz.contentprovider.MyContentProvider"
android:authorities="com.bz.contentprovider.ContentProvider"> <!-- 内容提供者主机名 -->
<!-- android:exported="true" //允许被其它App调用 -->
</provider>
第一次写的内容提供者 MyContentProvider.java
/* Uri: content://com.bz.contentprovider.ContentProvider/XXX */
/* | scheme | authorities | path */
/* 标志前缀 清单文件的 android:authorities 资源/数据 */
package com.bz.contentprovider;
import android.content.ContentProvider;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.net.Uri;
public class MyContentProvider extends ContentProvider {
// 定义一个路径匹配器 用于匹配uri 如果路径不满足条件 返回 -1 (NO_MATCH)
private static UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH);
//定义一些常量
private static final int INSERT = 1; //添加数据匹配Uri路径成功时返回码
private static final int DELETE = 2; //删除数据匹配Uri路径成功时返回码
private static final int UPDATE = 3; //更改数据匹配Uri路径成功时返回码
private static final int QUERY = 4; //查询数据匹配Uri路径成功时返回码
private static final int QUERYONE = 5; //查询一条数据匹配Uri路径成功时返回码
//静态代码块
static {
// 添加一组匹配规则. (清单文件设置的主机名,调用哪个方法,匹配码)
matcher.addURI("com.bz.contentprovider.ContentProvider", "insert", INSERT);
matcher.addURI("com.bz.contentprovider.ContentProvider", "delete", DELETE);
matcher.addURI("com.bz.contentprovider.ContentProvider", "update", UPDATE);
matcher.addURI("com.bz.contentprovider.ContentProvider", "query", QUERY);
//这里的“#”号为通配符凡是符合”query/”皆返回QUERYONE的返回码
matcher.addURI("com.bz.contentprovider.ContentProvider", "query/#", QUERYONE);
}
private MySQL helper;//数据库对象
@Override
public boolean onCreate() { //创建时调用 获取数据库
helper = new MySQL(getContext());
return false;
}
@Override
public String getType(Uri uri) { //根据传入的Uri返回代表的数据的类型 MIME
if (matcher.match(uri) == QUERY) {
return "vnd.android.cursor.dir/person"; // 返回查询的结果 集多条数据vnd.android.cursor.dir开头、
} else if (matcher.match(uri) == QUERYONE) {
return "vnd.android.cursor.item/person"; // 单条数据vnd.android.cursor.item开头
}
return null;
}
@Override
public Cursor query(Uri uri, String[] projection, String selection,String[] selectionArgs, String sortOrder) { //根据传入的Uri查询指定条件下的数据
// TODO 自动生成的方法存根
if (matcher.match(uri) == QUERY) { //匹配查询的Uri路径
SQLiteDatabase db = helper.getReadableDatabase();
Cursor cursor = db.query("person", projection, selection,selectionArgs, null, null, sortOrder);
return cursor;
} else if (matcher.match(uri) == QUERYONE) { //匹配成功,根据id查询数据
long id = ContentUris.parseId(uri);
SQLiteDatabase db = helper.getReadableDatabase();
Cursor cursor = db.query("person", projection, "id=?",new String[]{id+""}, null, null, sortOrder);
return cursor;
} else {
throw new IllegalArgumentException("路径不匹配,不能执行查询操作"); //自定义报错
}
}
@Override
public Uri insert(Uri uri, ContentValues values) { //根据传入的Uri插入数据
if (matcher.match(uri) == INSERT) {
SQLiteDatabase db = helper.getWritableDatabase();
db.insert("person", null, values);
} else {
throw new IllegalArgumentException("路径不匹配,不能执行插入操作");
}
return null;
}
@Override
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { //根据传入的Uri更新指定条件下的数据
if (matcher.match(uri) == UPDATE) {
SQLiteDatabase db = helper.getWritableDatabase();
db.update("person", values, selection, selectionArgs);
} else {
throw new IllegalArgumentException("路径不匹配,不能执行修改操作");
}
return 0;
}
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) { //根据传入的Uri删除指定条件下的数据
if (matcher.match(uri) == DELETE) {
SQLiteDatabase db = helper.getWritableDatabase();
db.delete("person", selection, selectionArgs);
} else {
throw new IllegalArgumentException("路径不匹配,不能执行删除操作");
}
return 0;
}
}
调用自己写的内容提供者 MyContentProvider.java
//利用ContentResolver查询本应用程序使用ContentProvider暴露的数据
private void getPersons() {
/* 插入
Uri uri2 = Uri.parse("content://com.bz.contentprovider.ContentProvider/insert");
ContentResolver contentResolver2 = getContentResolver();
ContentValues values = new ContentValues();
values.put("name", "lxj");
values.put("number", "520");
contentResolver2.insert(uri2, values);
*/
//首先要获取查询的uri
Uri uri = Uri.parse("content://com.bz.contentprovider.ContentProvider/query");
//获取ContentResolver
ContentResolver contentResolver = getContentResolver();
//利用ContentResolver查询数据得到一个Cursor
Cursor cursor = contentResolver.query(uri, null, null, null, null);
persons = new ArrayList<Person>();
//如果cursor为空立即结束该方法
if(cursor == null){return;}
while(cursor.moveToNext()){
int id = cursor.getInt(cursor.getColumnIndex("id"));
String name = cursor.getString(cursor.getColumnIndex("name"));
String number = cursor.getString(cursor.getColumnIndex("number"));
Person p = new Person(id, name, number);
persons.add(p);
}
cursor.close();
}
获取短信信息
private void getmsglist()
{
Uri uri = Uri.parse("content://sms/");
//获取ContentResolver对象
ContentResolver resolver = getContentResolver();
//通过ContentResolver对象查询系统短信
Cursor cursor = resolver.query(uri, new String[] { "address", "date", "type", "body" }, null, null, null);
persons = new ArrayList<Person>();
while (cursor.moveToNext()) {
String address = cursor.getString(cursor.getColumnIndex("address"));
String body = cursor.getString(cursor.getColumnIndex("body"));
Person p = new Person(0, address, body);
persons.add(p);
}
cursor.close();
}
短信到来时自动提醒 或者做别的事 嘿嘿嘿
内容观察者 观察短信内容提供者 新消息到时 得知数据被修改了
onCreate{
ContentResolver resolver = getContentResolver(); //内容解析者
Uri uri = Uri.parse("content://sms/");
// 注册内容观察者
resolver.registerContentObserver(uri, true, new MyObserver(new Handler()));
}
// 自定义的内容观察者
private class MyObserver extends ContentObserver {
public MyObserver(Handler handler) {
super(handler);
}
// 当内容观察者 观察到是数据库的内容变化了 调用这个方法
// 观察到 消息邮箱里面有一条数据库内容变化的通知.
public void onChange(boolean selfChange) {
super.onChange(selfChange);
Toast.makeText(Message_Receive_Activity.this, "数据库的内容变化了.", 1).show();
Uri uri = Uri.parse("content://sms/");
// 获取ContentResolver
ContentResolver resolver = getContentResolver();
// 查询变化的数据
Cursor cursor = resolver.query(uri, new String[] { "address", "date", "type", "body" }, null, null, null);
// 因为短信是倒序排列 因此获取最新一条就是第一个
cursor.moveToFirst();
String address = cursor.getString(0);
String body = cursor.getString(3);
// 更改UI界面
txt_msg.setText("短信内容:" + body + "\n" + "短信地址:" + address);
cursor.close();
}
}
获取联系人信息
<uses-permission android:name="android.permission.READ_CONTACTS"/>
class ContactInfo {
String name;
String PhoneNum;
Bitmap bitmap;
}
private void GetContactInfo() {
ContentResolver contentResolver = getContentResolver();
Uri uri = Phone.CONTENT_URI;// content://com.android.contacts/data/phones
String projection[] = new String[] { Phone.DISPLAY_NAME, Phone.NUMBER,Phone.PHOTO_ID, Phone.CONTACT_ID };
Cursor cursor = contentResolver.query(uri, projection, null, null, null);
if (cursor == null) {return;}
while (cursor.moveToNext()) {
ContactInfo contactInfo = new ContactInfo();
int indexName = cursor.getColumnIndex(Phone.DISPLAY_NAME);
String name = cursor.getString(indexName);
int indexNum = cursor.getColumnIndex(Phone.NUMBER);
String PhoneNum = cursor.getString(indexNum);
long photoID = cursor.getLong(cursor.getColumnIndex(Phone.PHOTO_ID));
Bitmap bitmap = null;
if (photoID > 0) { // have photo
// content://com.android.contacts/contacts/contatctID
long contatctID = cursor.getLong(cursor.getColumnIndex(Phone.CONTACT_ID));
Uri uriPhoto = Uri.withAppendedPath(ContactsContract.Contacts.CONTENT_URI,Long.toString(contatctID));
InputStream inputStream = ContactsContract.Contacts.openContactPhotoInputStream(contentResolver, uriPhoto);
bitmap = BitmapFactory.decodeStream(inputStream);
} else {
bitmap = BitmapFactory.decodeResource(getResources(),R.drawable.katong);
}
contactInfo.name = name;
contactInfo.PhoneNum = PhoneNum;
contactInfo.bitmap = bitmap;
arrayList.add(contactInfo);
}
}