¿Por qué Android restringe el background?
Un smartphone promedio tiene cientos de apps instaladas. Si cada una pudiera correr libremente en background — sincronizando datos, procesando, recibiendo eventos — la batería duraría horas y el dispositivo sería lento. Android tomó la decisión deliberada de sacrificar libertad de los desarrolladores para mejorar la experiencia del usuario.
Cada versión de Android desde el 6.0 (Marshmallow) agregó más restricciones. Entender esto no es opcional — es la diferencia entre una app que funciona bien y una que los usuarios desinstalan porque "consume mucha batería".
Doze mode — la pantalla apagada
Cuando el dispositivo está sin uso (pantalla apagada, estacionario, con batería), Android entra en Doze mode. En este modo:
- El acceso a la red está suspendido
- Los wakelocks (mantener CPU activa) son ignorados
- Los jobs del JobScheduler se difieren
- Las alarmas estándar se difieren (excepto
setAlarmClock()) - Los GPS y sensores se deshabilitan
Doze tiene dos niveles desde Android 7.0: el nivel profundo cuando el dispositivo está completamente inactivo, y un nivel más suave cuando la pantalla está apagada pero el dispositivo se mueve (ej: en un bolsillo).
Maintenance windowsDoze no bloquea el background para siempre — periódicamente abre ventanas de mantenimiento donde las apps pueden sincronizar, recibir notificaciones y correr jobs diferidos. WorkManager está diseñado específicamente para aprovechar estas ventanas.
App Standby Buckets
Android categoriza cada app en un "bucket" según qué tan recientemente la usó el usuario. El bucket determina qué recursos background puede usar:
# ACTIVE — la app está en uso ahora o fue usada hace muy poco
# Sin restricciones de background
# WORKING SET — se usa frecuentemente (todos los días)
# Jobs y alarmas con leve restricción
# FREQUENT — se usa regularmente pero no todos los días
# Jobs con más restricción, alarmas limitadas
# RARE — se usa pocas veces al mes
# Jobs muy restringidos, red limitada, alarmas muy limitadas
# RESTRICTED (Android 12+) — el sistema determinó que la app abusa del background
# Background casi completamente bloqueado
# Ver el bucket actual de una app:
adb shell am get-standby-bucket ar.pensa.miapp
Implicación prácticaSi tu app hace sync en background y un usuario no la abre en semanas, el sistema la pondrá en RARE y los jobs se van a ejecutar con mucho menos frecuencia de lo esperado. Es por eso que las apps de email o mensajería necesitan notificaciones push (FCM) en lugar de polling periódico.
Battery optimizations
El usuario puede ir a Ajustes → Batería → Optimización de batería y ver el estado de cada app. Hay tres estados posibles:
- Optimizada (default): el sistema aplica todas las restricciones de Doze y App Standby.
- Sin restricciones: la app puede correr en background libremente. El usuario la concede manualmente, o la app puede pedirla con
ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS. - Optimización pausada: estado intermedio en algunos dispositivos.
// Verificar si la app tiene la excepción de batería
val powerManager = getSystemService(Context.POWER_SERVICE) as PowerManager
val tieneExcepcion = powerManager.isIgnoringBatteryOptimizations(packageName)
// Pedir al usuario que excluya la app (muestra el diálogo del sistema)
// Solo válido para apps con justificación legítima (VPN, alarmas, etc.)
// Google rechaza apps que lo piden sin justificación
if (!tieneExcepcion) {
val intent = Intent(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS).apply {
data = Uri.parse("package:$packageName")
}
startActivity(intent)
}
No pidas la excepción sin justificación realGoogle Play tiene una política explícita: solo apps con necesidades legítimas de background (alarmas de despertador, VPN, apps de salud que monitorean señales vitales) pueden solicitar la excepción. Apps que la piden para sincronización o notificaciones son rechazadas o removidas.
Background execution limits (Android 8.0+)
Desde Android 8.0 (Oreo), las apps en background tienen limitaciones severas adicionales:
- Background services: una app en background no puede iniciar servicios nuevos. El sistema los detiene a los pocos minutos.
- Implicit broadcasts: la mayoría de los broadcasts implícitos del sistema ya no se reciben en el Manifest — solo en receivers registrados dinámicamente mientras la app está corriendo.
- Background location: el acceso a ubicación en background requiere un permiso especial (
ACCESS_BACKGROUND_LOCATION) y aprobación manual del usuario desde Android 10.
// Antes de Android 8 esto funcionaba — ahora el sistema lo mata en background:
startService(Intent(this, MiSyncService::class.java)) // MALO en Android 8+
// La solución correcta:
// 1. Para trabajo que no necesita notificación → WorkManager
// 2. Para trabajo que necesita notificación visible → ForegroundService
startForegroundService(Intent(this, MiSyncService::class.java)) // OK
Restricciones adicionales de fabricantes
Por si las restricciones de Google no fueran suficientes, los fabricantes agregan las propias. Samsung, Xiaomi, Huawei, OnePlus y otros tienen sistemas de optimización de batería propios que son mucho más agresivos que los de stock Android:
- Xiaomi MIUI puede matar apps de background casi inmediatamente
- Samsung tiene su propia whitelist de apps que pueden correr en background
- Huawei EMUI limita agresivamente el background incluso para apps con ForegroundService
dontkillmyapp.comEste sitio documenta las restricciones específicas de cada fabricante y tiene instrucciones para que el usuario las desactive. Es un recurso valioso para debugging cuando una app funciona bien en Pixel pero falla en Samsung o Xiaomi.