SetExactAndAllowWhileIdle – no es exacta como referencia del desarrollador

AlarmManager en API19 tiene el método setExact () para establecer una alarma exacta.

Medios exactos -> Si configuro una alarma a las 2:01 pm se disparará a las 2:01 pm

En la API 23 – Marhsmwallow (6.0) hay un nuevo método setExactAndAllowWhileIdle () , pero a partir de la referencia no es EXACTO porque sólo se activará cada minuto y en modo inactivo de baja potencia sólo cada 15 minutos .

Exacta = cada 15 minutos 🙂

Entonces, ¿cómo puedo lograr una alarma exacta con AlarmManager en 6.0 ?

Si un usuario agrega un recordatorio o una cita del calendario y quiere ser informado 10 minutos antes del evento debe mostrar la alarma EXACTA 10 minutos antes del evento. Con setExactAndAllowWhileIdle () esto parece que no es posible.

Enlace de referencia: http://developer.android.com/reference/android/app/AlarmManager.html#setExactAndAllowWhileIdle(int, long, android.app.PendingIntent)

Entonces, ¿cómo puedo lograr una alarma exacta con AlarmManager en 6.0?

Puede probar setAlarmClock() , ya que AFAIK no es afectado por el modo Doze. De lo contrario, AlarmManager no es una opción viable para usted. Incluso tener su aplicación en la lista blanca de optimización de la batería no ayudará, ya que el comportamiento de AlarmManager no cambia en función de la lista blanca.

Le invitamos a usar GCM, ya que un mensaje de alta prioridad debería darle la oportunidad de alertar al usuario. Esto, por supuesto, requiere conectividad de red.

La única solución fuera de línea que conozco y que estoy probando actualmente es que el usuario agregue su aplicación a la lista blanca de optimización de la batería, luego utilice un servicio de primer plano (para tratar de mantener su proceso), un ScheduledExecutorService (for El tiempo), y un WakeLock parcial (para mantener la CPU encendida). Esto será bastante devastador para la batería del usuario.

El uso de setExactAndAllowWhileIdle () para una alarma de una sola vez se disparará exactamente en el tiempo dado, incluso en modo inactivo Doze. Así que este es probablemente el camino a seguir.

Se inician los problemas si desea repetir la alarma a una velocidad <15 min (o programar cualquier otra a la vez <15 min del último) , ya que esto no funcionará en el modo inactivo Doze, en el que dichas alarmas son forzadas A los siguientes 15 minutos o se ejecutan cuando comienza el mantenimiento en vacío, lo que sucede durante unos diez minutos primero después de 1 hora, luego después de otras 2 horas, luego después de otras 4 horas y así sucesivamente.

– EDITAR –

A fecha de hoy 17 de noviembre, Dianne Hackborn escribe en los comentarios de este Post : " Por lo que vale la pena, el tiempo mínimo entre las alarmas inactivas se cambiará a 9 minutos en algún momento relativamente pronto (incluso en los dispositivos que ejecutan las actuales compilaciones Marshmallow) . "

Sin embargo, esto no cambia nada fundamentalmente.

Aquí están mis discusiones con Ian Lake en Google+.

SetExactAndAllowWhileIdle () es exacto y debería funcionar. El intervalo de tiempo de 15 minutos es incorrecto en el java doc.

Introduzca aquí la descripción de la imagen

He encontrado que hasta ahora la mejor opción es utilizar un SyncAdapter que extiende AbstractThreadedSyncAdapter. Lo programo para que siga funcionando automáticamente mi código en el intervalo requerido:

 ContentResolver.setSyncAutomatically(account, AUTHORITY, true); ContentResolver.addPeriodicSync(account, AUTHORITY, settingsBundle, syncInterval); 

Estaba tratando de crear un sistema de automatización que funcionaba en segundo plano. Mi rango de frecuencia fue entre 1-15 minutos. Mi deseo era no usar un servicio de primer plano. Al mirar el nombre del método "setExactAndAllowWhileIdle", pensé que sí es seguro ir con alarmas de una sola vez, la programación de la siguiente cuando se hace.

Sin embargo, no pude encontrar una forma de ejecutar código en modo doze con alarmas ejecutándose más frecuentemente que 15 minutos. En su lugar, elijo iniciar un servicio de primer plano cuando el modo de espera se activa y detiene ese servicio de primer plano cuando se despierta el teléfono. El usuario no verá su notificación de primer plano mientras usa su teléfono. No me importa mucho acerca de los que están en modo doze.

 PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { if(intent.getAction().equals("android.os.action.DEVICE_IDLE_MODE_CHANGED")){ if (pm.isDeviceIdleMode()) { //startAutomationForegroundService(); } else { //stopAutomationForegroundService(); return; } AutomationReceiver.completeWakefulIntent(intent); return; } } 

Debe registrar el filtro de intenciones "android.os.action.DEVICE_IDLE_MODE_CHANGED" en su WakefulBroadcastReceiver. El cuidado de ponerlo en manifiesto puede no ayudar.

FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.