Android Múltiples pausas de descarga reanudar en listview con actualización de progreso

Estoy intentando descargar varios archivos en listview con la barra de progreso. Lo que logré es, puedo iniciar una descarga en particular, pausar / reanudar con AsyncTask y la barra de progreso se actualiza (para un solo archivo), esta parte funciona bien

Mi problema es que no soy capaz de descargar múltiples archivos simultáneamente y cuando dejo el listview a otra pantalla, aunque mi descarga está pasando en segundo plano, pero el progreso no se actualiza, la barra de progreso muestra 0 progreso como si no se descarga, pero ha sido Descarga en segundo plano.

Finalmente encontré la respuesta que era mucho más simple de lo que pensaba, aquí es como sigue

  1. Crear un service con Asynctask para la descarga y hashtable de valores (url, Asynctask)
  2. Pase el valor (url, Asynctask) cuando se hace clic en un elemento de lista y compruebe si ese hashtable contiene el valor ya si sí cancela esa tarea de Asynctask si no lo agrega a hashtable e inicia Asynctask
  3. Ahora para actualizar el progreso en mi adapter corrí un hilo que iterar sobre hashtable y pasa el valor usando BroadcastListener .
  4. Y en actividad interceptar la broadcast y dependiendo del ListItem visible actualizar el progreso

