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

问题描述 投票:2回答:2

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

我发现只有两个广播:

1.DownloadManager.ACTION_DOWNLOAD_COMPLETE 2.DownloadManager.ACTION_NOTIFICTION_CLICKED

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

java android download-manager
2个回答
0
投票

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

1. use the api from DownloadManager, polling status periodically

排队下载任务后,启动以下线程进行检查。

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 to get notified when database changed

下载管理器的内容uri应该是content://downloads/my_downloads,我们可以监视这个数据库的更改。当您使用下载ID开始下载时,将创建一行content://downloads/my_downloads/{downloadId}。我们可以检查此光标以了解此任务是否被取消。如果返回的游标为空或null,则在数据库中找不到记录,则此下载任务将被用户取消。

// 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();
                                }
                            }
                        }
                    }
                }
            });

0
投票

另一种解决方案是在下载目录中使用文件观察器

观察员声明:

private FileObserver fileObserver = new DownloadObserver(
    Environment.getExternalStoragePublicDirectory(
            Environment.DIRECTORY_DOWNLOADS ).getAbsolutePath(), this);

当你想要开始:

fileObserver.startWatching();

当你想要停止时:

fileObserver.stopWatching();

观察员班:

public class DownloadObserver extends FileObserver {

public static final String TAG = "DownloadObserver";

Context context;

private static final int flags =
        FileObserver.CLOSE_WRITE
                | FileObserver.OPEN
                | FileObserver.MODIFY
                | FileObserver.DELETE
                | FileObserver.MOVED_FROM;

public DownloadObserver(String path, Context context) {
    super(path, flags);
    this.context = context;
}

@Override
public void onEvent(int event, String path) {

    if (path == null) {
        return;
    }

    if (event == FileObserver.OPEN || event == FileObserver.CLOSE_WRITE) {
        Log.d(TAG, "started or resumed: " + path);            
    } else if (event == FileObserver.DELETE) {
        Log.e(TAG, "File delete:" + path);
        //Here is your solution. Download was cancel from notification bar
    } else {
        //can be used to update download progress using DownloadManager.Query
    }
}}
© www.soinside.com 2019 - 2024. All rights reserved.