Plantilla Android (Java) que convierte cualquier aplicación web en una app nativa en modo kiosko: pantalla completa bloqueada, sin barras del sistema, sin navegación fuera del WebView y pensada para correr en dispositivos dedicados (tótems, exhibidores, puntos de venta, pantallas informativas).
Cambiás una URL, personalizás el icono y ya tenés tu kiosko empaquetado como APK.
- ¿Por qué kiosk-webview-template?
- Características
- Requisitos del Sistema
- Permisos
- Quick Start
- Configuración de tu WebApp
- Configuración del Proyecto
- Estructura del Código
- Comportamiento sin Internet
- Construcción y Despliegue
- Personalización Avanzada
- Casos de Uso
- Pruebas
- Roadmap
- Versión
- Licencia
Armar un kiosko Android real no es solo "abrir un WebView en fullscreen". Requiere bloquear barras del sistema, controlar gestos, manejar reconexión, evitar que el usuario salga de la app accidentalmente y, sobre todo, no reinventar la rueda cada vez que necesitás un exhibidor nuevo.
Esta plantilla te da:
- Un punto de partida probado y mínimo para apps kiosko.
- Cero lógica de negocio: toda la UI vive en tu webapp, vos solo definís la URL.
- Personalización por configuración, no por reescritura: orientación, touch, zoom, certificados, etc.
- Base lista para endurecer (lock task mode, Device Owner, MDM) cuando lo necesites.
- Pantalla completa inmersiva (sticky immersive): oculta barras de estado y navegación.
- Bloqueo del back del sistema fuera del WebView (la app no se cierra con el botón atrás).
- Entrada solo por mouse por defecto — el touch queda deshabilitado, ideal para exhibidores con mouse externo.
- Cierre protegido mediante clic derecho del mouse (comportamiento por defecto, modificable).
- Recarga automática al volver al primer plano, sin intervención del usuario.
- Caché optimizado para evitar pantallas en blanco al reanudar.
- Orientación bloqueada (portrait por defecto, configurable a landscape).
- URL configurable desde una única constante en
MainActivity.java. - Soporte HTTPS y HTTP claro para entornos de desarrollo.
- Carga de assets locales empaquetados en el APK (
file:///android_asset/). - JavaScript, DOM storage y base de datos web habilitados.
- DevTools remoto activable en builds de debug para inspeccionar la webapp desde Chrome.
- Detección de conexión en tiempo real.
- Reconexión automática cada 3 segundos cuando no hay red.
- Pantalla de error amigable con animación de carga y mensaje visual.
- Gestión de memoria del WebView para evitar memory leaks en sesiones largas.
- Manejo correcto del ciclo de vida (
onPause/onResume/onDestroy).
| Componente | Versión / Detalle |
|---|---|
| Mínimo SDK | Android 7.0 Nougat (API 24) |
| Target SDK | Android 14 (API 36) |
| Compile SDK | 36 |
| Java | 11 |
| Build Tool | Android Studio + Gradle |
| Permisos | INTERNET, ACCESS_NETWORK_STATE |
Declarados en app/src/main/AndroidManifest.xml:
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>Para endurecer el modo kiosko en producción (lock task mode, Device Owner) probablemente necesites permisos adicionales. Ver Personalización Avanzada.
# 1. Clonar el repositorio
git clone https://github.com/tu-usuario/kiosk-webview-template.git
cd kiosk-webview-template
# 2. Abrir en Android Studio
# File → Open → seleccionar la carpeta del proyecto
# 3. Configurar tu URL
# Editar MainActivity.java:
# private final String url = "https://tu-kiosko.com";
# 4. Compilar e instalar
./gradlew assembleDebug
adb install -r app/build/outputs/apk/debug/app-debug.apkEso es todo. Tu kiosko está corriendo en el dispositivo.
Abrí app/src/main/java/com/example/webapp/MainActivity.java y cambiá la constante:
private final String url = "https://tu-dominio.com";Ejemplos válidos:
// Producción (kiosko en local con tu webapp)
private final String url = "https://kiosko.miapp.com";
// Desarrollo local en emulador
private final String url = "http://10.0.2.2:3000";
// Desarrollo local en dispositivo físico (vía adb reverse)
private final String url = "http://localhost:3000";
// Asset local empaquetado en el APK
private final String url = "file:///android_asset/index.html";
// Con puerto y path específicos
private final String url = "https://api.miapp.com:8443/kiosk";Editá app/src/main/res/values/strings.xml:
<string name="app_name">Kiosko - Mi Empresa</string>Reemplazá los archivos en app/src/main/res/mipmap-*/ con tus propios assets:
ic_launcher.pngic_launcher_round.png
Tip: usá Image Asset Studio (clic derecho en
res→ New → Image Asset) para generar todas las densidades automáticamente.
Si querés renombrar el paquete, usá Refactor → Rename en Android Studio sobre el paquete com.example.webapp, y actualizá applicationId y namespace en build.gradle.kts.
Modificá estos valores en app/build.gradle.kts:
namespace = "com.example.webapp"
applicationId = "com.example.webapp"
versionCode = 1
versionName = "1.0"androidx.appcompat:appcompatcom.google.android.material:materialjunit:junit(testing unitario)androidx.test.ext:junit+espresso-core(testing instrumentado)
kiosk-webview-template/
├── app/
│ ├── src/
│ │ ├── main/
│ │ │ ├── AndroidManifest.xml
│ │ │ ├── java/com/example/webapp/
│ │ │ │ └── MainActivity.java # Lógica del WebView y modo kiosko
│ │ │ └── res/
│ │ │ ├── layout/ # activity_main.xml
│ │ │ ├── values/ # strings.xml, colors.xml, themes.xml
│ │ │ ├── values-night/ # tema oscuro
│ │ │ └── mipmap-*/ # iconos
│ │ └── test/ # tests unitarios e instrumentados
│ └── build.gradle.kts
├── build.gradle.kts
└── README.md
Punto de entrada único. Responsabilidades:
- Inflar el layout con el
WebView. - Configurar flags de pantalla completa e inmersión.
- Habilitar JavaScript, DOM storage y base de datos web.
- Registrar listeners de conectividad y manejar la reconexión.
- Manejar ciclo de vida (
onPause/onResume/onDestroy). - Gestionar navegación interna y eventos de mouse.
Cuando el dispositivo no tiene conexión:
- Se oculta el WebView y se muestra una vista de error.
- Aparece un mensaje de advertencia visual y una animación de carga giratoria.
- Un handler reintenta la conexión cada 3 segundos.
- Al establecerse la red, la app recarga la URL automáticamente.
Pensado para kioskos unattended: el dispositivo se recupera solo, sin intervención humana.
./gradlew assembleDebugSalida: app/build/outputs/apk/debug/app-debug.apk
./gradlew assembleReleasePor defecto, el
build.gradle.ktsusa la firma de debug para el build de release. Antes de publicar en Play Store configurá un keystore propio ensigningConfigs.
adb install -r app/build/outputs/apk/debug/app-debug.apkadb devices | tail -n +2 | cut -sf1 | xargs -I{} adb -s {} install -r app-debug.apk./gradlew cleanEn AndroidManifest.xml, dentro de la actividad:
android:screenOrientation="landscape" <!-- o "portrait", "sensor", "nosensor" -->En MainActivity.java, comentá o eliminá la línea que deshabilita el touch:
// webView.setOnTouchListener((v, event) -> true);Para mantener tráfico claro hacia un dominio específico, ajustá network_security_config.xml con un domain-config apropiado.
Por defecto el zoom está deshabilitado para una experiencia kiosko controlada. Para rehabilitarlo en MainActivity.java:
webView.getSettings().setBuiltInZoomControls(true);
webView.getSettings().setSupportZoom(true);Útil para depurar la webapp desde Chrome en escritorio:
WebView.setWebContentsDebuggingEnabled(true);Activá esto solo en builds de debug.
Para un kiosko real (que el usuario no pueda evadir), necesitás ir más allá de la UI:
- Lock Task Mode (
startLockTask()): requiere que la app sea Device Owner o que se lance desde un launcher en modo kiosko. - Device Owner: configurá la app como propietaria del dispositivo vía
adb shell dpm set-device-owner. - Quitar barras del sistema de forma agresiva: combinar
WindowInsetsController+ flags legacy. - Deshabilitar botones físicos: requiere permisos de sistema o root.
Estos cambios están fuera del scope de esta plantilla base, pero son los próximos pasos naturales si necesitás un kiosko unattended de producción.
- Tótems y exhibidores en puntos de venta mostrando catálogo, promociones o encuestas.
- Pantallas informativas en recepciones, salas de espera o ferias.
- Demos de producto en stands, corriendo 24/7 sin intervención.
- Kioskos de auto-consulta (turnos, trámites, información).
- Displays de cartelería digital (digital signage) alimentados desde una webapp.
- Equipos dedicados en líneas de producción o backoffice que necesitan una UI web simple y bloqueada.
El proyecto incluye el esqueleto estándar de Android Studio:
- Tests unitarios locales:
app/src/test/ - Tests instrumentados:
app/src/test/androidTest/
Ejecutar:
./gradlew test # unitarios
./gradlew connectedAndroidTest # instrumentados (requiere dispositivo/emulador)- Soporte opcional para Lock Task Mode / Device Owner out-of-the-box.
- Configuración de kiosko vía
Intent extraso archivoassets/kiosk.json(sin recompilar). - Plantilla de página offline personalizable.
- Soporte para wake lock configurable (mantener pantalla siempre encendida).
- Documentación de despliegue a flotas con MDM (Google Workspace, Knox, etc.).
- Script Gradle para build multi-flavor (varios kioskos desde un mismo proyecto).
- Versión actual: 1.0
- Version code: 1
Este proyecto se distribuye como plantilla de código abierto bajo licencia MIT. Adaptalo libremente a las necesidades de tu kiosko o producto.