Saya mencoba mereproduksi kemajuan yang sama yang ditunjukkan DownloadManager di bilah Pemberitahuan di dalam aplikasi saya, tetapi kemajuan saya tidak pernah dipublikasikan. Saya mencoba memperbaruinya menggunakan runOnUiThread (), tetapi untuk beberapa alasan itu belum diperbarui.
unduhan saya:
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();
metode statusMessage saya:
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);
}
Log saya bekerja dengan sempurna, saat unduhan saya berjalan, bertuliskan "Unduhan sedang berlangsung!" dan setelah selesai "Download selesai!", tetapi hal yang sama tidak terjadi pada kemajuan saya, mengapa? Saya benar-benar membutuhkan bantuan, logika lain untuk melakukan itu sangat dihargai
android
progress-bar
Victor Laerte
sumber
sumber
Jawaban:
Anda membagi dua bilangan bulat:
final double dl_progress = (bytes_downloaded / bytes_total) * 100;
As
bytes_downloaded
kurang daribytes_total
,(bytes_downloaded / bytes_total)
akan menjadi 0, dan karena itu kemajuan Anda akan selalu 0.Ubah perhitungan Anda menjadi
final int dl_progress = (int) ((bytes_downloaded * 100l) / bytes_total);
untuk mendapatkan kemajuan dalam persentil keseluruhan (meskipun berlantai).
sumber
division by zero
error yang fatal. Itulah mengapa saya melakukannya sepertifinal int dl_progress = ( bytes_total > 0 ? (int) ((bytes_downloaded * 100L) / bytes_total) : 0 );
Jawaban Paul benar tetapi dengan unduhan yang lebih besar Anda akan mencapai max int dengan cukup cepat dan mulai mendapatkan kemajuan negatif. Saya menggunakan ini untuk menyelesaikan masalah:
final int dl_progress = (int) ((bytes_downloaded * 100l) / bytes_total);
sumber
Seperti yang dikatakan paul, Anda membagi dua bilangan bulat, dengan hasil selalu <1.
Selalu berikan bilangan Anda sebelum membagi, yang menghitung dan mengembalikan dalam titik-mengambang.
Jangan lupa untuk menangani DivByZero.
final int dl_progress = (int) ((double)bytes_downloaded / (double)bytes_total * 100f);
sumber
Jika seseorang membutuhkan implementasi download progress retriever dari pertanyaan @Victor Laerte di Kotlin dengan RxJava ini dia:
DownloadStateRetriever.kt
class DownloadStateRetriever(private val downloadManager: DownloadManager) { fun retrieve(id: Long) { var downloading = AtomicBoolean(true) val disposable = Observable.fromCallable { val query = DownloadManager.Query().setFilterById(id) val cursor = downloadManager.query(query) cursor.moveToFirst() val bytesDownloaded = cursor.intValue(DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR) val bytesTotal = cursor.intValue(DownloadManager.COLUMN_TOTAL_SIZE_BYTES) if (isSuccessful(cursor)) downloading.set(false) cursor.close() if (bytesTotal == 0) 0.toInt() else ((bytesDownloaded * 100F) / bytesTotal).toInt() } .subscribeOn(Schedulers.newThread()) .delay(1, TimeUnit.SECONDS) .repeatUntil { !downloading.get() } .subscribe { Timber.i("Subscribed to $id. progress: $it") } } private fun isSuccessful(cursor: Cursor) = status(cursor) == DownloadManager.STATUS_SUCCESSFUL private fun status(cursor: Cursor) = cursor.intValue(DownloadManager.COLUMN_STATUS) }
Saya telah menambahkan ekstensi ke kursor agar kode lebih jelas:
CursorExtensions.kt
import android.database.Cursor fun Cursor.column(which: String) = this.getColumnIndex(which) fun Cursor.intValue(which: String): Int = this.getInt(column(which)) fun Cursor.floatValue(which: String): Float = this.getFloat(column(which)) fun Cursor.stringValue(which: String): String = this.getString(column(which)) fun Cursor.doubleValue(which: String): Double = this.getDouble(column(which))
sumber