5

Mi aplicación inicia un AsyncTask que descarga un archivo de una URL. Al mismo tiempo, crea una barra de estado Notification que le dice al usuario el porcentaje completado de la descarga.Android: ¿Cómo accedo a AsyncTask desde un PendingIntent creado por una notificación de la barra de estado?

Estoy tratando de hacer que mi aplicación responda al hacer clic en la notificación. Si la descarga aún está en progreso, quiero mostrar un DialogInterface que les pregunte si desean detener la descarga. Hacer clic en sí debería detener la descarga.

El problema que tengo es que no estoy seguro de cómo acceder a mi tarea Async desde el PendingIntent que configuré para la notificación. Puedo obtener el DialogInterface para mostrarlo con bastante facilidad, pero no estoy seguro de cómo mostrar la actividad que se ejecuta donde la descarga es para detenerlo.

Intenté hacer una clase Helper que tuviera acceso a la notificación, así como el objeto File que hace referencia al archivo descargable, pero recibo un error que dice que el objeto no es serializable (implementa Serializable). La clase de ayuda también incluía un miembro que mantendría el progreso de la descarga, que es lo que usaría para la condición de mostrar el diálogo o no.

Estaba pensando en utilizar una Acción Brodcast y un receptor, pero no estoy seguro de dónde colocar el receptor. ¿Iría en la clase que extiende el AsyncTask?

Cualquier ayuda sería apreciada. Este es el PendingIntent conectado al Notification. Si desea ver más código, solo pregunte.

public class DownloadNotificationActivity extends Activity { 

/** Called when the activity is first created. */ 
@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 

    Intent i = getIntent(); 

    DialogInterface.OnClickListener dialogClickListener = new DialogInterface.OnClickListener() { 

     @Override 
     public void onClick(DialogInterface dialog, int which) { 
      switch (which) { 
       case DialogInterface.BUTTON_POSITIVE : 
        // Yes button clicked 
        // Stop download 
        finish(); 
        break; 

       case DialogInterface.BUTTON_NEGATIVE : 
        // No button clicked 
        finish(); 
        break; 
      } 
     } 
    }; 

    if (/* download not complete */) { 
     AlertDialog.Builder builder = new AlertDialog.Builder(this); 
     builder.setMessage(R.string.stop_download). 
       setPositiveButton(R.string.yes, dialogClickListener). 
       setNegativeButton(R.string.no, dialogClickListener).show(); 
    } 
    else { 
     // Access file 
    } 

} 
} 

Así que para ser claro, tengo una clase ViewDetailActivity. Tiene una clase interna llamada DownloadFile que se extiende AsyncTask y se ejecuta cuando el usuario hace clic en un botón en la pantalla. En el método doInBackground() de DownloadFile, se inicia una descarga de un mp3 desde una URL y se crea y actualiza una barra de estado Notification según la cantidad del archivo que se descarga. El PendingIntent del Notification se crea con el DownloadNotificationActivity (código mostrado) y debe mostrar un cuadro de diálogo que, de "Sí", debe cancelar la descarga en el AsyncTask.

Mi problema es que necesito para obtener la palabra de nuevo a la tarea DownloadFile que la descarga se ha cancelado y no estoy seguro de cómo acceder a la DownloadFile del DownloadNotificationActivity con el fin de cancelarla.

¡Gracias de antemano!

Respuesta

1

En su asynctask, necesita comprobar isCancelled() en el doInBackground() y abortar cuando se cancela. Desde su notificación, llame al cancel() en el asynctask.

Para hacer esto, debe pasar la referencia al AsyncTask a su actividad de notificación.

Por ejemplo:

crear el AsyncTask así:

class MyAsyncTask extends AsyncTask<Void, Integer, Void> { 
     @Override 
     protected Void doInBackground(Void... unused) { //be sure to check isCancelled here, i.e. if (isCancelled()) break; 

Luego, en su principal Activity crear el AsyncTask como:

public class MyActivity extends Activity { 
    private MyAsyncTask zeTask; 
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
       zeTask= new MyAsyncTask(); 
       zeTask.execute(); 

Entonces, cuando se crea la notificación y desea cancelar la tarea asíncrona, simplemente haga referencia a ella como zeTask. MyAsyncTask necesita estar en la misma actividad que la notificación y zeTask puede ser una variable que contiene la referencia a su AsyncTask.

switch (which) { 
       case DialogInterface.BUTTON_POSITIVE : 
        zeTask.cancel(); 
        finish(); 
        break; 
+0

Ese es el problema que estoy teniendo es pasar la referencia del 'AsyncTask' a la actividad anterior. Intenté implementar 'Serializable' en' AsyncTask' y uso 'putExtra()' en 'Intent' que configuré como' PendingIntent', pero obtuve una excepción que decía que el objeto no es serializable. ¿Hay alguna otra manera de pasar una referencia a AsyncTask a mi actividad? – Shino

+0

Ok, creo que la forma en que lo estoy haciendo simplemente no funcionará. La tarea de notificación que publiqué SOLO se usó como 'PendingIntent' cuando se hizo clic en la notificación de la barra de estado. El 'AsyncTask' estaba realmente en la clase que manejaba la pantalla donde puede hacer clic para descargar el archivo. Parece que necesito mover mi 'AsyncTask' a' DownloadNotificationActivity' y ejecutarla en 'onCreate' de esa clase. Luego maneje el evento 'onClick' para la notificación. Te dejaré saber qué pasa. – Shino

+0

Probar lo que dije en mi comentario anterior no funcionó. Gracias por su ayuda @Motes. He actualizado el tema con más información (en la parte inferior). Siento que estoy haciendo esto de la manera incorrecta. Necesito buscar otras opciones. Pensé en probar un "Broadcast" y un "BraodcastReceiver" pero no estoy seguro de qué tan bien funcionará poner un receptor en un 'AsyncTask'. – Shino

Cuestiones relacionadas