Android
Meratyn se ejecuta como una aplicación nativa de Android construida desde la misma base de código React mediante Tauri v2 mobile, sin una app separada. La interfaz del webview va incluida en el APK, de modo que el shell de la app funciona sin conexión; los mosaicos del mapa y los motores más pesados se descargan a demanda (igual que en la build de escritorio).
Qué funciona en Android frente al escritorio
La build de Android incluye el espacio de trabajo completo del mapa, Add Data, las herramientas vectoriales (Turf.js / GeoPandas en el navegador vía Pyodide), el SQL Workspace (DuckDB-WASM y el motor PGlite/PostGIS en el navegador), la Python Console (Pyodide), la geocodificación, las estadísticas, el asistente de IA, los story maps y los plugins.
Android no tiene sidecar Python ni binarios auxiliares locales. El procesamiento
compatible con el navegador se ejecuta en el dispositivo cuando la operación y
el formato de entrada lo permiten: Whitebox y las herramientas ráster usan sus
motores WASM, y los formatos de conversión compatibles con el navegador siguen
disponibles. Las herramientas exclusivas del sidecar, las rutas a archivos
nativos y la fuente PostgreSQL/Martin local permanecen ocultas en móvil. Estos
límites se controlan mediante isMobile() del user-agent para que una ruta no
disponible no aparezca y falle después.
Preparación del toolchain (una sola vez)
Necesita el Android SDK + NDK, un JDK (17 o 21; los JDK más nuevos pueden romper el Android Gradle Plugin) y los targets de Rust para Android. La disposición más limpia, sin sudo, mantiene todo bajo un SDK escribible por el usuario en ~/Android/Sdk.
# 1. JDK 17/21 (or reuse Android Studio's bundled JBR at /opt/android-studio/jbr)
export JAVA_HOME=/path/to/jdk-21
# 2. Android SDK components (sdkmanager ships with Android Studio cmdline-tools)
export ANDROID_HOME="$HOME/Android/Sdk"
yes | sdkmanager --sdk_root="$ANDROID_HOME" --licenses
sdkmanager --sdk_root="$ANDROID_HOME" \
"platform-tools" "platforms;android-36" \
"build-tools;36.0.0" "ndk;27.3.13750724"
export NDK_HOME="$ANDROID_HOME/ndk/27.3.13750724" # Tauri needs NDK_HOME
# 3. Rust + the four Android targets (install rustup if you don't have it)
rustup target add aarch64-linux-android armv7-linux-androideabi \
i686-linux-android x86_64-linux-android
NDK r27 (LTS) es la línea soportada por Tauri v2. Añada los cuatro export a su perfil de shell para que todas las sesiones los tengan.
API 36 (Android 16), no 34: la plantilla de Android de Tauri v2.11 genera
compileSdk = 36 / targetSdk = 36, así que Gradle necesita tener instalada la plataforma correspondiente. También coincide con el mínimo de plataforma de Android: a partir del 31-08-2026 se espera que las apps destinadas a Android declaren la API 36 o posterior.
Las apps destinadas a Android 15+ cuyas librerías nativas no estén alineadas con páginas de memoria de 16 KB no cargan en dispositivos de páginas de 16 KB. NDK r28+ lo hace por defecto; r27 no, por eso los flags se pasan explícitamente. Exporte esto antes de una build de Android:
export RUSTFLAGS="-C link-arg=-Wl,-z,max-page-size=16384 -C link-arg=-Wl,-z,common-page-size=16384"
Debe ser la variable de entorno
RUSTFLAGS. Poner los mismos flags entarget.<triple>.rustflagsde un.cargo/config.tomlno funciona: la CLI de Tauri defineRUSTFLAGSpor su cuenta cuando invoca cargo para Android, y una variableRUSTFLAGSdel entorno prevalece sobre el archivo de configuración sin más. La forma vía archivo de configuración se ignora silenciosamente: se parsea, compila, y entrega librerías alineadas a 4 KB que fallan al cargar en dispositivos de 16 KB. Tauri añade sobre un valor heredado, así que exportarlo sí funciona.
Compruebe el resultado en un APK ya compilado:
unzip -o -q app-arm64-release-unsigned.apk 'lib/*/*.so' -d /tmp/apkcheck
"$NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-objdump" -p \
/tmp/apkcheck/lib/*/*.so | awk '$1 == "LOAD" { print $NF }' | sort -u
# every value must be 2**14 or greater; 2**12 means the flags did not apply
Use llvm-objdump -p en lugar de readelf -l: readelf reparte cada LOAD en dos líneas, por lo que es fácil parsear la columna equivocada y leer una dirección como si fuera una alineación. Ejecute esta comprobación en cada build cuyas librerías nativas hayan cambiado, antes de instalar cualquier cosa en un dispositivo de 16 KB.
Build
cd apps/mappview
bunx --no-install tauri android init # generate src-tauri/gen/android (once)
bunx --no-install tauri android build --apk --split-per-abi # release APKs, one per ABI (~40 MB each)
bunx --no-install tauri android build --aab # only if a bundle (.aab) is ever needed
-
gen/androidse genera (ignorado por git) y se regenera a demanda. -
Compile release, no
--debug: el perfil de Cargo optimizado y sin símbolos deja cada APK en ~40 MB; una build debug ronda los ~200 MB (.sosin depurar y con debuginfo). -
--split-per-abiemite un APK por arquitectura en lugar de un único APK universal de ~150 MB. Instale elarm64en teléfonos reales. -
Salida:
src-tauri/gen/android/app/build/outputs/apk/<abi>/release/app-<abi>-release-unsigned.apk, donde<abi>es el nombre corto de Tauri —arm64,arm,x86,x86_64— no el nombre de directorio ABI de Android (arm64-v8a,armeabi-v7a) que aparece dentro del APK bajolib/. -
Vía de instalación lateral (sideload): los APK por ABI —los artefactos instalables.
La app se llama Meratyn en Android (la build de escritorio se llama “Meratyn Desktop”) y usa el id de paquete com.mapptech.mappview; ambos se definen en src-tauri/tauri.android.conf.json, que además excluye el backend Python del bundle de Android.
El id de Android se sobreescribe allí en lugar de hacerlo en tauri.conf.json a propósito: identifier lo comparten todas las plataformas y también determina los directorios de datos y configuración de la aplicación de escritorio. El valor de escritorio sigue siendo el identificador heredado com.mapptech.mappview para que las actualizaciones de Meratyn conserven los plugins, notebooks, runtimes gestionados, ajustes y ámbitos de sistema de archivos persistidos existentes.
Firma
Los APK de release salen sin firmar. Para instalar uno, fírmelo (una clave debug sirve para pruebas; use una clave real para distribución):
BT="$ANDROID_HOME/build-tools/36.0.0"
KS="$HOME/.android/debug.keystore" # auto-created by Android tooling; or make your own
# -P 16, not -p: -p only guarantees 4 KB; the .so must sit on a 16 KB boundary
# inside the zip to load on 16 KB devices.
"$BT/zipalign" -P 16 -f 4 app-arm64-release-unsigned.apk aligned.apk
"$BT/apksigner" sign --ks "$KS" --ks-pass pass:android \
--ks-key-alias androiddebugkey --key-pass pass:android \
--out mappview-arm64.apk aligned.apk
"$BT/apksigner" verify mappview-arm64.apk
El ejemplo firma el APK arm64. Sustituya el ABI que necesite en todo el proceso:
app-x86_64-release-unsigned.apk → mappview-x86_64.apk, e igualmente para
armeabi-v7a / x86. La sección del emulador instala mappview-x86_64.apk,
que es este mismo recorrido con arm64 sustituido por x86_64.
Para una clave real de subida/release:
keytool -genkeypair -v -keystore upload.jks -alias upload -keyalg RSA \
-keysize 2048 -validity 10000
Builds de release
Las builds de Android son solo locales. Configure un keystore de subida propiedad de Meratyn y ejecute la build de Tauri Android en una máquina de desarrollo de confianza. Mantenga el keystore y las contraseñas fuera del repositorio. El .apk es el artefacto instalable para pruebas locales e instalación lateral.
Instalación / prueba
En un teléfono
- Active las Opciones de desarrollador (toque 7× el número de build) y la depuración USB.
- Instale lateralmente el APK firmado:
O copie el APK al teléfono y tóquelo (permita “instalar apps desconocidas”).adb install -r mappview-arm64.apk
Para desarrollo en vivo con hot reload, conecte el dispositivo y ejecute
bun run tauri android dev.
En un emulador
sdkmanager --sdk_root="$ANDROID_HOME" \
"emulator" "system-images;android-36;google_apis_playstore;x86_64"
avdmanager create avd -n mappview \
-k "system-images;android-36;google_apis_playstore;x86_64" -d pixel_7
emulator -avd mappview
# x86_64 APK to match the x86_64 system image — the emulator can translate the
# arm64 build, but far slower, and it would not exercise the x86_64 libraries.
adb install -r mappview-x86_64.apk
Si alguna vez recompila con una clave de firma distinta, desinstale primero la copia antigua (
adb uninstall com.mapptech.mappview): Android rechaza actualizaciones cuya firma cambió.
Limitaciones conocidas / pendientes
- Las fuentes de archivos locales (MBTiles, rásters locales, archivos de proyecto) asumen rutas reales del sistema de archivos; el almacenamiento acotado de Android devuelve URIs de contenido, así que esos flujos necesitan adaptarse antes de funcionar de forma nativa.
- La herramienta Download Offline Area depende de un service worker, que las builds de Tauri (escritorio y Android) no usan — es una función de PWA. El caché de mapas base sin conexión nativo (MBTiles/PMTiles incluidos o descargados) es una mejora futura.
- El OAuth de Earth Engine usa un flujo de escritorio de loopback/multi-ventana; una redirección móvil mediante deep-link es trabajo futuro.