App 里有本地相册功能,需要通过 ContentObserver 监听系统数据库变化,从而保证系统相册有数据更新时,App 相册能及时更新,但最近报出某些机型用相机拍照回到 app 后不能刷新相册,最终定位到了是 Android Q 中 ContentObserver 没能收到 onChange 数据导致的
解决办法
/**
* Register an observer class that gets callbacks when data identified by a
* given content URI changes.
* <p>
* Starting in {@link android.os.Build.VERSION_CODES#O}, all content
* notifications must be backed by a valid {@link ContentProvider}.
*
* @param uri The URI to watch for changes. This can be a specific row URI,
* or a base URI for a whole class of content.
* @param notifyForDescendants When false, the observer will be notified
* whenever a change occurs to the exact URI specified by
* <code>uri</code> or to one of the URI's ancestors in the path
* hierarchy. When true, the observer will also be notified
* whenever a change occurs to the URI's descendants in the path
* hierarchy.
* @param observer The object that receives callbacks when changes occur.
* @see #unregisterContentObserver
*/
public final void registerContentObserver(@NonNull Uri uri, boolean notifyForDescendants,
@NonNull ContentObserver observer) {
Preconditions.checkNotNull(uri, "uri");
Preconditions.checkNotNull(observer, "observer");
registerContentObserver(
ContentProvider.getUriWithoutUserId(uri),
notifyForDescendants,
observer,
ContentProvider.getUserIdFromUri(uri, mContext.getUserId()));
}
我们在注册 ContentObserver 时,会传两个重要的参数,Uri 和 notifyForDescendants,其中 Uri 就是系统发生变化的文件对应的 Uri,比如想监听系统图片变化,就使用 MediaStore.Images.Media.EXTERNAL_CONTENT_URI
,第二个参数比较重要,大概意思就是是否要精确匹配 Uri,如果 false 代表要精确匹配,true 就不要,具体例子可以参考这篇文章 android notifyForDescendents 为false 的含义
这里直接借用一下文中的结论
假设UriMatcher 里注册的Uri共有一下类型:
1 、content://com.qin.cb/student (学生)
2 、content://com.qin.cb/student/#
3、 content://com.qin.cb/student/schoolchild(小学生,派生的Uri)
假设我们当前需要观察的Uri为content://com.qin.cb/student,如果发生数据变化的Uri为
content://com.qin.cb/student/schoolchild ,当notifyForDescendents为 false,那么该ContentObserver会监听不到,
但是当notifyForDescendents 为ture,能捕捉该Uri的数据库变化。
原来版本的 App 这个参数传的是 false ,最终在 Android Q 中传 true 解决了这个问题,为避免其他 Android 版本受到影响,最好做个版本判断
原因
具体原因还没细究,日后有空会分析原因,补上此部分