2013-04-03 7 views
63

Próbuję odtworzyć ten sam postęp, jaki funkcja DownloadManager wyświetla na pasku powiadomień w mojej aplikacji, ale moje postępy nigdy nie zostaną opublikowane. Próbuję zaktualizować go za pomocą runOnUiThread(), ale z jakiegoś powodu nie został zaktualizowany.Pokaż postęp pobierania wewnątrz aktywności za pomocą narzędzia DownloadManager

moja pobrania:

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(); 

moja metoda Komunikat stanu:

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

Mój dziennik pracuje idealnie, podczas gdy mój pobieranie pracuje mówi "! Pobierania w toku" i kiedy jest kompletny "Pobierz kompletny!", ale to samo nie dzieje się na moich postępach, dlaczego? I naprawdę potrzebują pomocy, inne logiki do zrobienia, że ​​są naprawdę cenione

+0

Czy to możliwe, że plik jest po prostu za mały i pobieranie jest ukończone przed opublikowaniem postępu? Co zwraca zapytanie o pobieranie w twoim zadaniu? Jeśli zadanie zostanie wykonane dopiero po pewnym czasie, możesz wykonać inną długotrwałą operację na głównym wątku. –

+0

Zaktualizowałem kod, czy możesz teraz rzucić okiem? I o długości pliku nie jest zbyt mały, widzę postęp pobierania na pasku powiadomień –

Odpowiedz

40

Jesteś dzieląc dwie liczby całkowite:

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

Jak bytes_downloaded jest mniejsza niż bytes_total, (bytes_downloaded/bytes_total) będzie 0, a postęp będzie zatem zawsze 0.

Zmień swoje obliczenia do

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

uzyskanie Progr w całych (aczkolwiek pełnych) percentylach.

+0

@AZ_ Dziękuję za Twój wkład. Proponuję dodać własną odpowiedź za pomocą bardziej skomplikowanego rozwiązania. –

+0

W porządku, nie chcę dodawać odpowiedzi już zaakceptowanej, ponieważ będzie to trudne dla użytkowników. Możesz nie zaakceptować mojej edycji :) –

14

Odpowiedź Paula jest prawidłowa, ale przy większych pobraniach osiągniesz maksymalną prędkość i zaczniesz robić negatywne postępy. Kiedyś rozwiązać ten problem:

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

Masz rację; Zmieniłem swoją odpowiedź, aby upewnić się, że inni nie popełnią tego samego błędu. –

5

jak Paweł powiedział, jesteś podzielenie dwie liczby całkowite, z wynikiem zawsze < 1.

Zawsze oddać swój numer przed przepaści, która oblicza i powrotu w wartościach zmiennoprzecinkowych.

Nie zapomnij poradzić sobie z DivByZero.

final int dl_progress = (int) ((double)bytes_downloaded/(double)bytes_total * 100f); 
Powiązane problemy