Android DownloadManager Progress

后端 未结 2 1298
余生分开走
余生分开走 2020-12-02 09:38

i\'m developing an app where users are able to download different content packages. For the download process i am using the DownloadManager class. Thats working fine so far.

2条回答
  •  南方客
    南方客 (楼主)
    2020-12-02 09:59

    It turns out that the FileObserver implementation on Marshmallow has a bug. As a result, FileObserver will not report any modifications of a file downloaded by the download manager. (Older Android versions do not have this issue – it works fine on KitKat.) Source

    For me, the following code (based on this answer) works well. I poll every second – I've tried halving that interval, but without any visible effect.

    private static final int PROGRESS_DELAY = 1000;
    Handler handler = new Handler();
    private boolean isProgressCheckerRunning = false;
    
    // when the first download starts
    startProgressChecker();
    
    // when the last download finishes or the Activity is destroyed
    stopProgressChecker();
    
    /**
     * Checks download progress.
     */
    private void checkProgress() {
        DownloadManager.Query query = new DownloadManager.Query();
        query.setFilterByStatus(~(DownloadManager.STATUS_FAILED | DownloadManager.STATUS_SUCCESSFUL));
        Cursor cursor = downloadManager.query(query);
        if (!cursor.moveToFirst()) {
            cursor.close();
            return;
        }
        do {
            long reference = cursor.getLong(cursor.getColumnIndex(DownloadManager.COLUMN_ID));
            long progress = cursor.getLong(cursor.getColumnIndex(DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR));
            // do whatever you need with the progress
        } while (cursor.moveToNext());
        cursor.close();
    }
    
    /**
     * Starts watching download progress.
     * 
     * This method is safe to call multiple times. Starting an already running progress checker is a no-op.
     */
    private void startProgressChecker() {
        if (!isProgressCheckerRunning) {
            progressChecker.run();
        isProgressCheckerRunning = true;
        }
    }
    
    /**
     * Stops watching download progress.
     */
    private void stopProgressChecker() {
        handler.removeCallbacks(progressChecker);
        isProgressCheckerRunning = false;
    }
    
    /**
     * Checks download progress and updates status, then re-schedules itself.
     */
    private Runnable progressChecker = new Runnable() {
        @Override
        public void run() {
            try {
                checkProgress();
                // manager reference not found. Commenting the code for compilation
                //manager.refresh();
            } finally {
                handler.postDelayed(progressChecker, PROGRESS_DELAY);
            }
        }
    };
    

提交回复
热议问题