Android: ¿Cómo accedo a una AsyncTask desde un PendingIntent creado por una notificación de la barra de estado?

Mi aplicación inicia un AsyncTask que descarga un archivo desde una URL. Al mismo tiempo crea una barra de estado Notification que le dice al usuario el porcentaje completo de la descarga.

Estoy tratando de hacer que mi aplicación responda al hacer clic en la notificación. Si la descarga aún está en curso, quiero mostrar un DialogInterface que les pregunta si quieren 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 conseguir el DialogInterface para mostrar lo suficientemente fácil, pero no estoy seguro de cómo mostrar la Actividad que se está apagando donde está la descarga para detenerla.

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

Estaba pensando en usar un Brodcast Action 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 adjunto a 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 un ViewDetailActivity clase. 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 doInBackground() método de DownloadFile, se inicia una descarga de un mp3 desde una URL y una barra de estado Notification se crea y actualiza en función de la cantidad del archivo que se descarga. los PendingIntent de los Notification se crea con el DownloadNotificationActivity (código que se muestra) y debe mostrar un diálogo que, de seleccionar "Sí", debe cancelar la descarga en el AsyncTask.

Mi problema es que necesito comunicarme con el DownloadFile tarea que la descarga ha sido cancelada y no estoy seguro de cómo acceder a la DownloadFile from the DownloadNotificationActivity para cancelarlo.

Gracias de antemano!

preguntado el 12 de junio de 12 a las 18:06

1 Respuestas

En su asynctask, tienes que comprobar isCancelled() en la doInBackground() y abortar cuando se cancela. Desde tu notificación, llamas cancel() al asynctask.

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

Por ejemplo:

Creas la 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 tu principal Activity tu creas el AsyncTask me gusta:

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

Luego, cuando cree la notificación y desee cancelar la tarea asíncrona, simplemente consúltela como zeTask. MyAsyncTask debe estar en la misma actividad que la notificación y zeTask puede ser una variable que contenga la referencia a su AsyncTask.

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

Respondido el 13 de junio de 12 a las 16:06

Ese es el problema que estoy teniendo es en realidad pasar la referencia de la AsyncTask a la actividad anterior. Traté de implementar Serializable al AsyncTask y use putExtra() al Intent me establecí como el PendingIntent, pero obtuve una excepción que dice que el objeto no es serializable. ¿Hay otra forma de pasar una referencia a AsyncTask a mi actividad? - Shino

Ok, creo que la forma en que lo estoy haciendo simplemente no funcionará. La tarea de notificación que publiqué era SOLO para usar como PendingIntent cuando se hizo clic en la notificación de la barra de estado. los AsyncTask en realidad estaba en la clase que manejó la pantalla donde puede hacer clic para descargar el archivo. Parece que necesito mover mi AsyncTask de las personas acusadas injustamente llamadas DownloadNotificationActivity y ejecutarlo en el onCreate de esa clase. Luego maneja el onClick evento para la notificación. Te dejaré saber lo que sucede. - Shino

Intentar lo que dije en mi comentario anterior no funcionó. Te agradezco tu 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 BraodcastReceiver pero no estoy seguro de qué tan bien poner un receptor en un AsyncTask trabajará. - Shino

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.