Implementar pausa / reanudar en la descarga de archivos

Estoy tratando de implementar pausa / reanudar en mi gestor de descargas, busco en la web y leer varios artículos y cambiar mi código de acuerdo a ellos, pero parece que no funciona correctamente, ¿alguna idea?

if (!downloadPath.exists()) downloadPath.mkdirs(); if (outputFileCache.exists()) { downloadedSize = outputFileCache.length(); connection.setAllowUserInteraction(true); connection.setRequestProperty("Range", "bytes=" + downloadedSize + "-"); connection.setConnectTimeout(14000); connection.connect(); input = new BufferedInputStream(connection.getInputStream()); output = new FileOutputStream(outputFileCache, true); input.skip(downloadedSize); //Skip downloaded size } else { connection.setConnectTimeout(14000); connection.connect(); input = new BufferedInputStream(url.openStream()); output = new FileOutputStream(outputFileCache); } fileLength = connection.getContentLength(); byte data[] = new byte[1024]; int count = 0; int __progress = 0; long total = downloadedSize; while ((count = input.read(data)) != -1 && !this.isInterrupted()) { total += count; output.write(data, 0, count); __progress = (int) (total * 100 / fileLength); } output.flush(); output.close(); input.close(); 

El problema de la autorización fijó, aquí está mi código para otros usuarios que desee implementar la pausa / curriculum vitae:

  if (outputFileCache.exists()) { connection.setAllowUserInteraction(true); connection.setRequestProperty("Range", "bytes=" + outputFileCache.length() + "-"); } connection.setConnectTimeout(14000); connection.setReadTimeout(20000); connection.connect(); if (connection.getResponseCode() / 100 != 2) throw new Exception("Invalid response code!"); else { String connectionField = connection.getHeaderField("content-range"); if (connectionField != null) { String[] connectionRanges = connectionField.substring("bytes=".length()).split("-"); downloadedSize = Long.valueOf(connectionRanges[0]); } if (connectionField == null && outputFileCache.exists()) outputFileCache.delete(); fileLength = connection.getContentLength() + downloadedSize; input = new BufferedInputStream(connection.getInputStream()); output = new RandomAccessFile(outputFileCache, "rw"); output.seek(downloadedSize); byte data[] = new byte[1024]; int count = 0; int __progress = 0; while ((count = input.read(data, 0, 1024)) != -1 && __progress != 100) { downloadedSize += count; output.write(data, 0, count); __progress = (int) ((downloadedSize * 100) / fileLength); } output.close(); input.close(); } 

Es imposible decir lo que está mal sin más información, sin embargo las cosas a tener en cuenta:

  1. Debe hacer una solicitud de HTTP / 1.1 (es difícil de saber de su código de ejemplo)
  2. El servidor debe soportar HTTP / 1.1
  3. El servidor le dirá lo que soporta con un encabezado Accept-Ranges en la respuesta
  4. If-Range debe ser el etag que el servidor le dio para el recurso, no la última vez modificada

Usted debe comprobar su solicitud de rango con algo simple para probar el origen en realidad apoya la solicitud de rango primero (como curl o wget)

Empezaría a depurar desde esta línea:

 connection.setRequestProperty("Range", "bytes=" + downloadedSize + "-"); 

A partir del código fuente no es posible determinar qué es el tamaño downloadedSize , es difícil elaborar más, pero el formato debe ser bytes=from-to .

De todos modos, le sugiero que utilice Apache HttpClient para evitar las trampas comunes. Aquí hay una pregunta de alguien que usa Apache HttpClient en un tema similar y se proporciona algún código de ejemplo.

Puede ser que su servidor está tardando en responder (más que el límite de tiempo de espera) o esto también es un hecho que no todos los servidores de apoyo pausa – reanudar. También es un punto para reflexionar sobre el tiempo que el archivo se descarga a través de HTTP, https, ftp o udp.

Pausar "sólo podría significar la lectura de algunos de la secuencia y la escritura en el disco.Cuando la reanudación que tendría que utilizar los encabezados para especificar lo que queda para descargar .

Usted puede intentar algo como:

  HttpURLConnection connection = (HttpURLConnection) url.openConnection(); if(ISSUE_DOWNLOAD_STATUS.intValue()==ECMConstant.ECM_DOWNLOADING){ File file=new File(DESTINATION_PATH); if(file.exists()){ downloaded = (int) file.length(); connection.setRequestProperty("Range", "bytes="+(file.length())+"-"); } }else{ connection.setRequestProperty("Range", "bytes=" + downloaded + "-"); } connection.setDoInput(true); connection.setDoOutput(true); progressBar.setMax(connection.getContentLength()); in = new BufferedInputStream(connection.getInputStream()); fos=(downloaded==0)? new FileOutputStream(DESTINATION_PATH): new FileOutputStream(DESTINATION_PATH,true); bout = new BufferedOutputStream(fos, 1024); byte[] data = new byte[1024]; int x = 0; while ((x = in.read(data, 0, 1024)) >= 0) { bout.write(data, 0, x); downloaded += x; progressBar.setProgress(downloaded); } 

Y trata de sincronizar las cosas.

Creo que sólo necesita eliminar la línea input.skip (downloadSize). Establecer el encabezado HTTP para el rango de bytes significa que el servidor omitirá el envío de esos bytes.

Supongamos que tiene un archivo de 20 bytes que consiste en "aaaaabbbbbcccccddddd", y suponga que la transferencia se detiene después de descargar 5 bytes. Entonces el encabezado Range hará que el servidor envíe "bbbbbcccccddddd", debería leer todo este contenido y anexarlo al archivo – no skip (). Pero la llamada skip () en su código saltará "bbbbb" dejando "cccccddddd" para ser descargado. Si ya has descargado al menos el 50% del archivo, entonces skip () agotará toda la entrada y no pasará nada.

Además, todas las cosas en el post stringy05 se aplican. Asegúrese de que el servidor admite HTTP / 1.1, asegúrese de que el encabezado Range esté soportado para el recurso (el contenido generado dinámicamente no lo admita) y asegúrese de que el recurso no se modifique mediante etag y fecha de modificación.

  • ¿Cómo puedo hacer que una celda en un ListView en Android se expanda y contraiga verticalmente cuando se toca?
  • Mejor biblioteca json rpc 2.0 para Android
  • Las extensiones de Android - SPAN_EXCLUSIVE_EXCLUSIVE no pueden tener una longitud cero
  • Encontrar máquinas en la red local basada en el puerto (descubrimiento de red) en android
  • ListView filtrar correctamente pero muestra un resultado incorrecto
  • No se pudo encontrar la clase 'android.support.v4.widget.SwipeRefreshLayout'
  • Kotlin-android: enlace de datos de referencia no resuelto
  • Android NumberPicker que oculta los botones de incremento y decremento
  • Error en el archivo xml de maven pom: Creando un proyecto Android
  • Android: startActivityForResult () con funcionalidad de botón BACK
  • Crash en Android 2.3.3 después de actualizar a la biblioteca de soporte 25.0.0 (java.lang.NoSuchMethodError: android.view.View.isAttachedToWindow)
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.