Hi,大家好,我是编程小6,很荣幸遇见你,我把这些年在开发过程中遇到的问题或想法写出来,今天说一说每天记录学习的新知识:ContentResolver「建议收藏」,希望能够帮助你!!!。
ContentResolver直译为内容解析器,和ContentProvider成对出现。
程序间数据的共享是通过Provider/Resolver进行的。提供数据(内容)的就叫Provider,Resovler提供接口对这个内容进行解读。
onCreate() 、getType() 、query() 、insert() 、update()、delete()
提供的方法和参数都和ContentProvider呈对应关系
public void registerContentObserver(Uri uri, boolean notifyForDescendents,
IContentObserver observer) {
mRootNode.addObserverLocked(uri, observer,
notifyForDescendents, mRootNode,
Binder.getCallingUid(), Binder.getCallingPid());
}
uri:针对对有变化的感兴趣进行监听的URI
notifyForDescendents:true表示以uri前缀开始的任何变化都进行通知;false表示完全匹配才进行通知;
observer:IContentObserver接口,提供了一个方法onChange,变化发生时Cursor需要更新时调用;还可以extends ContentObserver ↓通过监听下面这个方法
@Override
public void onChange(boolean selfChange) {
}
使用此ContentService的registerContentObserver接口注册Observer,通过指定Uri可以仅对数据库中感兴趣的数据有变化时,进行监听。具体实现细节可以看下ContentService源代码中是如何构建一个树形结构来管理观察者对感兴趣数据的监听,看到根节点就是上述的mRootNode构建了一颗大树。
public void notifyChange(@NonNull Uri uri, @Nullable ContentObserver observer) {
notifyChange(uri, observer, true /* sync to network */);
}
作用:
观察 Uri引起 ContentProvider 中的数据变化 & 通知外界(即访问该数据访问者)
当ContentProvider 中的数据发生变化(增、删 & 改)时,就会触发该 ContentObserver类
Uri uri = Uri.parse("content://sms/");
ContentResolver resolver = getContentResolver();
//获取的是哪些列的信息
Cursor cursor = resolver.query(uri, new String[] {
"address", "date", "type", "body" }, null, null, null);
if (cursor != null) {
StringBuffer sb = new StringBuffer();
while (cursor.moveToNext()) {
sb.append("联系人:" + cursor.getString(cursor.getColumnIndex("address")));
sb.append("\n时间:" + cursor.getString(cursor.getColumnIndex("date")));
sb.append("\n类型:" + cursor.getString(cursor.getColumnIndex("type")));
sb.append("\n内容:" + cursor.getString(cursor.getColumnIndex("body")));
sb.append("\n===============================\n");
}
tv_info.setText(sb.toString());
cursor.close();
}
ContentValues values = new ContentValues();
values.put("address", "10086");//联系人
values.put("type", 1);//类型1是"收到"的短信
values.put("date", System.currentTimeMillis());//收到的时间
values.put("body", "您的余额还有1,000,000万元!");//内容
Uri returnUri = resolver.insert(Uri.parse("content://sms"), values);
if (returnUri != null) {
tv_info.setText(returnUri.toString());
if (returnUri.getPath().equals("/0")) {
Toast.makeText(this, "添加失败:" + returnUri.getPath(), Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(this, "添加成功:" + returnUri.getPath(), Toast.LENGTH_SHORT).show();
}
}
// 步骤1:注册内容观察者,通过ContentResolver类进行注册,并指定需要观察的URI
// 在
ContentObserver getContentResolver().registerContentObserver(uri);
// 步骤2:当该URI的ContentProvider数据发生变化时,通知外界(即访问该ContentProvider数据的访问者)
public class UserContentProvider extends ContentProvider {
public Uri insert(Uri uri, ContentValues values) {
db.insert("user", "userid", values);
getContext().getContentResolver().notifyChange(uri, null);// 通知访问者
}
}
// 步骤3:解除观察者 ,同样需要通过ContentResolver类进行解除
getContentResolver().unregisterContentObserver(uri);
例如系统日历的变化
public static String CALENDER_URL = "content://com.android.calendar/calendars";
public static String CALENDER_EVENT_URL = "content://com.android.calendar/events";
public static String CALENDER_REMINDER_URL = "content://com.android.calendar/reminders";
class MyHan extends Handler {
@Override
public void dispatchMessage(@NonNull Message msg) {
super.dispatchMessage(msg);
AppLogUtils.i(TAG, "dispatchMessage");
}
}
getContentResolver().registerContentObserver(Uri.parse(CALENDER_REMINDER_URL), true, new ContentObserver(new MyHan()) {
@Override
public boolean deliverSelfNotifications() {
AppLogUtils.i(TAG, "deliverSelfNotifications");
return super.deliverSelfNotifications();
}
@Override
public void onChange(boolean selfChange) {
super.onChange(selfChange);
AppLogUtils.i(TAG, "onChange");
}
@Override
public void onChange(boolean selfChange, @Nullable Uri uri) {
super.onChange(selfChange, uri);
AppLogUtils.i(TAG, "onChange");
}
});
其他
//管理联系人的Uri:
ContactsContract.Contacts.CONTENT_URI
MediaStore.Files.FileColumns.xxx
MediaStore.Audio.Media.EXTERNAL_CONTENT_URI
MediaStore.Images.Images.EXTERNAL_CONTENT_URI
MediaStore.Video.Images.EXTERNAL_CONTENT_URI
content://sms/inbox // 收件箱
content://sms/sent //已发送
content://sms/draft //草稿
content://sms/outbox //发件箱(正在发送的信息)
content://sms/failed //发送失败
content://sms/queued //待发送列表 (比如开启飞行模式后,该短信就在待发送列表里)
目前见过最全的解析:https://blog.csdn.net/carson_ho/article/details/76101093
https://www.cnblogs.com/baiqiantao/p/5535471.html
上一篇
已是最后文章
下一篇
已是最新文章