En este post voy a enseñarte a programar un servidor web en Android asegurándonos de que el web server se ejecuta siempre en segundo plano y que no será detenido por el sistema.
Vamos a programar un servidor web en Android usando Kotlin y la librería NanoHTTPD. Dicho web server va a ser iniciado desde un servicio (Service) que muestra una notificación persistente para que el usuario sepa que el servidor web está ejecutándose en segundo plano.
Te voy a enseñar a implementar el servicio, crear la notificación, solicitar los permisos para notificaciones e iniciar el servidor web en Android de manera programada.
Añadir dependencia NanoHTTPD
Esto puede cambiar entre proyectos pero en mi caso primero modifiqué mi libs.versions.toml. En [versions]
añadí:
nanohttpd = "2.3.1"
Luego, en [libraries]
lo siguiente:
nanohttpd = { group = "org.nanohttpd", name = "nanohttpd", version.ref = "nanohttpd" }
Finalmente mi libs.versions.toml completo quedó así:
Luego, en build.gradle.kts añadí lo siguiente en dependencies:
implementation(libs.nanohttpd)
De modo que quedó así:
Programando servidor web
El servidor web queda así. Toma en cuenta que ahora solo manejo una ruta que muestra un hola mundo, ya a partir de aquí puedes añadir más rutas.
Mi archivo se llama SimpleServer.kt y queda así:
Para usar e iniciar el servidor simplemente debemos hacer lo siguiente:
Todavía no lo vamos a hacer porque esto debe ir dentro del servicio.
Servicio en segundo plano
Ahora vamos a crear un servicio en segundo plano, iniciarlo desde nuestra actividad principal y, dentro de dicho servicio, encender el servidor web en Android en segundo plano.
Comenzamos creando el servicio, en mi caso se llama WebServerService.kt; el nombre es importante porque vamos a registrarlo en el manifiesto.
Lo importante aquí es que a partir de Android Oreo debemos registrar un canal de notificaciones para mostrar la notificación. Estoy usando NotificationCompat
para crear notificaciones sin importar la versión de Android.
Enviar una notificación cuando se crea un servicio en segundo plano (con crearNotificacionParaServicio
) es obligatorio en las versiones más recientes de Android. Además, a partir de Android 13 debemos tener permiso de enviar notificaciones y pedir dicho permiso tanto en el manifiesto como en tiempo de ejecución.
Otra parte importante es registrar el servicio en el AndroidManifest.xml dentro de application:
Además, debemos añadir los siguientes permisos:
Solo como referencia, dejo mi AndroidManifest.xml completo:
La parte importante y que realmente levanta el servidor web es el onCreate del servicio en el siguiente bloque:
El puerto del servidor será el 8000 y puedes ajustarlo como prefieras.
Iniciar servidor
Finalmente en nuestra actividad principal iniciamos el servicio en el onCreate
. Tengo la siguiente función que lo hace:
Es importante que notes que servidorIniciado
es una variable que está en conjunto con Jetpack Compose. Si tú no usas Compose entonces puedes omitir esas variables.
Ahora ya solo falta iniciar el servidor en el onCreate
:
Por favor toma en cuenta que justo ahora no estoy manejando la solicitud de permisos en tiempo de ejecución para mostrar notificaciones. Lo añadiré más adelante.
Si todo sale bien, tan pronto inicie la aplicación se nos debe mostrar una notificación persistente:

Y si navegamos a localhost:8000/version vamos a ver el servidor web manejando las peticiones:

De ese modo vamos a tener un servidor web en Android ejecutándose siempre en segundo plano, con la seguridad de que el proceso no será detenido por el sistema operativo.
Permiso para mostrar notificaciones
A partir de Android Tiramisú se necesita un permiso solicitado en tiempo de ejecución para mostrar notificaciones, además de declararlo en el manifiesto.
Yo tengo la siguiente función que me devuelve la lista de permisos que necesita mi app, en este caso solo es el de mostrar notificaciones desde Android 13:
La siguiente función me permite saber si se han concedido todos los permisos:
En caso de que los permisos no hayan sido concedidos, los solicito. Primero necesito el request permission launcher que será invocado después de que el usuario acepte o rechace los permisos:
Luego los solicito así indicando el requestPermissionLauncher previamente creado:
Y mi función que inicia el servidor revisando los permisos es la siguiente:
Resumiendo
- Añade las dependencias de NanoHTTPD (libs.versions.toml y build.gradle.kts)
- Crea el archivo que va a manejar el servidor (SimpleServer.kt)
- Crea el servicio que va a iniciar el servidor (WebServerService.kt)
- Solicita e indica los permisos necesarios
- Registra el servicio en el manifiesto (AndroidManifest.xml)
- Inicia el servicio (que inicia a su vez el web server) cuando quieras, en este caso lo hicimos en el onCreate de la actividad principal (MainActivity.kt)
Por cierto, no es obligatorio usar NanoHTTPD; yo lo he usado porque es muy fácil de implementar. Lo realmente importante es saber manejar el servidor en segundo plano para que no sea detenido por el sistema.