PS: Si alguien necesita algún código puedo proporcionar el código básico de la descripción explicada anteriormente

 public class DownloadingService extends Service { public static String PROGRESS_UPDATE_ACTION = DownloadingService.class.getName() + ".progress"; private static final long INTERVAL_BROADCAST = 800; private long mLastUpdate = 0; private Hashtable<String, DownloadFile> downloadTable; private LocalBroadcastManager broadcastManager; @Override public int onStartCommand(Intent intent, int flags, int startId) { MessageEntity entityRecieved = (MessageEntity) intent.getSerializableExtra("ENTITY"); queueDownload(entityRecieved); return super.onStartCommand(intent, flags, startId); } private void queueDownload(MessageEntity entityRecieved){ if (downloadTable.containsKey(entityRecieved.getPacketID())) { DownloadFile downloadFile = downloadTable.get(entityRecieved.getPacketID()); if (downloadFile.isCancelled()) { downloadFile = new DownloadFile(entityRecieved); downloadTable.put(entityRecieved.getPacketID(), downloadFile); startDownloadFileTask(downloadFile); } else { downloadFile.cancel(true); downloadTable.remove(entityRecieved.getPacketID()); } } else { DownloadFile downloadFile = new DownloadFile(entityRecieved); downloadTable.put(entityRecieved.getPacketID(), downloadFile); startDownloadFileTask(downloadFile); } } @Override public void onCreate() { super.onCreate(); downloadTable = new Hashtable<String, DownloadFile>(); broadcastManager = LocalBroadcastManager.getInstance(this); } @TargetApi(Build.VERSION_CODES.HONEYCOMB) void startDownloadFileTask(DownloadFile asyncTask) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) asyncTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); else asyncTask.execute(); } private void publishCurrentProgressOneShot(boolean forced) { if (forced || System.currentTimeMillis() - mLastUpdate > INTERVAL_BROADCAST) { mLastUpdate = System.currentTimeMillis(); int[] progresses = new int[downloadTable.size()]; String[] packetIds = new String[downloadTable.size()]; int index = 0; Enumeration<String> enumKey = downloadTable.keys(); while (enumKey.hasMoreElements()) { String key = enumKey.nextElement(); int val = downloadTable.get(key).progress; progresses[index] = val; packetIds[index++] = key; } Intent i = new Intent(); i.setAction(PROGRESS_UPDATE_ACTION); i.putExtra("packetIds", packetIds); i.putExtra("progress", progresses); mBroadcastManager.sendBroadcast(i); } class DownloadFile extends AsyncTask<Void, Integer, Void> { private MessageEntity entity; private File file; private int progress; public DownloadFile(MessageEntity entity) { this.entity = entity; } @Override protected Void doInBackground(Void... arg0) { String filename = entity.getMediaURL().substring(entity.getMediaURL().lastIndexOf('/') + 1); file = new File(FileUtil.getAppStorageDir().getPath(), filename); downloadFile(entity.getMediaURL(), file); return null; } public String downloadFile(String download_file_path, File file) { int downloadedSize = 0; int totalSize = 0; try { // download the file here while ((bufferLength = inputStream.read(buffer)) > 0 && !isCancelled()) { progress = percentage; publishCurrentProgressOneShot(true); } } catch (final Exception e) { return null; } return file.getPath(); } } 

En el problema grande con AsynchTask es cuando usted termina su actividad, AsynchTask pierde su pista con su UI. Después de eso, cuando regreses a esa actividad, la barra de progreso no se actualiza aunque el progreso de la descarga siga funcionando en segundo plano. De hecho, AsynchTask no pertenece a la nueva Actividad que almorzaste, por lo que la nueva instancia de la barra de progreso en la nueva Actividad no se actualizará. Para solucionar este problema te sugiero:

1- Ejecute un subproceso con un timerTask en onResume () que actualiza su barra de progreso con valores que se actualizan desde el fondo de ejecución de AsyncTask. Algo como esto:

 private void updateProgressBar(){ Runnable runnable = new updateProgress(); background = new Thread(runnable); background.start(); } public class updateProgress implements Runnable { public void run() { while(Thread.currentThread()==background) try { Thread.sleep(1000); Message msg = new Message(); progress = getProgressPercentage(); handler.sendMessage(msg); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } catch (Exception e) { } } } private Handler handler = new Handler(){ @Override public void handleMessage(Message msg) { progress.setProgress(msg.what); } }; 

Y cuando su actividad no es visible debe destruir el hilo:

 private void destroyRunningThreads() { if(background!=null) { background.interrupt(); background=null; } } 

2- Definir una variable booleana estática global. Establezca true en onPreExecute y en onPostExecute establezca en false. Se muestra que se está descargando o no, por lo que puede comprobar si la variable es igual a true, mostrar el cuadro de diálogo de la barra de progreso anterior (puede hacer algo como esto con un valor entero o matriz de enteros para mostrar la actualización Porcentaje para cada progreso de descarga).

3- La última forma en la que personalmente he usado es mostrar el progreso de la descarga en la barra de notificación y en mi vista de lista sólo muestro que se está descargando ahora o no (utilizando el 2do método con valores booleanos). De esta manera, incluso si finaliza la actividad, la barra de notificación se actualiza con el progreso de la descarga.

Cuando dejas tu actividad, la actividad que muestra asynctask muestra la barra de progreso es asesinada y por lo tanto la dosis de progressBar no se muestra más cuando vuelves a una nueva actividad porque la dosis de asíntate no es consciente de tu nueva actividad. Solución general que funcionará en cualquier caso, por ejemplo, cuando el usuario cierre la aplicación y vuelva a abrirla y quiere saber si ProgressBar separa completamente su presentación. Lo que significa que puede crear sharedPreferences o tabla de base de datos y poner su estado de su archivo en él mientras su asynctask está descargando. Por ejemplo, cada 500 milisegundos actualizar la tabla de base de datos sharedPreferences o con la cantidad descargada del tamaño total del archivo. Entonces cuando el usuario vuelve a su nueva actividad que lee desde DB o SharedPreferences para mostrar el progresoBar y actualizarlo cada ejemplo 1000 milisegundos. De esta forma, el usuario conocerá la barra de progreso incluso si cierra la aplicación y la vuelve a abrir. Sé que se necesita un poco más de trabajo, pero sin duda hace que sus usuarios sean felices.

Con el fin de leer y actualizar a tasa fija puede utilizar scheduleAtFixedRate

  • Android DownloadManager "Imposible abrir archivo"
  • Android: detecta si la aplicación se ha descargado del mercado
  • Android - Descargar e instalar el archivo apk en Webview
  • Descargar el archivo de url a cordova app error
  • Cómo establecer el tiempo de espera a cero en la acción HTTP Obtener de Tasker?
  • ¿por qué mi portadora móvil re-codifica un archivo cuando lo descargo?
  • Android SDK Bundle no se puede descargar dice "Unknown Network Error"
  • ¿Cómo puedo restringir mi aplicación de Android a no-Tablets?
  • Descarga de archivos zip en android
  • Android: ¿Cómo puedo obtener el tamaño de archivo de un archivo FTP a través de FTPClient?
  • Cómo descargar el archivo multimedia en formato m3u8 en Android
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.