【问题标题】:In Download manager, how to get status when its "cancel" from notification bar?在下载管理器中,如何从通知栏“取消”时获取状态?
【发布时间】:2018-01-14 09:40:23
【问题描述】:

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

我发现只有两个广播:

1.DownloadManager.ACTION_DOWNLOAD_COMPLETE 2.DownloadManager.ACTION_NOTIFICTION_CLICKED

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

【问题讨论】:

  • 当您按下取消按钮时,您应该查询下载管理器以查看您的下载状态。
  • stackoverflow.com/questions/42029895 的副本。请参阅我的答案已被接受为正确解决方案的其他问题。

标签: java android download-manager


【解决方案1】:

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

1。使用DownloadManager的api,定期轮询状态

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

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.使用ContentObserver在数据库更改时得到通知

下载管理器的内容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();
                                }
                            }
                        }
                    }
                }
            });

【讨论】:

    【解决方案2】:

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

    观察者声明:

    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
        }
    }}
    

    【讨论】:

      猜你喜欢
      • 2017-11-22
      • 1970-01-01
      • 2017-06-21
      • 1970-01-01
      • 2018-05-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多