Estoy tratando de reproducir el mismo progreso que muestra DownloadManager en la barra de notificaciones dentro de mi aplicación, pero mi progreso nunca se publica. Estoy tratando de actualizarlo usando runOnUiThread (), pero por alguna razón no se ha actualizado.
mi descarga:
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();
mi método 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);
}
Mi registro funciona perfectamente, mientras mi descarga se está ejecutando dice "¡Descarga en curso!" y cuando se completa "¡Descarga completa!", pero no ocurre lo mismo con mi progreso, ¿por qué? Realmente necesito ayuda, otras lógicas para hacer que son muy apreciadas
android
progress-bar
Victor Laerte
fuente
fuente
Respuestas:
Estás dividiendo dos números enteros:
Como
bytes_downloaded
es menor quebytes_total
,(bytes_downloaded / bytes_total)
será 0 y, por lo tanto, su progreso siempre será 0.Cambie su cálculo a
para obtener el progreso en percentiles completos (aunque en el suelo).
fuente
division by zero
error fatal. Es por eso que lo hice comofinal int dl_progress = ( bytes_total > 0 ? (int) ((bytes_downloaded * 100L) / bytes_total) : 0 );
La respuesta de Paul es correcta, pero con descargas más grandes llegará a max int bastante rápido y comenzará a obtener un progreso negativo. Usé esto para resolver el problema:
fuente
Como dijo Paul, estás dividiendo dos números enteros, con el resultado siempre <1.
Siempre lanza tu número antes de dividir, que calcula y devuelve en punto flotante.
No olvide manejar DivByZero.
fuente
En caso de que alguien necesite implementar el recuperador de progreso de descarga de la pregunta de @Victor Laerte en Kotlin con RxJava, aquí tienes:
DescargarStateRetriever.kt
He agregado extensiones al cursor para mayor claridad del código:
CursorExtensions.kt
fuente