Desarrolladores

Compila tú mismo la app de Android

Compila el APK de TRS Launcher desde el código: SDK y NDK de Android, targets de Rust, builds debug y release, tu propia clave de firma y tu propio ID de app.

La app de Android es el mismo proyecto de Tauri 2 que el launcher de escritorio, compilado para Android. Esta página es para quien colabora en el proyecto y para jugadores que quieren compilar e instalar su propio APK. Si solo quieres jugar, usa el APK firmado de nuestra web: mira Android: instalar el APK.

Lo que obtienes: la app completa, con inicio de sesión, instancias, modpacks, social, vestuario y Minecraft: Java Edition a través del motor de juego integrado con controles táctiles. Lo que no obtienes: actualizaciones automáticas. La app consulta nuestro canal oficial de actualizaciones, pero Android solo instala una actualización con el mismo nombre de paquete y la misma clave de firma. Tu build tiene otra clave, así que lo actualizas compilando de nuevo.

Los comandos de esta página son los que usa la CI (.github/workflows/ci.yml y release.yml, jobs Android), más las notas para builds locales de docs/mobile.md en el repositorio. La CI compila en Linux; los builds locales están descritos para Windows. Compilar la app de Android en macOS no está probado.

Qué hay en cada sitio

RutaQué es
src-tauri/gen/android/El proyecto de Gradle de la app (incluido en el repositorio, minSdk 26 = Android 8.0)
src-tauri/gen/android/app/build.gradle.ktsID de la app, niveles de SDK, firma de release
src-tauri/tauri.android.conf.jsonCambios de la configuración de Tauri para Android (sin actualizador de escritorio, sin los jars del TRS Client)
src-tauri/plugins/tauri-plugin-trs-game/android/El motor de juego (partes de Amethyst/PojavLauncher, ndk-build) y la capa táctil
src-tauri/plugins/tauri-plugin-trs-game/android/prebuilt.lockPartes del motor ya compiladas que Gradle descarga y comprueba con SHA-256

Requisitos

HerramientaVersión (como en la CI)
Node.js y pnpmNode 22, pnpm en la versión fijada en package.json (corepack enable)
Ruststable con rustup, targets aarch64-linux-android (móviles) y x86_64-linux-android (emulador)
JDK21 (CI: Temurin; el JBR que trae Android Studio también sirve)
SDK de Androidcon cmdline-tools y platform-tools
NDK de Android28.2.13676358 para la app (NDK_HOME) y 27.3.13750724 (r27d) para el motor de juego
Gradleno hay que instalar nada: el wrapper de src-tauri/gen/android usa Gradle 8.14.3

La app se compila contra el SDK de Android 36 (compileSdk/targetSdk). En la CI solo se instalan a mano platform-tools y los dos NDK; el resto lo trae el plugin de Android para Gradle. Acepta una vez las licencias del SDK con sdkmanager --licenses.

Necesitas los dos NDK. El plugin del juego fija ndkVersion = "27.3.13750724" en su propio build.gradle.kts; la parte de Rust se enlaza con el NDK de NDK_HOME (28.2).

Compilar un APK debug

Descarga el código

git clone https://github.com/theredstonee/TRS-Launcher.git
cd TRS-Launcher
pnpm install

Instala las partes del SDK y los targets de Rust

sdkmanager --install "platform-tools" "ndk;28.2.13676358" "ndk;27.3.13750724"
rustup target add aarch64-linux-android x86_64-linux-android

También puedes instalar las dos versiones del NDK en Android Studio (SDK Manager → SDK Tools → NDK (Side by side), marcando Show Package Details).

Prepara el entorno

En Windows (PowerShell) o Linux:

$env:ANDROID_HOME = "$env:LOCALAPPDATA\Android\Sdk"
$env:NDK_HOME     = "$env:ANDROID_HOME\ndk\28.2.13676358"
$env:JAVA_HOME    = "C:\Program Files\Android\Android Studio\jbr"

En Windows, activa antes el modo de desarrollador: mira Problemas.

Compila

pnpm tauri android build --apk --debug --target aarch64

Esto compila la interfaz (pnpm generate), la biblioteca de Rust para arm64 y luego el APK con Gradle. La primera vez, Gradle descarga las partes del motor de prebuilt.lock (comprobadas con SHA-256 y guardadas en ~/.gradle/caches/trs-engine-prebuilt), así que necesita internet y tarda un rato.

Busca el APK

Los APK quedan en src-tauri/gen/android/app/build/outputs/apk/, en una carpeta por ABI y tipo de build. La CI no depende del nombre exacto de la carpeta, y tú tampoco tienes que hacerlo:

find src-tauri/gen/android/app/build/outputs/apk -name '*.apk'

Instálalo en tu móvil

