Comportamiento incomprensible de Android AlarmManager

Sé que se habló de AlarmManager varias veces, pero realmente no puedo encontrar una respuesta que pueda ayudarme. Tengo una aplicación que necesita iniciar un servicio en un momento determinado y hacer algunas cosas, así que después de un poco de trabajo de investigación, decidí que AlarmManager es lo que necesito.

Yo uso este código para hacer el trabajo

    Intent myIntent=new Intent();
    ComponentName cn=new ComponentName("my.package.name", "my.package.name.AlarmService");
    myIntent.setComponent(cn);
    PendingIntent pendingIntent= PendingIntent.getService(alarm._context, alarm.id, myIntent, 0);
    AlarmManager alarmManager = (AlarmManager) _context.getSystemService(Context.ALARM_SERVICE);
    alarmManager.set(AlarmManager.RTC_WAKEUP, alarm.time, pendingIntent);

Donde "alarma" es un objeto escrito por mí. Ahora, estoy completamente seguro de que este código funciona, porque si configuro una (o más) acción durante 2 minutos u horas, funciona (escribo un archivo de inicio de sesión en la primera instrucción del servicio). si ejecuto

    adb shell dumpsys alarm

Puedo ver todos mis intentos pendientes. Ok, feliz de ver que todo funciona, programo mis acciones en:

01:00 AM 08:00 AM 08:40 AM 09:15:AM 01:00 PM 02:00 PM 18:00 PM

después de configurar estas acciones, ejecuto

   adb shell dumpsys alarm

y puedo ver todos los intentos pendientes. Luego me voy a dormir y... cuando me despierto por la mañana a las 07:30 a. m., la acción programada a la 01:00 a. m. no se ha ejecutado y si ejecuto

    adb shell dumpsys alarm

¡Todos mis intentos pendientes han desaparecido!

Estoy realmente frustrado por este comportamiento, porque pasé mucho tiempo escribiendo esta aplicación y no puedo hacer que funcione correctamente. Estoy publicando esta pregunta después de semanas de investigación, porque probé todo, pero todavía tengo este problema. por favor, ayúdame

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

¿En qué dispositivo/ROM estás? ¿Has probado a ejecutar la aplicación en otro dispositivo? Tengo exactamente el mismo problema en un dispositivo (Cyanogenmod 10.1.3, es decir, Android 4.2.2). Sin embargo, parece que el problema no ocurre en otro dispositivo (HTC Stock, Android 4.1). ¿Has encontrado una solución? -

1 Respuestas

De los documentos para AlarmManager (enlace aquí):

El administrador de alarmas mantiene un bloqueo de activación de la CPU siempre que se esté ejecutando el método onReceive() del receptor de alarmas. Esto garantiza que el teléfono no se dormirá hasta que haya terminado de manejar la transmisión. Una vez que onReceive() regresa, el Administrador de alarmas libera este bloqueo de activación. Esto significa que, en algunos casos, el teléfono se suspenderá tan pronto como se complete el método onReceive(). Si su receptor de alarma llama a Context.startService(), es posible que el teléfono entre en reposo antes de que se inicie el servicio solicitado. Para evitar esto, su BroadcastReceiver y Service deberán implementar una política de bloqueo de activación por separado para garantizar que el teléfono continúe funcionando hasta que el servicio esté disponible.

Si Service no mantiene configurados los bloqueos de activación adecuados, el dispositivo volverá a dormir cuando el AlarmManager está terminado, debe administrar esto también en su código.

HTH

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

Hola Devunwired, antes que nada muchas gracias por contestar. ¿Puede proporcionarme un enlace a un buen ejemplo para hacer esto? No soy un desarrollador de Android tan experto, y hay muchas cosas sobre esto que me confunden... gracias de antemano por su ayuda. lado superior

Comenzaría con los documentos de PowerManager, ya que así es como el código de su aplicación necesitará obtener un WakeLock mientras se ejecuta durante la "reposo": desarrollador.android.com/reference/android/os/PowerManager.html - desconectado

gracias de nuevo, pero tan pronto como entré en la página vi escrito en negrita: La duración de la batería del dispositivo se verá significativamente afectada por el uso de esta API ¿Significa que mi aplicación agotará la batería de los usuarios? ¿Es esta la única forma en que puedo hacer eso? ¿No hay una mejor manera de ejecutar algún código (que no necesita interacion del usuario) en un momento específico sin agotar la batería? - lado superior

Esa declaración es bastante ilógica; no puede despertar un dispositivo del modo de suspensión para hacer algún trabajo y esperar que la batería no se use para hacerlo. La razón por la que esas declaraciones están ahí es para mantenerlo consciente de que debe usar esas API con prudencia y no mantener el dispositivo despierto más tiempo del necesario para hacer su trabajo. Sostener un WakeLock indefinidamente mataría una batería como dejar el GPS encendido todo el tiempo. - desconectado

Ok, tienes razón, fue una declaración estúpida, pero en este punto hay algo que no entiendo: si configuro mi intención pendiente en 2 minutos adelante y pongo el teléfono a dormir (con el botón de encendido/apagado), y vuelvo a encender el teléfono después de que la acción debería haberse ejecutado, veo que la acción se ejecuta. Pero cuando configuro las acciones como se explica en la pregunta principal, a la mañana siguiente todos mis intentos pendientes ya no existen. Qué me estoy perdiendo ? - lado superior

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