是否可以取消/停止使用 DownloadManager 开始的下载?
Posted
技术标签:
【中文标题】是否可以取消/停止使用 DownloadManager 开始的下载?【英文标题】:Is it possible to cancel/stop a download started using DownloadManager? 【发布时间】:2012-12-13 22:39:15 【问题描述】:我正在使用 DownloadManager 在我的应用程序中下载一堆文件。我无法弄清楚如何取消已由 downloadManager 排队的下载。
有两种可能: 一种。用户可以通过在通知栏中单击它来手动取消它。 湾。通过代码取消并删除下载。
我定义了以下接收器。
<receiver
android:name=".DownloadStatusReceiver"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.DOWNLOAD_COMPLETE" />
<action android:name="android.intent.action.DOWNLOAD_NOTIFICATION_CLICKED" />
</intent-filter>
</receiver>
在接收器中
if (DownloadManager.ACTION_NOTIFICATION_CLICKED.equals(action))
Constants.showLog(TAG, "Notification clicked");
long downloadId = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, 0);
DownloadManager dm =(DownloadManager)context.getSystemService(Context.DOWNLOAD_SERVICE);
dm.remove(downloadId);
有什么见解吗?
【问题讨论】:
根据文档,remove()
应该可以工作。当然,在下载完成之前,您似乎不会调用remove()
。这就像在马跑了之后锁住了谷仓。 :-)
我会实现自己的下载工作流程,因为内置的下载管理器有问题,不能在旧设备上运行。
@CommonsWare:单击通知栏时我正在调用删除。我假设通知点击事件来自下载是否完成。
击败我。我没有玩太多的通知点击。尝试在您的控制范围内尝试使用remove()
,例如Button
或操作栏项目。另外,您是否确认 downloadId
会返回一个与您的原始请求相匹配的值?
我修好了。对我来说,我正在下载多个文件,它们在同一个进度条上聚集在一起。所以现在只要我收到点击广播的通知,我就会查询并遍历 Id 并将它们一一删除。作品。我不确定的唯一问题是它是否还会删除我的应用程序未启动的下载。
【参考方案1】:
您可以通过DownloadManager
调用其remove(long...)
方法来取消下载。为此,您需要下载的 ID。根据我的经验,基本上有两种可靠的方法来获得它:
-
记住
enqueue(DownloadManager.Request)
方法的返回值。
通过query(DownloadManager.Query)
方法查询DownloadManager
以获取下载。然后从返回的Cursor
中检索ID,它们存储在名为DownloadManager.COLUMN_ID
的列中。
广播接收器
根据我的经验,通过 BroadcastReceiver
检索下载 ID 以执行操作 android.intent.action.DOWNLOAD_NOTIFICATION_CLICKED
是不可靠的(尽管总是发送广播)。
-
从额外的
DownloadManager. EXTRA_NOTIFICATION_CLICK_DOWNLOAD_IDS
获取下载 ID 无法正常工作。在某些设备上,它总是返回 null。如果它在某些设备上返回某些内容,则它是首先开始下载的 ID。如果第一次下载完成/取消,则返回 null 以通知剩余下载。
从额外的DownloadManager.EXTRA_DOWNLOAD_ID
获取值不适用于此操作。
在广播中获取 ID 以供行动android.intent.action.DOWNLOAD_COMPLETE
似乎可靠。您必须从额外的DownloadManager.EXTRA_DOWNLOAD_ID
获得它。请注意,广播不仅会在下载完成时发送,还会在您取消下载调用remove()
时发送。
注意: 下载有时会在一个通知中分组,有时会创建多个通知。我无法弄清楚通知何时分组和不分组的条件。它似乎取决于许多因素,例如操作系统版本、设备、下载标题……而且总体而言似乎相当不可预测。
注意:
我测试了你是否可以取消其他应用程序的下载,但似乎不能。即使 ID 是在所有应用程序中唯一的数据库 ID。调用 remove()
不会取消其他应用的下载。
【讨论】:
感谢 Tomik,您总结得很好,我同意我也观察到了同样的情况。我接受这个答案,因为它会在未来帮助其他人。 非常有用。提供个人经验总是最有价值的东西,你可以节省很多时间。 @Tomik,那么实际上在 DOWNLOAD_NOTIFICATION_CLICKED 上获取 id 的最佳方式是什么?我正在同时下载多个文件,无法保留所有 id。 如果我不知道 ID 怎么办,因为它是由另一个应用程序或实例启动的?如何添加所有下载? 你的答案是正确的。但是如何重新开始下载。你有任何完整的来源作为例子。【参考方案2】:如果您正在寻找如何停止下载,那么我相信您知道如何通过 URL 下载数据。 我希望您熟悉第 1 点、第 2 点和第 3 点,您的解决方案是第 4 点。
private var mgr: DownloadManager? = null
private var enqueue: Long? = null
enqueue = mgr?.enqueue(request)
mgr?.remove(enqueue!!)
【讨论】:
以上是关于是否可以取消/停止使用 DownloadManager 开始的下载?的主要内容,如果未能解决你的问题,请参考以下文章