即使光标没有变化,ContentObserver也会被调用
我有一个内容观察者,当我的同步适配器添加的联系人之一被修改时,应该通知该内容观察者。 我注册和取消注册观察者是这样做的:
private static final Uri MYAPP_CONTENT_URI = ContactsContract.RawContacts.CONTENT_URI.buildUpon().appendQueryParameter(RawContacts.ACCOUNT_NAME, SyncAdapter.MYAPP_ACCOUNT_NAME).appendQueryParameter(RawContacts.ACCOUNT_TYPE, MY_APP_ACCOUNT_TYPE).build();
public static void registerContentObserver() {
ContentResolver resolver = MyApplication.getAppContext().getContentResolver();
cursorContacts = resolver.query(MYAPP_CONTENT_URI, null, RawContacts.DELETED + "=0", null, null);
cursorContacts.registerContentObserver(MYAPP_URI_OBSERVER);
}
public static void unregisterContentObserver() {
if (cursorContacts != null) {
cursorContacts.unregisterContentObserver(MYAPP_URI_OBSERVER);
cursorContacts.close();
}
}
问题是,即使在注册观察者后光标为空(getCount 返回 0),我也会调用 onChange,无论我在本机地址簿中执行什么操作。 难道只有当游标中的条目之一被修改时才调用观察者吗? 文档指出:
注册一个观察者,当支持该光标的内容发生更改时调用该观察者
什么是“支持该光标的内容”?我以为它是光标中联系人的lookupuri列表,但看起来只需在ContactsContract.RawContacts.CONTENT_URI中进行更改就足够了。
我还尝试为每个 Uri 注册一个观察者。这没有帮助。尽管 ContentResolver.registerContentObserver 的文档指出:
注册一个观察者类,当给定内容 URI 标识的数据发生更改时,该类会获取回调。
Parameters
uri The URI to watch for changes. This can be a specific row URI, or a base URI for a whole class of content.
notifyForDescendents If true changes to URIs beginning with uri will also cause notifications to be sent. If false only changes to the exact URI specified by uri will cause notifications to be sent. If true, than any URI values at or below the specified URI will also trigger a match.
(我将notifyForDescendents设置为false,但在任何情况下它都不应该调用观察者)。
怎么了? 谢谢
I have a content observer that should be notified when one of the contacts added by my sync adapter is modified.
I register and unregister the observer doing this:
private static final Uri MYAPP_CONTENT_URI = ContactsContract.RawContacts.CONTENT_URI.buildUpon().appendQueryParameter(RawContacts.ACCOUNT_NAME, SyncAdapter.MYAPP_ACCOUNT_NAME).appendQueryParameter(RawContacts.ACCOUNT_TYPE, MY_APP_ACCOUNT_TYPE).build();
public static void registerContentObserver() {
ContentResolver resolver = MyApplication.getAppContext().getContentResolver();
cursorContacts = resolver.query(MYAPP_CONTENT_URI, null, RawContacts.DELETED + "=0", null, null);
cursorContacts.registerContentObserver(MYAPP_URI_OBSERVER);
}
public static void unregisterContentObserver() {
if (cursorContacts != null) {
cursorContacts.unregisterContentObserver(MYAPP_URI_OBSERVER);
cursorContacts.close();
}
}
The problem is that even when the cursor is empty (getCount returns 0) after I register the observer I get a call to onChange what ever I do in the native address book.
Shoudn't the observer be called only when one of the entries in the cursor was modified?
The documentation states:
Register an observer that is called when changes happen to the content backing this cursor
What's "the content that is backing this cursor"? I thought it was the list of lookupuri of the contacts in the cursor but it looks like it is enough to have a change in the ContactsContract.RawContacts.CONTENT_URI.
I have also tried to register one observer for each Uri. It does not help. Although the documentation for ContentResolver.registerContentObserver states:
Register an observer class that gets callbacks when data identified by a given content URI changes.
Parameters
uri The URI to watch for changes. This can be a specific row URI, or a base URI for a whole class of content.
notifyForDescendents If true changes to URIs beginning with uri will also cause notifications to be sent. If false only changes to the exact URI specified by uri will cause notifications to be sent. If true, than any URI values at or below the specified URI will also trigger a match.
(I set notifyForDescendents to false but it shouldn't have called the observers in any case).
What's wrong?
Thank-you
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
由内容提供商决定何时报告更改。对于复杂的内容提供程序(例如联系人提供程序),确定因操作而更改的所有特定 URI 可能非常困难,因此它们只是在发生某些情况时报告全局更改。
It is up to the content provider to decide when to report changes. For complicated content providers (like the contacts provider) it can be very difficult to determine all of the specific URIs that change due to an operation, so they just report a global change when something happens.
当观察者 Uri 匹配发生时,您的 Uri、Fragment 甚至 Scheme 中的查询参数都不会被考虑。唯一重要的是 Uri 权限和路径段。发生严格的从左到右匹配。我没有在路径段中测试“*”来表示通配符,但我怀疑它不起作用。
您的特定观察者是 ContactsContract.RawContacts.CONTENT_URI,因此每当任何联系人内容因任何原因发生更改时,您的观察者都会触发。
Query parameters in your Uri, the Fragment, nor even the Scheme are considered when Observer Uri matching occurs. The only thing that matters is the Uri Authority and the Path Segments. Strict left to right matching occurs. I have not tested "*" in a path segment to denote a wildcard, but I suspect that it will not work.
Your particular Observer is ContactsContract.RawContacts.CONTENT_URI, so any time any contact content changes for any reason, your Observer will fire.