2012-04-30 22 views
7

Tengo un código simple que se supone que hace una tarea, cuando se hace clic en el botón, descarga un archivo, guárdalo en la tarjeta SD y ábrelo. Todo funciona, excepto durante la descarga, para archivos más grandes, la conexión se cae y la barra de progreso se cuelga, casi siempre al 20%. He buscado y buscado y no puedo imaginar qué hacer para mantener viva la conexión y permitir que se complete la descarga. ¿Alguna idea de cómo mantener viva la conexión para que la descarga se complete en lugar de estancarse en un 20%?Android - Detener descargas de archivos grandes - usando async/progressdialog

import java.io.BufferedInputStream; 
import java.io.File; 
import java.io.FileOutputStream; 
import java.io.InputStream; 
import java.io.OutputStream; 
import java.net.URL; 
import java.net.URLConnection; 
import java.util.List; 
import android.app.Activity; 
import android.app.ProgressDialog; 
import android.content.Intent; 
import android.content.pm.PackageManager; 
import android.net.Uri; 
import android.os.AsyncTask; 
import android.os.Bundle; 
import android.os.Environment; 
import android.util.Log; 
import android.view.View; 
import android.view.View.OnClickListener; 
import android.widget.Button; 

public class DownloadTestActivity extends Activity { 

    public static final int DIALOG_DOWNLOAD_PROGRESS = 0; 
    private Button startBtn; 
    private ProgressDialog mProgressDialog; 

    /** Called when the activity is first created. */ 
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
      super.onCreate(savedInstanceState); 
      setContentView(R.layout.main); 
      mProgressDialog = new ProgressDialog(DownloadTestActivity.this); 
      mProgressDialog.setMessage("Downloading..."); 
      mProgressDialog.setIndeterminate(false); 
      mProgressDialog.setMax(100); 
      mProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); 

      startBtn = (Button) findViewById(R.id.startBtn); 
      startBtn.setOnClickListener(new OnClickListener() { 
        public void onClick(View v) { 
          startDownload(); 
        } 
      }); 
    } 

    private void startDownload() { 
      DownloadFile downloadFile = new DownloadFile(); 
      downloadFile 
          .execute("http://www.website.com/file.pdf"); 

    } 

    class DownloadFile extends AsyncTask<String, Integer, String> { 

      @Override 
      protected void onPreExecute() { 
        super.onPreExecute(); 
        mProgressDialog.show(); 
      } 

      @Override 
      protected void onProgressUpdate(Integer... progress) { 
        super.onProgressUpdate(progress); 
        mProgressDialog.setProgress(progress[0]); 
      } 

      @Override 
      protected String doInBackground(String... aurl) { 
        try { 
          URL url = new URL(aurl[0]); 
          URLConnection connection = url.openConnection(); 
          connection.connect(); 

          int fileLength = connection.getContentLength(); 
          Log.d("ANDRO_ASYNC", "Lenght of file: " + fileLength); 

          InputStream input = new BufferedInputStream(url.openStream()); 
          String path = Environment.getExternalStorageDirectory() 
              + "/Android/Data/" 
              + getApplicationContext().getPackageName() + "/files"; 
          File file = new File(path); 
          file.mkdirs(); 
          File outputFile = new File(file, "test1.doc"); 
          OutputStream output = new FileOutputStream(outputFile); 

          byte data[] = new byte[8192]; 
          long total = 0; 
          int count; 
          while ((count = input.read(data)) != -1) { 
            total += count; 
            publishProgress((int) (total * 100/fileLength)); 
            output.write(data, 0, count); 
          } 

          output.flush(); 
          output.close(); 
          input.close(); 
          showPdf(); 

        } catch (Exception e) { 
        } 
        return null; 
      } 

      private void showPdf() { 
        // TODO Auto-generated method stub 
      if(mProgressDialog != null){ 
        mProgressDialog.dismiss(); 
      } 

        File file = new File(Environment.getExternalStorageDirectory() 
            + "/Android/Data/" 
            + getApplicationContext().getPackageName() 
            + "/files/test1.doc"); 
        PackageManager packageManager = getPackageManager(); 
        Intent testIntent = new Intent(Intent.ACTION_VIEW); 
        testIntent.setType("application/msword"); 
        List list = packageManager.queryIntentActivities(testIntent, 
            PackageManager.MATCH_DEFAULT_ONLY); 
        Intent intent = new Intent(); 
        intent.setAction(Intent.ACTION_VIEW); 
        Uri uri = Uri.fromFile(file); 
        intent.setDataAndType(uri, "application/msword"); 
        startActivity(intent); 
      } 


    } 
} 