Activa la depuración USB en las opciones de desarrollador del móvil, conéctalo y ejecuta:

adb install -r ruta/al.apk

O copia el APK al móvil y ábrelo allí, como se explica en Android: instalar el APK. Un APK debug está firmado con la clave debug de tu SDK de Android, así que se instala sin más.

Un build debug y nuestra app oficial tienen el mismo nombre de paquete, pero claves distintas. Android no instala uno encima del otro («App no instalada» / «entra en conflicto con un paquete existente»). Desinstala antes el otro (eso borra también sus instancias y mundos) o dale a tu build su propio ID de app (mira más abajo).

Para el emulador

pnpm tauri android build --apk --debug --target x86_64

Arranca el emulador con -gpu host: con SwiftShader el renderizador se cuelga en su comprobación de Vulkan. Minecraft 26.x no se puede jugar en el emulador (a su Vulkan le faltan extensiones necesarias y OpenGL se bloquea allí); prueba esas versiones en un móvil real.

Compilar un APK release

pnpm tauri android build --apk --target aarch64

Es el comando de release de la CI sin --ci. Los builds release se reducen con R8. Sin clave de firma sale un APK sin firmar (…-unsigned.apk), y Android no lo puede instalar. Fírmalo con tu propia clave:

Crea un keystore una vez

keytool -genkeypair -v -keystore my-release.jks -alias my-key \
  -keyalg RSA -keysize 4096 -validity 10000

keytool viene con el JDK. Guarda bien el archivo y las contraseñas: Android solo instala actualizaciones de una app si están firmadas con la misma clave.

Define las cuatro variables

Gradle firma el APK release por sí mismo (signingConfigs en src-tauri/gen/android/app/build.gradle.kts) cuando ANDROID_KEYSTORE_PATH apunta a un archivo que existe:

export ANDROID_KEYSTORE_PATH=/ruta/a/my-release.jks
export ANDROID_KEYSTORE_PASSWORD='…'
export ANDROID_KEY_ALIAS=my-key
export ANDROID_KEY_PASSWORD='…'      # igual que la del keystore si no elegiste otra

En Windows se definen como arriba, con $env:NOMBRE = "…".

Compila y comprueba

pnpm tauri android build --apk --target aarch64
"$ANDROID_HOME"/build-tools/<versión>/apksigner verify --print-certs <el.apk>

apksigner muestra el SHA-256 de tu certificado, no el de la página de instalación, que es el de nuestra clave oficial.

No necesitas ningún secreto del proyecto. La clave del actualizador de escritorio (TAURI_SIGNING_PRIVATE_KEY) solo firma los archivos del canal de actualizaciones en el workflow de release, y los builds de Android no generan archivos de actualización (tauri.android.conf.json). La clave de CurseForge es opcional, igual que en escritorio: la variable de entorno CURSEFORGE_API_KEY o el archivo ~/.tauri/curseforge-api-key (%USERPROFILE%\.tauri\curseforge-api-key en Windows). Sin ella el build funciona y CurseForge simplemente se oculta.

Hazla tu propia app

Si quieres instalar tu build junto a la app oficial o compartirlo con amigos, dale su propio ID de app y su propio nombre:

QuéDóndeCambio
ID de la app (nombre de paquete)src-tauri/gen/android/app/build.gradle.ktsapplicationId = "dev.theredstonee.trslauncher" → por ejemplo "io.github.tunombre.trslauncher"
Nombre en la pantalla de iniciosrc-tauri/gen/android/app/src/main/res/values/strings.xmlapp_name y main_activity_title
Iconosrc-tauri/gen/android/app/src/main/res/mipmap-*/ic_launcher*.png (los archivos ic_launcher_halloween* son el icono de evento)
Clave de firmatu propio keystoremira arriba
Cambia solo applicationId, no namespace en el mismo archivo ni identifier en src-tauri/tauri.conf.json. El paquete de Kotlin dev.theredstonee.trslauncher está fijado en el código de Rust (register_android_plugin en src-tauri/src/mobile.rs, la función JNI Java_dev_theredstonee_trslauncher_PushPollWorker_nativePoll en src-tauri/src/push.rs), y la CLI de Tauri detiene el build con «you have modified your "identifier" in the Tauri configuration» si el identificador ya no coincide con la carpeta de Kotlin. Los plugins del motor y de notificaciones leen el nombre de paquete en tiempo de ejecución, así que un applicationId nuevo no les afecta.

