DownloadManager
当它处理用户下载任务时,会将信息写入数据库。因此我们可以检查数据库的状态来了解任务是否被取消。
1.使用来自DownloadManager
,定期轮询状态
将下载任务放入队列后,启动以下线程进行检查。
private static class DownloadQueryThread extends Thread {
private static final String TAG = "DownloadQueryThread";
private final WeakReference<Context> context;
private DownloadManager downloadManager;
private final DownloadManager.Query downloadQuery;
private boolean shouldStopQuery = false;
private boolean downloadComplete = false;
private static final Object LOCK = new Object();
private final BroadcastReceiver downloadCompleteBroadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (DownloadManager.ACTION_DOWNLOAD_COMPLETE.equals(intent.getAction())) {
synchronized (LOCK) {
shouldStopQuery = true;
downloadComplete = true;
}
}
}
};
/**
* Create from context and download id
* @param context the application context
* @param queryId the download id from {@link DownloadManager#enqueue(DownloadManager.Request)}
*/
public DownloadQueryThread(Context context, long queryId) {
this.context = new WeakReference<>(context);
this.downloadQuery = new DownloadManager.Query().setFilterById(queryId);
this.downloadManager = (DownloadManager) context.getSystemService(DOWNLOAD_SERVICE);
}
@Override
public void run() {
super.run();
if (context.get() != null) {
context.get().registerReceiver(downloadCompleteBroadcastReceiver,
new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE));
}
while (true) {
if (downloadManager != null) {
Cursor cursor = downloadManager.query(downloadQuery);
if (cursor != null && cursor.moveToFirst()) {
Log.d(TAG, "download running");
} else {
shouldStopQuery = true;
}
}
synchronized (LOCK) {
if (shouldStopQuery) {
if (downloadComplete) {
Log.d(TAG, "download complete");
} else {
Log.w(TAG, "download cancel");
}
break;
}
}
try {
sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
if (context.get() != null) {
context.get().unregisterReceiver(downloadCompleteBroadcastReceiver);
}
}
}
2.use ContentObserver
当数据库更改时收到通知
下载管理器的内容 uri 应该是content://downloads/my_downloads
,我们可以监控这个数据库的变化。当您使用下载 ID 开始下载时,将创建一行content://downloads/my_downloads/{downloadId}
。我们可以检查这个光标来知道这个任务是否被取消。如果返回的游标为空或为空,数据库中没有找到记录,则用户取消本次下载任务。
// get the download id from DownloadManager#enqueue
getContentResolver().registerContentObserver(Uri.parse("content://downloads/my_downloads"),
true, new ContentObserver(null) {
@Override
public void onChange(boolean selfChange, Uri uri) {
super.onChange(selfChange, uri);
if (uri.toString().matches(".*\\d+$")) {
long changedId = Long.parseLong(uri.getLastPathSegment());
if (changedId == downloadId[0]) {
Log.d(TAG, "onChange: " + uri.toString() + " " + changedId + " " + downloadId[0]);
Cursor cursor = null;
try {
cursor = getContentResolver().query(uri, null, null, null, null);
if (cursor != null && cursor.moveToFirst()) {
Log.d(TAG, "onChange: running");
} else {
Log.w(TAG, "onChange: cancel");
}
} finally {
if (cursor != null) {
cursor.close();
}
}
}
}
}
});