AlarmManager
clase) te brindan una forma de realizar
en tiempo real fuera del ciclo de vida de tu aplicación.
Por ejemplo, podrías usar una alarma para iniciar una operación prolongada, como
como iniciar un servicio una vez al día para descargar el pronóstico del tiempo.
Las alarmas tienen las siguientes características:
Te permiten activar intents en horas o intervalos determinados.
Puedes usarlos junto con receptores de emisión para programar trabajos o WorkRequests para realizar otras las operaciones.
Funcionan fuera de tu aplicación, por lo que puedes usarlas para activar eventos o acciones incluso cuando la app no se está ejecutando y si el dispositivo en sí está dormida.
Ayudan a minimizar los requisitos de recursos de tu app. Puedes programar sin depender de temporizadores ni servicios en ejecución continua.
Cómo establecer una alarma inexacta
Cuando una app establece una alarma inexacta, el sistema la emite en algún momento en el futuro. Las alarmas inexactas brindan algunas garantías sobre la sincronización la entrega de la alarma y, al mismo tiempo, se respetan las restricciones de ahorro de batería, Descanso
Los desarrolladores pueden aprovechar las siguientes garantías de APIs para personalizar los tiempos de entrega de alarmas inexactas.
Cómo activar una alarma después de una hora específica
Si la app llama a set()
,
setInexactRepeating()
,
o setAndAllowWhileIdle()
,
de que la alarma nunca suene antes de la hora de activación proporcionada.
En Android 12 (nivel de API 31) y versiones posteriores, el sistema invoca la alarma dentro de uno hora del tiempo de activación proporcionado, a menos que se apliquen restricciones en efecto, como el ahorro de batería o Descanso.
Mostrar una alarma durante un período determinado
Si la app llama a setWindow()
, la alarma nunca sonará antes del horario indicado.
tiempo de activación. A menos que se apliquen restricciones de ahorro de batería, la alarma se
entregados dentro del período especificado, a partir del activador determinado
tiempo.
Si tu app se orienta a Android 12 o versiones posteriores, el sistema puede retrasar
la invocación de una alarma inexacta con ventana de tiempo durante al menos 10 minutos. Para
Por este motivo, los valores del parámetro windowLengthMillis
en 600000
se ajustan a
600000
Publicar una alarma que se repite en intervalos aproximadamente regulares
Si la app llama a setInexactRepeating()
,
el sistema invoca varias alarmas:
- La primera alarma suena dentro del período especificado, a partir de la tiempo de activación determinado.
- Por lo general, las alarmas posteriores se activan después del período especificado. el tiempo transcurrido. El tiempo entre dos invocaciones consecutivas de la alarma puede variar.
Cómo establecer una alarma exacta
El sistema invoca una alarma exacta en un momento preciso del futuro.
La mayoría de las apps pueden programar tareas y eventos con alarmas inexactas para hacer lo siguiente: completan varios casos de uso comunes. Si el componente central de tu app depende de una alarma con una hora precisa, por ejemplo, para una aplicación de alarma o una app de calendario, está bien usar una alarma exacta.
Casos de uso que podrían no exigir alarmas exactas
En la siguiente lista, se muestran los flujos de trabajo comunes que pueden no requerir una alarma exacta:
- Programa operaciones de tiempo durante el ciclo de vida de la app
- La clase
Handler
incluye varias prácticas recomendadas para manejar las operaciones de sincronización, como hacer un trabajo cada n segundos, mientras la app está activa:postAtTime()
ypostDelayed()
. Ten en cuenta que estas APIs dependen del tiempo de actividad del sistema y no en tiempo real. - Tarea en segundo plano programada, por ejemplo, actualizar la app y subir registros
WorkManager
proporciona una forma de programar sesiones periódicas urgentes. del trabajo. Puedes proporcionar un intervalo de repetición yflexInterval
(15 minutos como mínimo) para definir el entorno de ejecución detallado para el trabajo.- Acción especificada por el usuario que debe ocurrir después de un tiempo específico (incluso si el sistema está inactivo)
- Usa una alarma inexacta. Específicamente, llama
setAndAllowWhileIdle()
- Acción especificada por el usuario que debe ocurrir después de un tiempo específico
- Usa una alarma inexacta. Específicamente, llama
set()
- Acción especificada por el usuario que puede ocurrir dentro de un período específico
- Usa una alarma inexacta. Específicamente, llama
setWindow()
Ten en cuenta que, si tu app está orientada a Android 12 o versiones posteriores, la versión más pequeña la duración permitida del período es de 10 minutos.
Formas de establecer una alarma exacta
Tu app puede establecer alarmas exactas con uno de los siguientes métodos. Estos métodos se ordenan de manera que las que están más cerca de la parte inferior de la lista publiquen más tareas urgentes, pero demandan más recursos del sistema.
setExact()
Invocar una alarma casi en un momento preciso en el futuro, siempre que otros las medidas de ahorro de batería no están vigentes.
Usa este método para establecer alarmas exactas, a menos que el trabajo de tu app urgentes para el usuario.
setExactAndAllowWhileIdle()
Invocar una alarma en un momento casi preciso en el futuro, incluso si ahorras batería medidas de seguridad estén vigentes.
setAlarmClock()
Invoca una alarma en un momento preciso en el futuro. Como las alarmas son altamente visible para los usuarios, el sistema nunca ajusta su tiempo de entrega. El el sistema identifica estas alarmas como las más críticas y deja las modos si es necesario para entregar las alarmas.
Consumo de recursos del sistema
Cuando el sistema activa alarmas exactas que establece tu app, el dispositivo consume una gran cantidad de recursos, como la duración de la batería, especialmente si está en un modo de ahorro de energía. Además, el sistema no puede agrupar en lotes estas solicitudes con facilidad para usar los recursos de forma más eficiente.
Te recomendamos crear una alarma inexacta siempre que
como sea posible. Para realizar un trabajo más largo, prográmalo usando
WorkManager
o
JobScheduler
de la alarma
BroadcastReceiver
Para realizar un trabajo mientras
que el dispositivo esté en Descanso, crea una alarma inexacta usando
setAndAllowWhileIdle()
:
y comenzar un trabajo con la alarma.
Declara el permiso adecuado de alarmas exactas
Si la app se orienta a Android 12 o versiones posteriores, debes obtener la
"Alarmas y recordatorios" acceso especial de apps. Para hacerlo, declara el
SCHEDULE_EXACT_ALARM
permiso en el archivo de manifiesto de tu app, como se muestra en el siguiente fragmento de código:
<manifest ...> <uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM"/> <application ...> ... </application> </manifest>
Si tu app se orienta a Android 13 (nivel de API 33) o versiones posteriores, puedes hacer lo siguiente:
declarar SCHEDULE_EXACT_ALARM
o USE_EXACT_ALARM
permiso.
<manifest ...> <uses-permission android:name="android.permission.USE_EXACT_ALARM"/> <application ...> ... </application> </manifest>
Si bien los permisos SCHEDULE_EXACT_ALARM
y USE_EXACT_ALARM
señalan las mismas capacidades, se les otorgan diferentes y admiten distintas
para cada caso de uso. Tu app debe usar alarmas exactas y declarar cualquiera de ellas
los permisos SCHEDULE_EXACT_ALARM
o USE_EXACT_ALARM
, solo si un permiso
en tu app requiere acciones con tiempos precisos.
USE_EXACT_ALARM
- Otorgado automáticamente
- El usuario no puede revocarlo
- Sujeto a una política de Google Play futura
- Casos de uso limitados
SCHEDULE_EXACT_ALARM
- Otorgado por el usuario
- Conjunto más amplio de casos de uso
- Las apps deben confirmar que no se revocó el permiso
El permiso SCHEDULE_EXACT_ALARM
no se otorga de forma previa a instalaciones nuevas de
apps orientadas a Android 13 (nivel de API 33) y versiones posteriores. Si un usuario transfiere la app
datos a un dispositivo con Android 14 mediante una operación de copia de seguridad y restablecimiento, el
Se rechazará el permiso SCHEDULE_EXACT_ALARM
en el dispositivo nuevo. Sin embargo, si
una app existente ya tiene este permiso, se otorgará de forma previa cuando la
se actualiza a Android 14.
Nota: Si la alarma exacta se configura con un
OnAlarmListener
objeto, como con el
setExact
API, el permiso SCHEDULE_EXACT_ALARM
no es necesario.
Cómo usar el permiso SCHEDULE_EXACT_ALARM
A diferencia de USE_EXACT_ALARM
, el permiso SCHEDULE_EXACT_ALARM
debe
otorgada por el usuario. Tanto el usuario como el sistema pueden revocar el
SCHEDULE_EXACT_ALARM
.
Para verificar si se otorgó el permiso a tu app, llama a
canScheduleExactAlarms()
antes de intentar establecer una alarma exacta. Cuando se habilita el permiso SCHEDULE_EXACT_ALARM
se revoca para tu app, esta se detiene y todas las alarmas exactas futuras
se cancelan. Esto también significa que el valor devuelto por
canScheduleExactAlarms()
sigue siendo válido durante todo el ciclo de vida de tu app.
Cuando se otorga el permiso SCHEDULE_EXACT_ALARMS
a tu app, el
el sistema le envía el
ACTION_SCHEDULE_EXACT_ALARM_PERMISSION_STATE_CHANGED
transmisión. Tu app debe implementar una transmisión
receptor que hace lo
lo siguiente:
- Confirma que tu app todavía tiene el acceso especial de apps. Para ello, llama a
canScheduleExactAlarms()
. Esta verificación protege a tu app contra el caso en el que el usuario le otorga la permiso y lo revoca casi inmediatamente después. - Reprograma las alarmas exactas que necesita la app, en función de su estado actual.
Esta lógica debería ser similar a lo que hace la app cuando recibe la emisión
ACTION_BOOT_COMPLETED
.
Solicita a los usuarios que otorguen el permiso SCHEDULE_EXACT_ALARM
Si es necesario, puedes dirigir a los usuarios a la sección Alarmas y de recordatorios en el sistema de seguridad, como se muestra en la Figura 1. Para ello, completa los siguientes pasos:
- En la IU de la app, explícale al usuario por qué la app debe programar alarmas exactas.
- Invoca un intent que incluya la acción de intent
ACTION_REQUEST_SCHEDULE_EXACT_ALARM
.
Cómo establecer una alarma repetitiva
Las alarmas repetidas permiten que el sistema notifique a tu app de forma recurrente de un proyecto.
Una alarma mal diseñada puede agotar la batería y generar una carga significativa servidores. Por este motivo, en Android 4.4 (nivel de API 19) y versiones posteriores, todas Las alarmas repetitivas son alarmas inexactas.
Una alarma repetitiva tiene las siguientes características:
Un tipo de alarma. (Para obtener más información, consulta Cómo elegir un tipo de alarma)
Una hora de activación Si el tiempo de activación que especificas es en el pasado, la alarma se activa de inmediato.
El intervalo de la alarma Por ejemplo, una vez al día, cada hora o cada 5 minutos.
Un intent pendiente que se activa cuando se activa la alarma Cuando estableces un que usa el mismo intent pendiente, reemplaza a la alarma original.
Para cancelar un PendingIntent()
, pasa
FLAG_NO_CREATE
para PendingIntent.getService()
para obtener una instancia del intent (si existe) y, luego, pásalo a
AlarmManager.cancel()
Kotlin
val alarmManager = context.getSystemService(Context.ALARM_SERVICE) as? AlarmManager val pendingIntent = PendingIntent.getService(context, requestId, intent, PendingIntent.FLAG_NO_CREATE) if (pendingIntent != null && alarmManager != null) { alarmManager.cancel(pendingIntent) }
Java
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); PendingIntent pendingIntent = PendingIntent.getService(context, requestId, intent, PendingIntent.FLAG_NO_CREATE); if (pendingIntent != null && alarmManager != null) { alarmManager.cancel(pendingIntent); }
Cómo elegir un tipo de alarma
Una de las primeras consideraciones sobre el uso de una alarma repetitiva es cuál es su tipo debe ser.
Hay dos tipos de reloj generales para las alarmas: "tiempo real transcurrido" y “reloj en tiempo real” RTC. El tiempo real transcurrido usa el “tiempo desde que se inició el sistema” como y el reloj en tiempo real usa UTC (reloj de pared). Esto significa que tiempo real transcurrido es adecuado para establecer una alarma basada en el paso del tiempo (por ejemplo, una alarma que se activa cada 30 segundos), ya que no se ve afectada por a la zona horaria o a la configuración regional. El tipo de reloj en tiempo real es más adecuado para las alarmas que dependen de la configuración regional actual.
Ambos tipos tienen una "activación" versión, que indica que se active la CPU del dispositivo si la pantalla está apagada. Esto garantiza que la alarma se active a la hora programada. Esto es útil si tu app tiene una dependencia de tiempo. Por ejemplo, si incluye una ventana limitada para realizar una operación en particular. Si no usas activar una versión de tu tipo de alarma, todas las alarmas repetitivas se activarán la próxima vez que actives el dispositivo.
Si solo necesitas que la alarma se active en un intervalo determinado (por ejemplo, cada media hora), usa uno de los tipos de tiempo real transcurrido. En general, este es la mejor opción.
Si necesitas que la alarma se active a una hora determinada del día, elige una de los tipos de reloj en tiempo real. Sin embargo, ten en cuenta que este enfoque puede tienen algunas desventajas. Es posible que la app no se traduzca bien a otras configuraciones regionales y si el usuario cambia la configuración de hora del dispositivo, se pueden producir comportamientos inesperados en tu app. El uso de un tipo de alarma de reloj en tiempo real tampoco escala bien, ya que que mencionamos anteriormente. Te recomendamos que uses una ventana de “tiempo real transcurrido” alarma si puedes.
A continuación, se muestra una lista de los tipos:
ELAPSED_REALTIME
: Activa el intent pendiente según la cantidad de tiempo que transcurrió desde que se inició el dispositivo se inició, pero no activa el dispositivo. El El tiempo transcurrido incluye cualquier tiempo en el que el dispositivo estuvo inactivo.ELAPSED_REALTIME_WAKEUP
: Activa el dispositivo y activa el intent pendiente después de la duración especificada. transcurrió un tiempo desde el inicio del dispositivo.RTC
: Activa el intent pendiente a la hora especificada, pero no activa el dispositivo.RTC_WAKEUP
: Activaciones activar el dispositivo para activar el intent pendiente en el momento especificado
Ejemplos de alarmas de tiempo real transcurrido
Estos son algunos ejemplos del uso de ELAPSED_REALTIME_WAKEUP
Activa el dispositivo para activar la alarma en 30 minutos, cada 30 minutos después de eso:
Kotlin
// Hopefully your alarm will have a lower frequency than this! alarmMgr?.setInexactRepeating( AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() + AlarmManager.INTERVAL_HALF_HOUR, AlarmManager.INTERVAL_HALF_HOUR, alarmIntent )
Java
// Hopefully your alarm will have a lower frequency than this! alarmMgr.setInexactRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() + AlarmManager.INTERVAL_HALF_HOUR, AlarmManager.INTERVAL_HALF_HOUR, alarmIntent);
Activa el dispositivo para activar una única alarma (no repetitiva) en un minuto:
Kotlin
private var alarmMgr: AlarmManager? = null private lateinit var alarmIntent: PendingIntent ... alarmMgr = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager alarmIntent = Intent(context, AlarmReceiver::class.java).let { intent -> PendingIntent.getBroadcast(context, 0, intent, 0) } alarmMgr?.set( AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() + 60 * 1000, alarmIntent )
Java
private AlarmManager alarmMgr; private PendingIntent alarmIntent; ... alarmMgr = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE); Intent intent = new Intent(context, AlarmReceiver.class); alarmIntent = PendingIntent.getBroadcast(context, 0, intent, 0); alarmMgr.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() + 60 * 1000, alarmIntent);
Ejemplos de alarmas de reloj en tiempo real
Estos son algunos ejemplos de cómo usar
RTC_WAKEUP
Activar el dispositivo para activar la alarma aproximadamente a las 2:00 p.m. repetirse una vez al día a la misma hora:
Kotlin
// Set the alarm to start at approximately 2:00 p.m. val calendar: Calendar = Calendar.getInstance().apply { timeInMillis = System.currentTimeMillis() set(Calendar.HOUR_OF_DAY, 14) } // With setInexactRepeating(), you have to use one of the AlarmManager interval // constants--in this case, AlarmManager.INTERVAL_DAY. alarmMgr?.setInexactRepeating( AlarmManager.RTC_WAKEUP, calendar.timeInMillis, AlarmManager.INTERVAL_DAY, alarmIntent )
Java
// Set the alarm to start at approximately 2:00 p.m. Calendar calendar = Calendar.getInstance(); calendar.setTimeInMillis(System.currentTimeMillis()); calendar.set(Calendar.HOUR_OF_DAY, 14); // With setInexactRepeating(), you have to use one of the AlarmManager interval // constants--in this case, AlarmManager.INTERVAL_DAY. alarmMgr.setInexactRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY, alarmIntent);
Activa el dispositivo para activar la alarma precisamente a las 8:30 a.m. y cada 20 minutos Luego de esa fecha, ocurrirá lo siguiente:
Kotlin
private var alarmMgr: AlarmManager? = null private lateinit var alarmIntent: PendingIntent ... alarmMgr = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager alarmIntent = Intent(context, AlarmReceiver::class.java).let { intent -> PendingIntent.getBroadcast(context, 0, intent, 0) } // Set the alarm to start at 8:30 a.m. val calendar: Calendar = Calendar.getInstance().apply { timeInMillis = System.currentTimeMillis() set(Calendar.HOUR_OF_DAY, 8) set(Calendar.MINUTE, 30) } // setRepeating() lets you specify a precise custom interval--in this case, // 20 minutes. alarmMgr?.setRepeating( AlarmManager.RTC_WAKEUP, calendar.timeInMillis, 1000 * 60 * 20, alarmIntent )
Java
private AlarmManager alarmMgr; private PendingIntent alarmIntent; ... alarmMgr = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE); Intent intent = new Intent(context, AlarmReceiver.class); alarmIntent = PendingIntent.getBroadcast(context, 0, intent, 0); // Set the alarm to start at 8:30 a.m. Calendar calendar = Calendar.getInstance(); calendar.setTimeInMillis(System.currentTimeMillis()); calendar.set(Calendar.HOUR_OF_DAY, 8); calendar.set(Calendar.MINUTE, 30); // setRepeating() lets you specify a precise custom interval--in this case, // 20 minutes. alarmMgr.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), 1000 * 60 * 20, alarmIntent);
Cómo decidir qué tan precisa debe ser la alarma
Como se describió anteriormente, elegir el tipo de alarma suele ser el primer paso
creando una alarma. Otra distinción es la precisión con la que necesitas la alarma
ser. Para la mayoría de las apps,
setInexactRepeating()
es la elección correcta. Cuando usas este método, Android sincroniza varias alarmas y activaciones inexactas
al mismo tiempo. De esta manera, se reduce el consumo de batería.
Si es posible, evita usar alarmas exactas. Sin embargo, para una app poco común que tiene fallas
requisitos de tiempo, puedes establecer una alarma exacta llamando
setRepeating()
Con setInexactRepeating()
,
no puede especificar un intervalo personalizado como lo hace con
setRepeating()
Debes usar una de las constantes de intervalo, como
INTERVAL_FIFTEEN_MINUTES
:
INTERVAL_DAY
,
etcétera. Consulta AlarmManager
para ver la lista completa.
Cancela una alarma
Según tu app, es posible que quieras incluir la capacidad para cancelar la alarma.
Para cancelar una alarma, llama a cancel()
.
en el Administrador de alarmas, pasando el
PendingIntent
ya no quieres
se dispare. Por ejemplo:
Kotlin
// If the alarm has been set, cancel it. alarmMgr?.cancel(alarmIntent)
Java
// If the alarm has been set, cancel it. if (alarmMgr!= null) { alarmMgr.cancel(alarmIntent); }
Cómo iniciar una alarma cuando se reinicia el dispositivo
De manera predeterminada, todas las alarmas se cancelan cuando se apaga un dispositivo.
Para evitar que esto suceda, puedes diseñar tu aplicación
para reiniciar automáticamente una alarma recurrente si el usuario reinicia el dispositivo Esta
garantiza que el elemento AlarmManager
continuar realizando la tarea sin que el usuario deba reiniciar manualmente la alarma.
A continuación, se indican los pasos que debes seguir:
Establece el elemento
RECEIVE_BOOT_COMPLETED
. permiso en el manifiesto de tu aplicación. Esto permite que tu app reciba elACTION_BOOT_COMPLETED
que se transmite después de que el sistema termina de iniciarse (esto solo funciona si el el usuario ya la inició al menos una vez):<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
Implementa un
BroadcastReceiver
para recibir la transmisión:Kotlin
class SampleBootReceiver : BroadcastReceiver() { override fun onReceive(context: Context, intent: Intent) { if (intent.action == "android.intent.action.BOOT_COMPLETED") { // Set the alarm here. } } }
Java
public class SampleBootReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { if (intent.getAction().equals("android.intent.action.BOOT_COMPLETED")) { // Set the alarm here. } } }
Agrega el receptor al archivo de manifiesto de tu app con un filtro de intents que filtros en
ACTION_BOOT_COMPLETED
acción:<receiver android:name=".SampleBootReceiver" android:enabled="false"> <intent-filter> <action android:name="android.intent.action.BOOT_COMPLETED"></action> </intent-filter> </receiver>
Ten en cuenta que, en el manifiesto, el receptor de inicio está configurado para
android:enabled="false"
Esto significa que el receptor a menos que la aplicación lo habilite explícitamente. Esto evita que las al receptor de inicio se llame innecesariamente. Puedes habilitar un receptor (por ejemplo, si el usuario establece una alarma) de la siguiente manera:Kotlin
val receiver = ComponentName(context, SampleBootReceiver::class.java) context.packageManager.setComponentEnabledSetting( receiver, PackageManager.COMPONENT_ENABLED_STATE_ENABLED, PackageManager.DONT_KILL_APP )
Java
ComponentName receiver = new ComponentName(context, SampleBootReceiver.class); PackageManager pm = context.getPackageManager(); pm.setComponentEnabledSetting(receiver, PackageManager.COMPONENT_ENABLED_STATE_ENABLED, PackageManager.DONT_KILL_APP);
Una vez que habilites el receptor de esta manera, permanecerá habilitado, incluso si el usuario reinicia el dispositivo. En otras palabras, habilitar de manera programática el receptor anula la configuración del manifiesto, incluso luego de un reinicio. El receptor permanecerá habilitado hasta que tu app la inhabilite. Puedes inhabilitar un receptor (por ejemplo, si el usuario cancela una alarma) de la siguiente manera:
Kotlin
val receiver = ComponentName(context, SampleBootReceiver::class.java) context.packageManager.setComponentEnabledSetting( receiver, PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP )
Java
ComponentName receiver = new ComponentName(context, SampleBootReceiver.class); PackageManager pm = context.getPackageManager(); pm.setComponentEnabledSetting(receiver, PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP);
Invocar alarmas mientras el dispositivo esté en modo Descanso
Dispositivos compatibles con Android 6.0 (nivel de API 23) Descanso general, que ayuda a extender la duración de batería del dispositivo. Las alarmas no se activan cuando el dispositivo está en Modo Descanso Las alarmas programadas se aplazan hasta que el dispositivo sale del modo Descanso. Si necesitas completar el trabajo incluso cuando el dispositivo esté inactivo, hay varias opciones disponibles:
Establece una alarma exacta.
Usa la API de WorkManager, que se creó para realizar el trabajo en segundo plano. Puedes indicar que el sistema debería acelerar tu trabajo para que el trabajo termine lo antes posible. Para obtener más información, consulta Cómo programar tareas con WorkManager
Prácticas recomendadas
Cada decisión que tomes al diseñar una alarma repetitiva puede tener consecuencias en la manera en que tu app usa (o abusa) de los recursos del sistema. Por ejemplo, imagina un app popular que se sincroniza con un servidor. Si la operación de sincronización se basa en el reloj y cada instancia de la aplicación se sincroniza a las 11:00 p.m., la carga del el servidor, lo que puede generar una latencia alta o incluso “denegación del servicio”. Sigue estas prácticas recomendadas para usar las alarmas:
Agregar aleatorización (jitter) a cualquier solicitud de red que se activa como resultado de una alarma repetida:
Realiza las tareas locales cuando se active la alarma. "Trabajo local" significa todo lo que no llegue a un servidor ni requiera los datos de este.
Al mismo tiempo, programa la alarma que contenga las solicitudes de red para activar en algún período aleatorio.
Mantén la frecuencia de la alarma al mínimo.
No actives el dispositivo innecesariamente (este comportamiento lo determina la según se describe en Cómo elegir un tipo de alarma).
No hagas que el tiempo de activación de tu alarma sea más preciso de lo necesario.
Usa
setInexactRepeating()
en vez desetRepeating()
Cuando usassetInexactRepeating()
, Android sincroniza las alarmas repetitivas de varias apps y se activa al mismo tiempo. Esto reduce la cantidad total de veces que el sistema debe activar el del dispositivo y, por lo tanto, se reduce el consumo de la batería. A partir de Android 4.4 (nivel de API 19), todas las alarmas repetitivas son una alarma inexacta. Nota que mientrassetInexactRepeating()
es una mejora con respectosetRepeating()
, puede sobrecargar un servidor si cada instancia de una app llega a él casi al mismo tiempo. Por lo tanto, para las solicitudes de red, agrega aleatorización las alarmas, como lo analizamos anteriormente.Si es posible, evita basar tu alarma en la hora del reloj.
Las alarmas repetitivas que se basan en una hora de activación precisa no se escalan bien. Usa
ELAPSED_REALTIME
si que puedas. La alarma diferente se describen con más detalle en la siguiente sección.