因为我的应用程序使用来自
android.provider.ContactsContract.Data
(API > 11)和 ContactsContract.Contacts.CONTENT_URI
(API < 11) to populate Contacts
。)的内容
我已尝试
registerContentObserver()
反对这些提供商。但即使我一拨打电话就尝试从设备上呼叫某人,它也会呼叫我的ContentObserver
。它确实触发了我的 ContentObserver
,这对我来说没有用,因为 Contacts Provider
中没有内容更改。
根本原因:
当从由
LAST_TIME_CONTACTED
合法唤醒的设备发出呼叫时,ContactsContract.Contacts.CONTENT_URI
或 ContentObserver
中的某些内容似乎会发生变化。
尝试过:
private class ContactsContentObserver extends ContentObserver {
public ContactsContentObserver() {
super(null);
}
@Override
public void onChange(boolean selfChange) {
super.onChange(selfChange);
Zname.getPreferences().setRefreshContact(true);
}
}
已在
ContentObserver
的
OnCreate()
中注册
Activity
ContactsContentObserver contactsContentObserver = new ContactsContentObserver();
getContentResolver().registerContentObserver(ContactsContract.Contacts.CONTENT_URI, false, contactsContentObserver);
尝试将
notifyForDescendents
用作 false
上的 registerContentObserver
。还是会触发ContentObserver
问题:
如何注册
ContentObserver
并触发当且仅当联系人信息处于CRUD(创建、更新、删除)状态(除了Last_Time_Contacted
或其后代之外)?
这里的根本问题是注册
ContactsContract.Contacts.CONTENT_URI
并不像您合理想象的那样有效。
即使
notifyForDescendents
是 false
,您也会收到更新的原因是,触发更新的 Uri
是...ContactsContract.Contacts.CONTENT_URI
而不是正在拨打的联系人行。
联系人应用程序中的违规代码可以在 GrepCode 中找到,并且在 Google Code 上为此提交了一个错误。
因此,要回答您的问题,您无法注册将触发联系人上特定字段的ContentObserver
。您的应用程序中需要有一些东西,以便在
onChange
触发时跟踪计算差异.
android.provider.ContactsContract
内容提供商有其自身的复杂性,这使得
ContentObserver
很难仅通知
contacts
内容更改,除非它是
LAST_TIME_CONTACTED
字段,因为每个遇到的人都这么说,所以事实如此。需要开发自己的逻辑,当
contacts
通知时,
ContentObserver
数据是否更新。无论
contacts
是否真的更新,都要考虑构建逻辑。
ContentObserver
中添加
Service
,即
STICKY
,这样当联系人发生变化时它就可以在那里。
同步电话簿逻辑:-由于我使用 SQLite 维护联系人,因此检查其是否存在并构建逻辑。
ContentValues values;
Cursor cursor = Zname.getApplication().getContentResolver().query(DBConstant.All_Contacts_Columns.CONTENT_URI,null,DBConstant.All_Contacts_Columns.COLUMN_CONTACT_NUMBER+ "=?",new String[] { _contact.getContactNumber() },null);
if (cursor.getCount() <= 0) {
cursor.moveToFirst();
Zname.getApplication().getContentResolver().delete(DBConstant.All_Contacts_Columns.CONTENT_URI,DBConstant.All_Contacts_Columns.COLUMN_CONTACT_NUMBER+ "?=",new String[] { _contact.getContactNumber() });
Log.i(TAG, "Updating zname phonebook");
values = new ContentValues();
values.put(DBConstant.All_Contacts_Columns.COLUMN_CONTACT_ID,_contact.getContactId());
values.put(DBConstant.All_Contacts_Columns.COLUMN_CONTACT_NUMBER,_contact.getContactNumber());
values.put(DBConstant.All_Contacts_Columns.COLUMN_DISPLAY_NAME,_contact.getContactName());
values.put(DBConstant.All_Contacts_Columns.COLUMN_ZNAME_DP_URL_SMALL,_contact.getContactPhotoUri().toString());
Zname.getApplication().getContentResolver().insert(DBConstant.All_Contacts_Columns.CONTENT_URI,values);
if (cursor != null)
cursor.close();
}
https://developer.android.com/reference/android/provider/ContactsContract.ContactOptionsColumns#LAST_TIME_CONTACTED
如果您想监控整个地址簿甚至一个联系人,您确实可以使用:
applicationContext.contentResolver.registerContentObserver(ContactsContract.Contacts.CONTENT_URI, false, observer)
然后你查询整个通讯录:
applicationContext.contentResolver.query(ContactsContract.Contacts.CONTENT_URI, projection,
null, null, null
)?.use { cursor ->
while (cursor.moveToNext()) {
Log.d("AppLog", "" + DatabaseUtils.dumpCurrentRowToString(cursor))
}
}
您可以将其更改为专注于您想要监控的特定联系人。您可以使用每个联系人的 CONTACT_LAST_UPDATED_TIMESTAMP 查看是否有任何更改。然后,您还可以为自己保存所有您希望在检查中排除和包含的内容。这非常适合您自己的需求。
您可能需要使用一些去抖动技术,特别是当您监视整个地址簿时。操作方法如下: