Diario de desarrollo
Estamos en 2026 y mantener una app de sueño sonando toda la noche sigue siendo sorprendentemente difícil
Quería que mi teléfono hiciera ruido de ventilador hasta la mañana. En 2026 parecía un problema bastante resuelto, pero me ha ocupado una cantidad sorprendente de tiempo como desarrollador.
Durante años usé White Noise Lite. Tenía anuncios y una interfaz que me parecía antiquísima, pero generalmente funcionaba, que era lo importante. Después empezó a detenerse con frecuencia. Yo lo consideraba un fallo de la app, aunque no tenía los registros para saber qué ocurría. También quería una interfaz moderna y sonidos generados en el dispositivo en lugar de grabaciones, con controles para ajustarlos a mi gusto. Terminé creando mi propia app, Veil, y entendiendo mucho mejor el problema de la fiabilidad.
En iOS, la reproducción en segundo plano ha sido relativamente sencilla y, según mi experiencia, Veil ha sido muy estable desde el principio. Android se convirtió en un proyecto más largo. Hay hardware muy variado, incluidos teléfonos antiguos con poca memoria, gestión de batería propia de cada fabricante y alguna actualización que llega en plena sesión. Mi código también tenía bastantes problemas. Para quien se despierta a las tres de la mañana, la diferencia importa poco.
Empecé con informes de fallos, pero pronto necesité más contexto. Un proceso terminado puede no informar nunca de una excepción, y un proceso vivo puede tener un flujo de audio silencioso. Ni un servicio en primer plano ni una notificación de reproducción demuestran que salga sonido del altavoz. Añadí un diario nativo de reproducción, información sobre la terminación del proceso, mediciones de memoria, estado del servicio, eventos de audio y registros explícitos de paradas intencionadas. Las pruebas relevantes sobreviven al proceso y se recogen en un inicio posterior.
El objetivo era reconstruir suficiente contexto de la noche para distinguir causas posibles. ¿La reproducción seguía siendo deseada? ¿Había terminado el temporizador? ¿Crecía la memoria? ¿Estaba enchufado el teléfono? ¿Había sustituido Android el paquete? Más señales ayudaban, siempre que entendiera lo que realmente podían decirme.
Una de las primeras cosas que tuve que depurar fue la propia medición. Quitar Veil de las apps recientes podía detener el audio sin cerrar correctamente la sesión registrada. Horas después Android podía eliminar el proceso en caché, y mis informes lo contaban como un fallo de reproducción. Alguien que cerraba la app voluntariamente por la mañana podía aparecer como un «cierre nocturno». Mientras tanto, las actualizaciones que interrumpían una reproducción real se excluían como terminaciones normales del sistema.
Corregir esas definiciones cambió el panorama antes de arreglar más código de audio. Desde entonces distingo cuidadosamente entre mejorar la reproducción y mejorar su medición. Reviso regularmente los datos por versión, familia de dispositivos, duración y motivo de terminación, excluyendo equipos de prueba y eliminando duplicados. También importa el retraso de los informes: unas sesiones cortas en una versión nueva no demuestran que aguante toda la noche.
Esos patrones orientan las pruebas en dispositivos. He hecho pruebas prolongadas y nocturnas en teléfonos físicos, además de sesiones en el laboratorio remoto de Samsung, con logcat continuo, muestras de memoria y presión de memoria, y capturas del estado del audio y los servicios cuando algo falla. El sistema recoge las pruebas sin que yo tenga que sorprender al teléfono fallando en persona.
También aprendí que el entorno de prueba puede alterar el resultado. El USB alimenta el teléfono, así que una prueba conectada no equivale a usarlo desenchufado con batería. Ejecutar dumpsys meminfo repetidamente podía provocar fallos de audio por sí mismo. Y una noche sin incidentes solo demuestra que no reproduje el fallo en esas condiciones. Es una prueba útil, pero no valida todos los dispositivos ni estados del sistema.
Uno de los descubrimientos más extraños fue Android Auto Backup. En mi Pixel, los registros captaron a BackupManager terminando el proceso de Veil durante una copia de seguridad mientras sonaba el audio. Al revisar los datos de los dispositivos, encontré 190 SIGKILL de procesos protegidos en 93 instalaciones, entre el 14 de agosto y el 11 de septiembre de 2026, con intervalos recurrentes cercanos a tres días. El patrón respaldaba la explicación de la copia de seguridad sin demostrar la causa de cada cierre.
Desactivé Auto Backup para Veil, aceptando la contrapartida para la restauración desde la nube. Android documenta que las copias cierran la app, aunque normalmente excluyen las apps en primer plano; capturar lo sucedido en el dispositivo permitió actuar sobre este caso concreto. Documentación de copias de seguridad de Android
Otros problemas me correspondían a mí. La recuperación del audio podía construir un contexto nuevo antes de que el anterior terminara de cerrarse, solapando recursos cuando la app ya tenía dificultades. Hice que se esperara al cierre con un límite de tiempo y serialicé la recuperación con las operaciones de reproducción. También hay que respetar las intenciones más recientes: si alguien pulsa detener mientras espera una reparación, esta no debe volver a encender el sonido.
Una corrección introdujo otro fallo. Añadí una comprobación de 150 ms para ver si avanzaba el reloj del contexto de audio y detectar uno bloqueado pese a declararse activo. Por desgracia, esperaba a un temporizador JavaScript. En segundo plano, esa espera podía quedar suspendida hasta volver al primer plano. Ahora la comprobación solo se ejecuta en primer plano, y tengo otro motivo para probar las recuperaciones con la pantalla apagada.
Algunos cambios especialmente útiles fueron decisiones de producto. Las mediciones mostraron unos 90 MB adicionales de memoria residente asociados al proceso WebView publicitario. Una investigación anterior también había detectado fallos de memoria graves relacionados con el SDK. Primero intenté contener ese coste y después eliminé los anuncios y el SDK por completo. Para algo que debe funcionar toda la noche, la fiabilidad importaba más que conservar los anuncios.
La telemetría seguía dejando una pregunta importante sin responder: ¿la persona esperaba que se detuviera? Tras una interrupción relevante, Veil puede mostrar una tarjeta con la hora y preguntar: «¿Esperabas que ocurriera esto?». La formulación es deliberada. «¿Lo detuviste tú?» no contempla que lo hiciera una pareja o que la interrupción fuera esperada aunque el usuario no tocara nada.
Si la parada era esperada, no enviamos al usuario a revisar la batería. Si no lo era, la app reconoce la interrupción y ofrece ayuda ajustada a las pruebas disponibles. Su respuesta me da información directa sobre la experiencia sin pretender identificar la causa técnica. También evita recibir a cada nuevo usuario Android con permisos alarmantes y una búsqueda por los ajustes de batería.
Esos ajustes son complicados para ambas partes. Puedo abrirlos o solicitar una excepción cuando corresponde, pero la decisión es del usuario. El mecanismo de excepciones de Android tampoco controla todas las funciones de limpieza de cada fabricante. Un paso concreto después de un problema ayuda más que pedir que se exploren ajustes desconocidos antes de reproducir el primer sonido. Guía de gestión de energía de Android
Las actualizaciones son especialmente frustrantes. Puedo guiar a alguien hasta la opción de actualización automática de cada app en Play, pero Veil no controla esa preferencia. Gestionarlas manualmente añade otra tarea, y Google contempla excepciones para actualizaciones críticas de seguridad. Una actualización pensada para mejorar la fiabilidad nocturna puede interrumpir la noche. Ajustes de actualización de Google Play
La recuperación automática después de actualizar sigue pendiente. Reconstruir el grafo de audio es solo una parte: también deben conservarse correctamente el temporizador y la intención del usuario. Algunos patrones específicos de fabricantes necesitan mejores reproducciones antes de que pueda explicarlos con confianza. Quiero que la app se recupere de los fallos, pero no que pelee con alguien que la ha detenido voluntariamente.
Los avances más útiles han venido de combinar análisis recurrentes, pruebas largas, correcciones concretas y respuestas directas de los usuarios. Cada cosa detecta lo que las demás pasan por alto. Me interesa menos que la app diga que está reproduciendo y más qué pruebas lo respaldan. Quien pulsa reproducir antes de acostarse debería poder darlo por hecho, aunque conseguirlo haya requerido mucho más trabajo del esperado.
¿Buscas pasos prácticos para tu teléfono? Consulta la guía complementaria: Solucionar cortes de audio en Android.