Lo que sigue funcionando en tu propio build, según el código:

  • Inicio de sesión con Microsoft: la app usa el inicio de sesión con código de dispositivo (escribes un código en la página de Microsoft). No depende del nombre de paquete ni de una redirección a la app.
  • Servicios de TRS (amigos, chat, capas, API de TRS): la app habla con la misma API; no se comprueba ni el nombre de paquete ni la firma.
  • Enlaces como trs-launcher://pack/<code> usan el mismo esquema en todos los builds. Si tienes la app oficial y tu build instalados a la vez, Android te pregunta con cuál abrirlos.
  • Actualizaciones: mira el principio de la página. El instalador de la app solo acepta un APK con su propio nombre de paquete, así que no puede sustituir tu build por la app oficial, y Android rechaza nuestro APK encima de un build con tu clave.

Nosotros todavía no hemos probado un build con otro nombre; si algo falla, avísanos.

Ejecutar las comprobaciones

Las mismas comprobaciones que el job Android de la CI:

pnpm generate                       # generate_context! necesita la interfaz compilada
cd src-tauri
cargo clippy --workspace --target aarch64-linux-android -- -D warnings
cd gen/android
./gradlew --no-daemon :tauri-plugin-trs-game:testDebugUnitTest   # capa táctil y lógica del motor, sin dispositivo

Clippy se ejecuta fuera de tauri android build y necesita el compilador del NDK para las partes en C (SQLite, ring). La CI define en Linux:

bin="$NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin"
export CC_aarch64_linux_android="$bin/aarch64-linux-android26-clang"
export AR_aarch64_linux_android="$bin/llvm-ar"
export CARGO_TARGET_AARCH64_LINUX_ANDROID_LINKER="$bin/aarch64-linux-android26-clang"

Problemas

«A required privilege is not held by the client»

En Windows, tauri android build enlaza la biblioteca de Rust en gen/android/app/src/main/jniLibs con un enlace simbólico. Sin el modo de desarrollador (o permisos de administrador) eso falla. Activa el modo de desarrollador en la configuración de Windows, o copia tú la biblioteca (src-tauri/target/<triple>/debug/libtrs_launcher_lib.so → jniLibs/<abi>/) y ejecuta la tarea de Gradle en src-tauri/gen/android; para el emulador, gradlew assembleX86_64Debug.

No encuentra el NDK o la versión del NDK es otra

NDK_HOME tiene que apuntar a 28.2.13676358, y 27.3.13750724 también tiene que estar en la carpeta ndk/ del SDK. Si tu r27d está en otro sitio, define android.ndkPath en src-tauri/gen/android/local.properties o la variable ANDROID_NDK_HOME (mira el comentario en el build.gradle.kts del plugin).

La instalación del SDK pide el paquete «tools»

El antiguo paquete tools del SDK ya no existe con las cmdline-tools actuales. Instala solo cmdline-tools, platform-tools y los dos NDK; la CI hace lo mismo.

El APK release no se instala

Está sin firmar (…-unsigned.apk). Define las cuatro variables de firma y vuelve a compilar, o usa un build debug.

«App no instalada» o «entra en conflicto con un paquete existente»

Ya hay instalado un build de la app con otra clave, a menudo nuestra app oficial. Desinstálalo antes (eso borra sus instancias) o dale a tu build su propio ID de app.

«SHA-256 stimmt nicht» al descargar las partes del motor

Una descarga de prebuilt.lock no coincide con su suma de comprobación (por ejemplo, por una conexión cortada o un proxy). El archivo se descarta; vuelve a lanzar el build.

El juego se cierra en el emulador o 26.x no arranca allí

Usa -gpu host y prueba Minecraft 26.x en un móvil real (mira Para el emulador).

La app no se instala en un móvil antiguo o de 32 bits

La app necesita Android 8.0 y un procesador de 64 bits: solo se empaquetan arm64-v8a y x86_64, porque el motor de juego solo existe para 64 bits.

Falta CurseForge

El build no tenía clave de API de CurseForge. En builds propios es normal; mira la nota sobre la clave más arriba.

Licencia y nombre

TRS Launcher es software libre bajo la GNU General Public License v3.0 (LICENSE, avisos de copyright en NOTICE). Puedes compilar, cambiar y compartir la app. Si compartes un APK, la GPL exige que sea bajo la misma licencia y que pongas a disposición el código fuente completo de ese build exacto, con tus cambios. El motor de juego incluye partes de terceros con sus propias licencias (Amethyst/PojavLauncher bajo LGPL-3.0 y otras); están en NOTICE y tienen que quedarse.

El repositorio no tiene reglas propias sobre la marca. Aun así: si repartes tu propio build, dale otro nombre y otro ID de app para que nadie lo confunda con el TRS Launcher oficial, y remite a tu código fuente, no a nuestro soporte.

Siguientes pasos

Compila tú mismo la app de iOS

Lo mismo para iPhone y iPad; necesitas un Mac con Xcode.

Compilar desde el código

El launcher de escritorio, las comprobaciones y el mod TRS Client.