当且仅当 ContactsContract.Contacts.CONTENT_URI 更改时,ContentObserver 应该调用
Posted
技术标签:
【中文标题】当且仅当 ContactsContract.Contacts.CONTENT_URI 更改时,ContentObserver 应该调用【英文标题】:ContentObserver should call if and only if ContactsContract.Contacts.CONTENT_URI changes 【发布时间】:2014-07-10 02:32:03 【问题描述】:由于我的应用程序使用来自 android.provider.ContactsContract.Data
(API > 11) 和 ContactsContract.Contacts.CONTENT_URI
(API 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);
在OnCreate()
的Activity
中注册ContentObserver
ContactsContentObserver contactsContentObserver = new ContactsContentObserver();
getContentResolver().registerContentObserver(ContactsContract.Contacts.CONTENT_URI, false, contactsContentObserver);
在registerContentObserver
上尝试将notifyForDescendents
用作false
。仍然会触发ContentObserver
问题:
如何注册ContentObserver
触发当且仅当联系人信息在除Last_Time_Contacted
或其后代之外的CRUD(创建、更新、删除)下?
【问题讨论】:
【参考方案1】:这里的根本问题是注册ContactsContract.Contacts.CONTENT_URI
并没有像您想象的那样有效。
即使notifyForDescendents
是false
,您也会收到更新的原因是因为触发更新的Uri
是...ContactsContract.Contacts.CONTENT_URI
而不是正在拨打的联系人行.
联系人应用程序中的违规代码可以在 GrepCode 找到,并且在 Google Code 上提交了一个错误。
所以要回答您的问题,您不能注册ContentObserver
,这将触发联系人的特定字段。您需要在您的应用程序中添加一些东西来跟踪计算onChange
触发时的差异。
【讨论】:
有人在那里写道:“从 Android 4.3 开始,我们为每个联系人设置了时间戳,每当我们对特定联系人进行任何更改时,该时间戳都会更新”。知道他在说什么,更重要的是,如何使用它来过滤无帮助的回调,因为没有任何改变?也许他在谈论这个:developer.android.com/reference/kotlin/android/provider/…? 在别处看,也完全不靠谱:***.com/a/57489435/878126【参考方案2】:由于android.provider.ContactsContract
内容提供商有其自身的复杂性,这使得ContentObserver
很难仅通知contacts
内容更改,除非它是LAST_TIME_CONTACTED
字段,因为每个人都会说这些,所以它是。
当ContentObserver
通知时,无论contacts
数据是否更新,都需要开发自己的逻辑。
无论contacts
是否真的得到更新,都需要考虑构建逻辑。
Service
中添加ContentObserver
,即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();
【讨论】:
以上是关于当且仅当 ContactsContract.Contacts.CONTENT_URI 更改时,ContentObserver 应该调用的主要内容,如果未能解决你的问题,请参考以下文章
当且仅当区域在 Emacs 中处于活动状态时,标记是不是处于活动状态?
当且仅当 ContactsContract.Contacts.CONTENT_URI 更改时,ContentObserver 应该调用