android - DownloadManager 在 INSUFFICIENT_SPACE_ERROR 后不发送广播

标签 android android-download-manager

问题

如果 cache 目录已满,尝试执行一个简单的请求将失败,而不会发送 DownloadManager.ACTION_DOWNLOAD_COMPLETE 广播。

注意:这个问题是普遍存在的,但大多数情况下可以在缓存有限的低端设备上重现(/data/data/com.android.providers.downloads/cache) 尺寸。

代码

接收器配置正确,因为当操作成功和由于其他原因失败时我仍然收到广播。

    DownloadManager.Request request = new DownloadManager.Request(Uri.parse("http://www.apkmirror.com/wp-content/themes/APKMirror/download.php?id=44753"));

    request.setTitle("Facebook");

    DownloadManager downloadManager = (DownloadManager) getSystemService(Context.DOWNLOAD_SERVICE);

    downloadManager.enqueue(request);

所需的解决方案

我对特定问题的解决方案很感兴趣,如果您也遇到过,我想了解更多信息。
正在寻找一种解决方案,要求我停止使用DownloadManager 或添加WRITE_EXTERNAL_STORAGE 权限。

日志

当缓存越来越满,最后当它不能再容纳时,您可以观察到以下日志入口(使用 downloadmanager 过滤)

11-08 08:47:06.079 830-14261/? I/DownloadManager: Download 135 starting
11-08 08:47:06.989 830-14261/? W/DownloadManager: Downloads data dir: /data/data/com.android.providers.downloads/cache is running low on space. space available (in bytes): -6994124
11-08 08:47:06.999 830-14261/? I/DownloadManager: discardPurgeableFiles: destination = 2, targetBytes = 10485760
11-08 08:47:06.999 830-14261/? I/DownloadManager: Purged files, freed 0 for 10485760 requested
11-08 08:47:07.309 830-14261/? W/DownloadManager: Aborting request for download 135: not enough free space in the filesystem rooted at: /data/data/com.android.providers.downloads/cache and unable to free any more
11-08 08:47:07.319 830-14261/? I/DownloadManager: Download 135 finished with status INSUFFICIENT_SPACE_ERROR

这是一个DEMO PROJECT可以证明这个问题。请记住,到那时缓存目录必须已满(不可清除的项目,根据我的经验,这基本上意味着中止下载)

最佳答案

由于DownloadManager本质上是一个系统ContentProvider,你可以向它注册自己的ContentObserver, 所以当下载提供者更新时,它会选择在 INSUFFICIENT_SPACE 的情况下通知观察者。

final DownloadManager downloadManager = (DownloadManager)context.getSystemService(Context.DOWNLOAD_SERVICE);
        context.getContentResolver().registerContentObserver(Uri.parse("content://downloads/my_downloads"),
                true, new ContentObserver(null) {
                    @Override
                    public void onChange(boolean selfChange) {
                        super.onChange(selfChange);
                        Cursor localCursor = downloadManager.query(
                                new DownloadManager.Query());
                        if (localCursor.getCount() == 0) {
                            localCursor.close();
                        }
                        localCursor.moveToFirst();
                        do {
                            if ((localCursor.getInt(localCursor.getColumnIndex(DownloadManager.COLUMN_STATUS)) & DownloadManager.STATUS_FAILED )!=0) {
                                // Download failed, go see why
                                if (localCursor.getInt(localCursor.getColumnIndex(DownloadManager.COLUMN_REASON)) == DownloadManager.ERROR_INSUFFICIENT_SPACE){
                                    Log.w("DownloadStatus", " Download failed with ERROR_INSUFFICIENT_SPACE");
                                }
                            }
                        }while (localCursor.moveToNext());
                    }
                });

注意不要设置状态为 DownloadManager.STATUS_FAILED 的查询过滤器,因为 DownloadManager 奇怪地只将 400 到 600 之间的状态视为失败状态, 但是 INSUFFICIENT_SPACE 有错误代码 198...

android.app.DownloadManager.Request:

Cursor runQuery(ContentResolver resolver, String[] projection, Uri baseUri) {
 .....
 if ((mStatusFlags & STATUS_FAILED) != 0) {
                    parts.add("(" + statusClause(">=", 400)
                              + " AND " + statusClause("<", 600) + ")");
                }
}

关于android - DownloadManager 在 INSUFFICIENT_SPACE_ERROR 后不发送广播,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33595541/

相关文章:

android - 无法在 Playstore 中按应用名称找到应用

javascript - 无法获取资源 'https://jcenter.bintray.com/com/android/tools/build/gradle/2.1.0/gradle-2.1.0.pom'

android - 如何在私有(private)路径中使用 DownloadManager 保存文件?

android - 下载管理器 Android 权限错误 : write external Storage

android - 如何在 LinearLayout 中对齐单选按钮中心

android - <sdk>/tools/adb devices 无法识别用于 Samsung Intercept 的 USB 设备

android - Activity 与 fragment

android - 下载管理器有时显示不成功

java - Android中从本地隐藏文件夹下载图像并显示

android - 如何使用 Google Drive 将文件从 Linux 传输到 Android