Editar información Logcat:

--------- beginning of /dev/log/system 
W/InputManagerService( 199): Window already focused, ignoring focus gain of:  [email protected] 
--------- beginning of /dev/log/main 
D/AndroidRuntime(20673): 
D/AndroidRuntime(20673): >>>>>> AndroidRuntime START com.android.internal.os.RuntimeInit <<<<<< 
D/AndroidRuntime(20673): CheckJNI is OFF 
D/AndroidRuntime(20673): Calling main entry com.android.commands.pm.Pm 
D/AndroidRuntime(20673): Shutting down VM 
D/dalvikvm(20673): GC_CONCURRENT freed 101K, 82% free 467K/2560K, paused 1ms+0ms 
D/dalvikvm(20673): Debugger has detached; object registry had 1 entries 
I/AndroidRuntime(20673): NOTE: attach of thread 'Binder Thread #3' failed 
D/AndroidRuntime(20687): 
D/AndroidRuntime(20687): >>>>>> AndroidRuntime START com.android.internal.os.RuntimeInit <<<<<< 
D/AndroidRuntime(20687): CheckJNI is OFF 
D/AndroidRuntime(20687): Calling main entry com.android.commands.am.Am 
I/ActivityManager( 199): START {act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10000000 cmp=com.myapp/.Activity} from pid 20687 
D/AndroidRuntime(20687): Shutting down VM 
D/dalvikvm(20687): GC_CONCURRENT freed 102K, 81% free 489K/2560K, paused 0ms+0ms 
D/jdwp (20687): Got wake-up signal, bailing out of select 
D/dalvikvm(20687): Debugger has detached; object registry had 1 entries 
I/AndroidRuntime(20687): NOTE: attach of thread 'Binder Thread #3' failed 
D/dalvikvm(20698): Late-enabling CheckJNI 
I/ActivityManager( 199): Start proc com.myapp for activity  com.myapp/.Activity: pid=20698 uid=10102 gids={1015, 3003} 
I/dalvikvm(20698): Turning on JNI app bug workarounds for target SDK version 10... 
V/PhoneStatusBar( 271): setLightsOn(true) 
D/AudioHardware( 98): AudioHardware pcm playback is going to standby. 
D/AudioHardware( 98): closePcmOut_l() mPcmOpenCnt: 1 
I/ActivityManager( 199): Displayed com.myapp/.Activity: +197ms 
W/InputManagerService( 199): Starting input on non-focused client [email protected] (uid=10098 pid=20011) 
I/ActivityManager( 199): START {cmp=com.myapp/.Choice} from pid 20698 
D/AudioHardware( 98): AudioHardware pcm playback is exiting standby. 
D/AudioHardware( 98): openPcmOut_l() mPcmOpenCnt: 0 
V/PhoneStatusBar( 271): setLightsOn(true) 
I/ActivityManager( 199): Displayed com.myapp/.Choice: +93ms 
D/ANDRO_ASYNC(20698): Lenght of file: 736768 
D/dalvikvm(20698): GC_CONCURRENT freed 103K, 3% free 9403K/9607K, paused 2ms+3ms 
W/NetworkStats( 199): found non-monotonic values; saving to dropbox 
D/dalvikvm( 199): JIT code cache reset in 5 ms (1048440 bytes 13/0) 
D/dalvikvm( 199): GC_CONCURRENT freed 1472K, 13% free 24697K/28231K, paused 12ms+14ms 
D/AudioHardware( 98): AudioHardware pcm playback is going to standby. 
D/AudioHardware( 98): closePcmOut_l() mPcmOpenCnt: 1 
I/ActivityManager( 199): Force stopping package com.myapp uid=10102 
I/ActivityManager( 199): Killing proc 20698:com.myapp/10102: force stop 
W/ActivityManager( 199): Force removing ActivityRecord{41eb1ec0 com.myapp/.Choice}: app died, no saved state 
I/InputDispatcher( 199): Dropping event because there is no focused window or focused application. 
I/ActivityManager( 199): Force finishing activity ActivityRecord{418450c8 com.myapp/.Activity} 
I/InputDispatcher( 199): Dropping event because there is no focused window or focused application. 
W/InputDispatcher( 199): channel '417b41f0  com.myapp/com.myapp/.Activity (server)' ~  Consumer closed input channel or an error occurred. events=0x8 
E/InputDispatcher( 199): channel '417b41f0 com.myapp/com.myapp.Activity (server)' ~ Channel is unrecoverably broken and will be disposed! 
W/InputDispatcher( 199): Attempted to unregister already unregistered input channel '417b41f0 com.myapp/com.myapp.Activity (server)' 
W/WindowManager( 199): Failed looking up window 
W/WindowManager( 199): java.lang.IllegalArgumentException: Requested window [email protected] does not exist 
W/WindowManager( 199): at com.android.server.wm.WindowManagerService.windowForClientLocked(WindowManagerService.java:7176) 
W/WindowManager( 199): at com.android.server.wm.WindowManagerService.windowForClientLocked(WindowManagerService.java:7167) 
W/WindowManager( 199): at com.android.server.wm.WindowState$DeathRecipient.binderDied(WindowState.java:1545) 
W/WindowManager( 199): at android.os.BinderProxy.sendDeathNotice(Binder.java:417) 
W/WindowManager( 199): at dalvik.system.NativeStart.run(Native Method) 
I/WindowManager( 199): WIN DEATH: null 
I/WindowManager( 199): WIN DEATH: Window{4175b280  com.myapp/com.myapp.Choice paused=false} 
W/WindowManager( 199): Failed looking up window 
W/WindowManager( 199): java.lang.IllegalArgumentException: Requested window [email protected] does not exist 
W/WindowManager( 199): at com.android.server.wm.WindowManagerService.windowForClientLocked(WindowManagerService.java:7176) 
W/WindowManager( 199): at com.android.server.wm.WindowManagerService.windowForClientLocked(WindowManagerService.java:7167) 
W/WindowManager( 199): at com.android.server.wm.WindowState$DeathRecipient.binderDied(WindowState.java:1545) 
W/WindowManager( 199): at android.os.BinderProxy.sendDeathNotice(Binder.java:417) 
W/WindowManager( 199): at dalvik.system.NativeStart.run(Native Method) 
I/WindowManager( 199): WIN DEATH: null 
W/InputManagerService( 199): Got RemoteException sending setActive(false) notification to pid 20698 uid 10102 
D/dalvikvm(20011): GC_CONCURRENT freed 460K, 32% free 9468K/13767K, paused 3ms+4ms 
D/AudioHardware( 98): AudioHardware pcm playback is exiting standby. 
D/AudioHardware( 98): openPcmOut_l() mPcmOpenCnt: 0 
+0

