web-dev-qa-db-fra.com

Afficher la progression du téléchargement dans l'activité à l'aide de DownloadManager

J'essaie de reproduire la même progression que DownloadManager montre dans la barre de notification de mon application, mais ma progression n'est jamais publiée. J'essaie de le mettre à jour en utilisant runOnUiThread (), mais pour une raison quelconque, il n'a pas été mis à jour.

mon téléchargement:

String urlDownload = "https://dl.dropbox.com/s/ex4clsfmiu142dy/test.zip?token_hash=AAGD-XcBL8C3flflkmxjbzdr7_2W_i6CZ_3rM5zQpUCYaw&dl=1";
DownloadManager.Request request = new DownloadManager.Request(Uri.parse(urlDownload));

request.setDescription("Testando");
request.setTitle("Download");
request.allowScanningByMediaScanner();
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, "teste.Zip");

final DownloadManager manager = (DownloadManager) getSystemService(Context.DOWNLOAD_SERVICE);

final long downloadId = manager.enqueue(request);

final ProgressBar mProgressBar = (ProgressBar) findViewById(R.id.progressBar1);

new Thread(new Runnable() {

    @Override
    public void run() {

        boolean downloading = true;

        while (downloading) {

            DownloadManager.Query q = new DownloadManager.Query();
            q.setFilterById(downloadId);

            Cursor cursor = manager.query(q);
            cursor.moveToFirst();
            int bytes_downloaded = cursor.getInt(cursor
                    .getColumnIndex(DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR));
            int bytes_total = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_TOTAL_SIZE_BYTES));

            if (cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_STATUS)) == DownloadManager.STATUS_SUCCESSFUL) {
                downloading = false;
            }

            final double dl_progress = (bytes_downloaded / bytes_total) * 100;

            runOnUiThread(new Runnable() {

                @Override
                public void run() {

                    mProgressBar.setProgress((int) dl_progress);

                }
            });

            Log.d(Constants.MAIN_VIEW_ACTIVITY, statusMessage(cursor));
            cursor.close();
        }

    }
}).start();

ma méthode statusMessage:

private String statusMessage(Cursor c) {
    String msg = "???";

    switch (c.getInt(c.getColumnIndex(DownloadManager.COLUMN_STATUS))) {
    case DownloadManager.STATUS_FAILED:
        msg = "Download failed!";
        break;

    case DownloadManager.STATUS_PAUSED:
        msg = "Download paused!";
        break;

    case DownloadManager.STATUS_PENDING:
        msg = "Download pending!";
        break;

    case DownloadManager.STATUS_RUNNING:
        msg = "Download in progress!";
        break;

    case DownloadManager.STATUS_SUCCESSFUL:
        msg = "Download complete!";
        break;

    default:
        msg = "Download is nowhere in sight";
        break;
    }

    return (msg);
}

Mon journal fonctionne parfaitement, alors que mon téléchargement est en cours dit "Téléchargement en cours!" Et lorsqu'il est terminé "Téléchargement terminé!", Mais la même chose ne se produit pas sur ma progression, pourquoi? J'en ai vraiment besoin aide, d'autres logiques pour le faire sont vraiment appréciées

81
Victor Laerte

Vous divisez deux entiers:

final double dl_progress = (bytes_downloaded / bytes_total) * 100;

Comme bytes_downloaded est inférieur à bytes_total, (bytes_downloaded / bytes_total) sera 0, et votre progression sera donc toujours 0.

Changez votre calcul en

final int dl_progress = (int) ((bytes_downloaded * 100l) / bytes_total);

pour obtenir les progrès dans les centiles entiers (quoique plancher).

59
Paul Lammertsma

La réponse de Paul est correcte, mais avec des téléchargements plus importants, vous atteindrez max int assez rapidement et commencerez à obtenir une progression négative. Je l'ai utilisé pour résoudre le problème:

final int dl_progress = (int) ((bytes_downloaded * 100l) / bytes_total);
17
JustinMorris

Comme l'a dit Paul, vous divisez deux entiers, avec un résultat toujours <1.

Toujours exprimez votre nombre avant divisez, qui calcule et retourne en virgule flottante.

N'oubliez pas de gérer DivByZero.

final int dl_progress = (int) ((double)bytes_downloaded / (double)bytes_total * 100f);
5
Dennis C