当且仅当 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_CONTACTEDContactsContract.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 并没有像您想象的那样有效。

即使notifyForDescendentsfalse,您也会收到更新的原因是因为触发更新的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 中处于活动状态时,标记是不是处于活动状态?

当且仅当 CGPoint 在视图内持续 2 秒时才启动函数

强制 Emacs 使用特定的编码,当且仅当这不会导致问题

当且仅当 ContactsContract.Contacts.CONTENT_URI 更改时,ContentObserver 应该调用

当且仅当文本框具有焦点并且按下“输入”时才实现插槽功能?

Hibernate HQL:当且仅当所有子实体都具有相同值的属性时,如何选择父实体?