2012-09-24 41 views
5

Estoy escribiendo una aplicación de Android donde el usuario puede elegir varias acciones para ver y recibe una alerta si se cumple una condición de alerta predefinida. Los datos de stock se guardan en 5 objetos de una clase de alerta personalizada "Parcelable" (un objeto por stock y condición). La actualización periódica de datos se realiza a través de un servicio iniciado por un AlarmManager. Los objetos de alerta se pasan al servicio poniéndolos en el Intento que se coloca en el PendingIntent del AlarmManager.¿Cómo actualizar el envío de datos a un servicio con intención cuando el administrador de alarmas inicia el servicio?

Intent intent = new Intent(this, UpdateService.class); 
    Bundle b = new Bundle(); 
    saveAlertsToBundle(b);  
    intent.putExtras(b); 
    intent.setData(Uri.parse("updateManager")); 
    PendingIntent pendIntent = PendingIntent.getService(this,0,intent,0); 

    // 1min intervall 
    long intervall = DateUtils.MINUTE_IN_MILLIS * 1; 
    // time of first start 
    long firstStartDelay = DateUtils.SECOND_IN_MILLIS * 30; 
    long firstStart = System.currentTimeMillis() + firstStartDelay; 

    AlarmManager am = (AlarmManager) getSystemService(Context.ALARM_SERVICE); 
    // kill running 
    am.cancel(pendIntent); 
    //start new 
    am.setRepeating(AlarmManager.RTC_WAKEUP,firstStart,intervall,pendIntent); 

Mi problema es:

Al iniciar el servicio por primera vez cuando sólo hay un objeto de alerta se pasa al servicio de todo funciona bien. Tan pronto como haya más objetos de alerta existentes, también deberán pasarse al servicio, pero esto no funciona con el código anterior. El servicio no recibe la intención actualizada con los objetos de alerta adicionales, sino solo la inicial con solo un objeto de alerta. El código anterior crea correctamente una intención que contiene el objeto de alerta adicional, pero nunca llegan al servicio.

Así que mi pregunta es cómo pasar el intento actualizado al AlarmManager ya en ejecución.

Ya traté de detener el AlarmManager (la línea en el // matar el comentario en ejecución) y reiniciarlo, pero esto no funciona. ¿Quizás por la intención de no tener los mismos objetos de alerta como en el momento en que fue creado? Traté de solucionar esto estableciendo un uri en la parte de datos del intento, pero esto tampoco ayudó.

Gracias por la ayuda.

Respuesta

2

Su problema es la forma en que PendingIntent funciona. El sistema administra un grupo de PengingIntent s. Cuando su código hace:.

PendingIntent pendIntent = PendingIntent.getService(this,0,intent,0); 

Esto hace que el sistema busque un PendingIntent que corresponden con los parámetros que ha aprobado en (en este caso, su Intent Sin embargo, el algoritmo de coincidencia que utiliza PendingIntent sólo compara ciertos campos del Intent para determinar si es el que está buscando. En particular, no compara los extras. Esto significa que después de haber creado el primer PendingIntent, la llamada a PendingIntent.getService() siempre devolverá el mismo PendingIntent de el grupo (y no crear uno nuevo, que es lo que desea).

Con el fin de hacer la llamada a PendingIntent.getService() crear un nuevo PendingIntent cada vez que se llame, trate de hacer los parámetros se pasan a la llamada única, como este:

int requestCode = (int) System.currentTimeMillis(); // Create unique request code 
PendingIntent pendIntent = PendingIntent.getService(this, requestCode, intent, 0); 

Desde requestCode será diferente para cada llamada a PendingIntent.getService(), esto debería resolver su problema.

EDITAR Basándose en los comentarios de OP debajo

desea cancelar la alarma existente y crear una nueva con los nuevos datos. En ese caso, no necesita usar identificadores únicos porque solo desea tener un solo PendingIntent en el grupo. Pero, desea cambiar los datos para eso.Pruebe esto:

// Create a PendingIntent (or update the existing PendingIntent with new values 
PendingIntent pendIntent = PendingIntent.getService(this, 0, intent, 
         PendingIntent.FLAG_UPDATE_CURRENT); 

AlarmManager am = (AlarmManager) getSystemService(Context.ALARM_SERVICE); 
// cancel any pending alarms 
am.cancel(pendIntent); 
//start new 
am.setRepeating(AlarmManager.RTC_WAKEUP,firstStart,intervall,pendIntent); 
+0

Gracias por su ayuda, esto resolvió el problema pero creó uno nuevo. Los objetos de alerta adicionales se pasan al servicio, pero como servicios adicionales controlados por AlarmManager, los AlarmManagers ya en ejecución se siguen ejecutando. Por lo tanto, la cantidad de AlarmManagers aumenta cada vez que agrego un objeto de alerta. Esto significa que tengo uno corriendo por un objeto de alerta, uno por dos, uno por tres, etc. Creo que sería mejor si solo hay uno con la cantidad actual de alertas existentes, así que todavía tengo que detener el antiguo AlarmManager. Los servicios se detienen con una llamada a stopSelf(). – user1695117

+0

OK. No estaba seguro exactamente de lo que querías hacer. Según este comentario, parece que desea cancelar la alarma existente y crear una nueva con los nuevos parámetros. Voy a editar mi respuesta para eso. –

+0

Esto funcionó perfectamente. Así que todo lo que me faltaba era la bandera correcta, parece. Gracias por tu ayuda. – user1695117

Cuestiones relacionadas