在下载管理器中,如何从通知栏中“取消”时获取状态?

Ank*_*ini 5 java android download-manager

我正在使用下载管理器在 android 中下载文件。但是在点击通知栏中的“取消”按钮的情况下,我无法获得任何广播。

我发现只有两个广播:

1. DownloadManager.ACTION_DOWNLOAD_COMPLETE 2.DownloadManager.ACTION_NOTIFICTION_CLICKED

下载管理器取消时是否有任何广播?如果没有,请给我任何解决方案如何处理它?

ali*_*dro 1

DownloadManager当它处理用户下载任务时,会将信息写入数据库。因此我们可以检查数据库的状态来了解任务是否被取消。

1.使用来自 的api 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);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

2.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();
                                }
                            }
                        }
                    }
                }
            });
Run Code Online (Sandbox Code Playgroud)