¿Cómo se definen los archivos 'grandes'? ¿Qué tamaño? – Squonk

+0

¿Se apaga el teléfono durante la descarga? – debracey

+0

@MisterSquonk: no demasiado grande, aproximadamente 8 MB. El máximo que necesitaré para descargar sería de aproximadamente 35 MB. – user1363871

Respuesta

2

He intentado descargar su archivo varias veces, parece que se ha descargado por algunos segundos aquí y allá, y podría provocar un tiempo de espera en su aplicación. Intente especificar los tiempos de espera de forma explícita en el rango de 10-20 segundos.

private DefaultHttpClient httpclient = new DefaultHttpClient(); 
private HttpGet get = new HttpGet("your url comes here"); 

protected String[] doInBackground(Void... v) { 
    HttpParams httpParameters = new BasicHttpParams(); 
    // set the timeout in milliseconds until a connection is established 
    // the default value is zero, that means the timeout is not used 
    int timeoutConnection = 3000; 
    HttpConnectionParams.setConnectionTimeout(httpParameters, timeoutConnection); 
    // set the default socket timeout (SO_TIMEOUT) in milliseconds 
    // which is the timeout for waiting for data 
    int timeoutSocket = 5000; 
    HttpConnectionParams.setSoTimeout(httpParameters, timeoutSocket); 

    httpclient.setParams(httpParameters); 

    try { 
     HttpEntity entity = httpclient.execute(get).getEntity(); 
     FileOutputStream output = new FileOutputStream(outputFile); 
     entity.writeTo(output); 
     output.close(); 
     // return something, maybe? 
    } catch (ClientProtocolException e) { 
     e.printStackTrace(); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } finally { 
     httpclient.getConnectionManager().shutdown(); 
    } 
    return null; 
} 
+0

