ContentObserver 每行实现

Posted

技术标签:

【中文标题】ContentObserver 每行实现【英文标题】:ContentObserver per row implementation 【发布时间】:2014-01-20 10:01:43 【问题描述】:

在“观察”了 ContentObserver 之后,我注意到 API 16 之前的 OnChange 没有传递任何参数,所以我决定在我的项目的每一行中实现它(项目正在使用内置的 DownloadManager 下载 url)

我为每一行创建一个新的 ContentObserver :

    Uri downloadsContentUri = Uri.parse("content://downloads/my_downloads/downloads/" + appDownloadId);
    DownloadsObserver downloadsObserver = new DownloadsObserver(downloadId, new Handler());
    getContentResolver().registerContentObserver(downloadsContentUri, true, downloadsObserver);

你可以看到 Uri 总是通过行 id 改变(在我检查过的 DownloadManager DB 上它是相同的),并且在这段代码之后,我将所有观察者存储在一个列表中, 奇怪的是 OnChange 只被调用一次,并且只在第一次下载时被调用,即使在下载完成后也不会再次调用..

我在这里做错了什么? 如何完成对 DownloadManager DB 上每一行的观察? (我是系统应用)

谢谢。

【问题讨论】:

您是否考虑将一个 ContentObserver 注册到 uri 并在 onChange 方法中检查导致更改的最后一条记录? 谷歌搜索后如何检查导致更改的最后一条记录? 您是否在 _id 上使用自动增量? id是DownloadManager的Downloads.db给我的id,我打开了这个表(根设备)并确认这是我正在寻找的下载的id... 表中是否有可以识别最后一条记录的字段?一些时间戳 【参考方案1】:

我明白了!

这是我针对每一行的 ContentObserver 的解决方案,这可以应用于 API 15(15 没有像 API 16 上的 OnChange 和 URI 参数)。 当然,您需要为每一行创建一个新的 ContentObserver。

错误就在这一行

 Uri downloadsContentUri = Uri.parse("content://downloads/my_downloads/downloads/" + appDownloadId);

它应该没有“/downloads/”,像这样:

Uri downloadsContentUri = Uri.parse("content://downloads/my_downloads/" + appDownloadId);

这是我的 ContentObserver:

public class DownloadsObserver extends ContentObserver

private long mAppDownloadId = 0;

public DownloadsObserver(Handler handler)

    super(handler);


public DownloadsObserver(long appDownloadId, Handler handler)

    super(handler);
    mAppDownloadId = appDownloadId;



@Override
public void onChange(boolean selfChange)

    super.onChange(selfChange);
    // Do some work on this row with the id



【讨论】:

以上是关于ContentObserver 每行实现的主要内容,如果未能解决你的问题,请参考以下文章

为啥 ContentObserver 会被多次调用?

如何注册 ContentObserver 以更改媒体音量?

自动填充短信验证码(使用ContentObserver)

用于 SMS 的 ContentObserver [重复]

Android ContentProviderContentResolver和ContentObserver的使用

SMS 发送观察者执行 3 次