¿Debo cambiar el código de alguna otra manera que los tiempos de espera en su opinión? Soy bastante nuevo en esto y estoy tratando de aprender sobre la marcha, ¿sería demasiado pedir un ejemplo de los tiempos muertos? ¡Gracias! – user1363871

+0

he agregado un ejemplo, utiliza HttpClient en lugar de url.connection, y tiene que agregar la variable correcta 'outputFile' para su archivo de salida. – lenik

+0

Espero que esto ayude a alguien a experimentar el mismo problema, seleccionando como respuesta aceptada. Gracias. – user1363871

1

Lo que parece ser el problema es que el proceso 199 en su Logcat parece ser su actividad, pero luego se muestra:

I/ActivityManager( 199): Force stopping package com.viperean.atcassistant uid=10102 
I/ActivityManager( 199): Killing proc 20698:com.viperean.atcassistant/10102: force stop 
W/ActivityManager( 199): Force removing ActivityRecord{41eb1ec0 com.viperean.atcassistant/.atcChoice}: app died, no saved state 

(y la segunda línea muestra que está matando su asynctask ...).

No creo que haya nada de malo en el código de descarga. Creo que deberías buscar más en la actividad (qué estás haciendo durante ese tiempo junto a esa asynctask, qué estás mostrando en la pantalla ... etc ...).

Parece que también tiene poco espacio en el montón.

D/dalvikvm(20698): GC_CONCURRENT freed 103K, 3% free 9403K/9607K, paused 2ms+3ms 
D/dalvikvm( 199): JIT code cache reset in 5 ms (1048440 bytes 13/0) 
D/dalvikvm( 199): GC_CONCURRENT freed 1472K, 13% free 24697K/28231K, paused 12ms+14ms 

Esos son de la recolección de basura y sucede justo antes de su aplicación se estrelló, tal vez eso podría ser un problema también?

+0

Creo que puedo explicar que, después de un tiempo esperando la descarga del archivo y que no va a ningún lado, "presioné durante mucho tiempo para finalizar" la aplicación. Así que por eso es que lo matan y lo eliminan ... a partir del montón de espacio no sé qué decir. Reinicié mi teléfono y aún cuelga. – user1363871

+0

No sé si esto significa algo, pero probé varios archivos en línea para descargar. Tomando la longitud del archivo en logcat y dividiendo por el porcentaje de detención de la descarga, siempre obtengo un valor de entre 428799 - 471531 ... ¿Esto significa algo? Tal vez con mi buffer o algo así? – user1363871

1

cada hilo en Android está siendo eliminado por el sistema si no responde durante más de cinco minutos. tal vez debería considerar descargar como servicio o reemplazar el onProgress y obtener el hilo para mantenerse vivo

+0

¿Puede mostrarme o vincularme con un ejemplo para descargar como servicio? – user1363871

+0

me parece que hacer el onProgress será una mejor solución – thepoosh

Cuestiones relacionadas