Pasos para generar una APK y ABB firmado en modo Release en Flutter mediante VSC para Google Play
- 👤 Andrés Cruz
Cuando llega el momento de llevar una aplicación Flutter a producción en Android, uno de los pasos más importantes (y también más propensos a errores) es generar correctamente un APK o AAB firmado. Google Play exige que cualquier app esté firmada para poder publicarse, y si algo falla en este proceso, la compilación o la subida a la Play Console simplemente no funcionará.
En esta guía te explico paso a paso cómo generar un APK y un AAB firmado en Flutter, usando Visual Studio Code o Android Studio, trabajando en Windows (aunque los pasos aplican igual para macOS y Linux), y además veremos errores reales que suelen aparecer y cómo solucionarlos.
Veremos varios tips, pasos y consideraciones que debes de tener en cuenta cuando quieres generar el release para producción de tu aplicación en Flutter empleando Visual Studio Code; la app/apk en Android que vamos a generar va a estar firmada, que es el requisito por Google para poder cargar tu app en la Google Play Store.
Requisitos previos antes de firmar tu app Flutter
Antes de entrar en comandos y configuraciones, conviene revisar algunos puntos básicos.
Tener Flutter y Android correctamente configurados
Asegúrate de que tu entorno esté bien configurado ejecutando:
$ flutter doctor -vAquí podrás verificar:
- Ruta correcta de Java (JDK)
- Android SDK instalado
- Licencias aceptadas
Diferencia entre clave de carga y clave de firma (Play App Signing)
Google Play usa dos claves:
- Clave de carga: con la que tú subes el AAB o APK.
- Clave de firma de la app: la gestiona Google y es la que reciben los usuarios.
Lo normal (y recomendado) es usar Play App Signing, así no arriesgas la clave final de la app.
Dónde NO guardar el keystore
Nunca subas el archivo .jks a:
- GitHub
- GitLab
- Repositorios públicos o privados
Guárdalo en una ubicación segura y haz copias de respaldo. Si pierdes el keystore, podrías perder la app para siempre.
Crear el keystore (JKS) para firmar tu aplicación Flutter
Estos pasos también los puedes tener en cuenta si empleas Android Studio.
Finalmente, vamos a emplear Windows para realizar estos pasos; esta es la documentación oficial del equipo de Flutter:
https://docs.flutter.dev/deployment/android
Para generar un APK firmado en modo Release para una aplicación Flutter en Android utilizando Visual Studio Code (VSC), debes de seguir estos pasos:
1 Generar el keystore con keytool
- Abre una terminal en VSC.
Ejecuta el siguiente comando para generar una clave (keystore) utilizando
keytool(puedes hacerlo desde cualquier ubicación en tu sistema):keytool -genkey -v -keystore release-key.jks -keyalg RSA -keysize 2048 -validity 10000 -alias key-alias- Sigue las instrucciones para configurar la clave (contraseña, nombre, etc.); es un formulario como el siguiente que debes de llenar con información básica; del comando anterior, puedes personalizar la ubicación del release-key.jks así como el alias key-alias.
C:\Users\andre\flutter
.\keytool.exe -genkey -v -keystore my-release-key.jks -keyalg RSA -keysize 2048 -validity 10000 -alias key-alias
Introduzca la contraseña del almacén de claves:
Volver a escribir la contraseña nueva:
¿Cuáles son su nombre y su apellido?
[Unknown]: Tu Nombre
¿Cuál es el nombre de su unidad de organización?
[Unknown]: TuEmpresa
¿Cuál es el nombre de su organización?
[Unknown]: TuEmpresa
¿Cuál es el nombre de su ciudad o localidad?
[Unknown]: TuCiudad
¿Cuál es el nombre de su estado o provincia?
[Unknown]: TuEstado
¿Cuál es el código de país de dos letras de la unidad?
[Unknown]: (EJ VE)
¿Es correcto CN=andres cruz, OU=desarrollolibre, O=desarrollolibre, L=caracas, ST=distrito capital, C=VE?
[no]: siSi tienes problemas con el comando de keytool ya lo tratamos en el siguiente apartado.
En resumen:
- Durante el proceso se te pedirá:
- Contraseña del almacén
- Alias
Nombre, organización, país, etc.
En Windows, puedes especificar una ruta completa si tienes problemas de permisos:
keytool -genkey -v -keystore C:\Users\tu_usuario\release-key.jks -keyalg RSA -keysize 2048 -validity 10000 -alias key-alias2 Crear el archivo key.properties
- En la carpeta
androidde tu proyecto Flutter, crea un archivo llamadokey.properties. Agrega la siguiente información al archivo:
storePassword=your_keystore_password keyPassword=your_key_password keyAlias=my-key-alias storeFile=release-key.jks
- ⚠️ En Windows, recuerda usar doble barra invertida \\.
3 Modificar el archivo build.gradle
- Abre el archivo
android/app/build.gradle. Agrega la siguiente configuración, los que tienen el simbolo de + son los que debes de agregar
+ def keystoreProperties = new Properties() + def keystorePropertiesFile = rootProject.file('key.properties') + if (keystorePropertiesFile.exists()) { + keystoreProperties.load(new FileInputStream(keystorePropertiesFile)) + } + android { ... } + signingConfigs { + release { + keyAlias keystoreProperties['keyAlias'] + keyPassword keystoreProperties['keyPassword'] + storeFile keystoreProperties['storeFile'] ? file(keystoreProperties['storeFile']) : null + storePassword keystoreProperties['storePassword'] + } + } buildTypes { release { // TODO: Add your own signing config for the release build. // Signing with the debug keys for now, // so `flutter run --release` works. - signingConfig signingConfigs.debug + signingConfig signingConfigs.release } }
En resumen, estamos agregando a nivel de código que empleará el compilador cuales son las los parámetros en base al keystore generado anteriormente para que genere nuestra app firmada.
Error común: alias no encontrado en el keystore
Error típico:
No key with alias 'upload' found in keystoreEsto significa que:
- El keyAlias en key.properties
- No coincide con el alias usado al generar el keystore
Revísalo cuidadosamente. Es uno de los errores más comunes.
4 Generar el APK firmado
Finalmente, ejecutamos el comando para generar la app firmada en formato apk:
flutter build apk- o en abb:
flutter build appbundle- El archivo APK firmado (
app-release.apk) se generará en la carpetabuild/app/outputs/apkde tu proyecto de Flutter y este es el que debes de subir a la Google Play, antes de subir, te recomiendo que instales la apk en un dispositivo físico, para eso, lo copias en el dispositivo Android y sigues los pasos de instalación.
No compartas públicamente el archivo del keystore (
release-key.jks). Guárdalo de forma segura.
Listo! Ahora tienes un APK firmado en modo Release para tu aplicación Flutter en Android.
Problemas habituales con keytool y cómo solucionarlos
❌ keytool no se reconoce como comando
Esto pasa porque keytool no está en el PATH. La solución rápida:
Ejecuta:
flutter doctor -vBusca la línea:
Java binary at: C:\Program Files\Android\Android Studio\jbr\bin\javaVe a esa carpeta (sin incluir java):
cd "C:\Program Files\Android\Android Studio\jbr\bin"Ejecuta el comando keytool desde ahí.
Problemas al generar la apk firmada
Por supuesto, hay muchas cosas que pueden salir mal al momento de generar tu aplicación firmada, y esto es lo que trataremos a continuación; si al momento de ejecutar el comando de da un error como el siguiente:
Debes de agregar al path de tu sistema la referencia al instalador o simplemente te mueves a la ubicación de la keystore; para esto, primero debemos de ubicar dónde se encuentra el .exe, para eso, podemos emplear el comando de flutter:
flutter doctor -vY buscamos algo como:
cd 'C:\Program Files\Android\Android Studio\jbr\bin\\'
C:\Program Files\Android\Android Studio\jbr\bin\java
Android toolchain - develop for Android devices (Android SDK version 34.0.0)
• Android SDK at C:\Users\andre\AppData\Local\Android\sdk
• Platform android-34, build-tools 34.0.0
• Java binary at: C:\Program Files\Android\Android Studio\jbr\bin\java
• Java version OpenJDK Runtime Environment (build 17.0.10+0--11572160)
• All Android licenses accepted.En donde nos indica donde esta Java:
C:\Program Files\Android\Android Studio\jbr\bin\javaAhora, movemos la terminal hasta esa ubicación sin incluir la carpeta de java (esta misma dirección puedes agregarla al path de tu sistema si así lo deseas):
cd C:\Program Files\Android\Android Studio\jbr\binY ejecutamos:
keytool -genkey -v -keystore release-key.jks -keyalg RSA -keysize 2048 -validity 10000 -alias key-aliasProbablemente te indique que solo es escritura:
error de herramienta de claves: java.io.FileNotFoundException: my-release-key.jks (Acceso denegado)
java.io.FileNotFoundException: my-release-key.jks (Acceso denegado)
at java.base/java.io.FileOutputStream.open0(Native Method)
at java.base/java.io.FileOutputStream.open(FileOutputStream.java:293)
at java.base/java.io.FileOutputStream.<init>(FileOutputStream.java:235)
at java.base/java.io.FileOutputStream.<init>(FileOutputStream.java:123)
at java.base/sun.security.tools.keytool.Main.doCommands(Main.java:1375)
at java.base/sun.security.tools.keytool.Main.run(Main.java:423)
at java.base/sun.security.tools.keytool.Main.main(Main.java:416)Así que, colocas una ubicación distinta para generar el release-key.jks, por ejemplo:
keytool -genkey -v -keystore C:\Users\andres\release-key.jks -keyalg RSA -keysize 2048 -validity 10000 -alias key-aliasY ahora, debería de generar el archivo de manera satisfactoria en la ubicación especificada.
El siguiente paso consiste en generar la apk firmada, antes de eso, deberías de actualizar el namespace de tu app, ya que, no puede decir example como parte del nombre, para ello, puedes emplear el siguiente paquete:
https://pub.dev/packages/change_app_package_name
Hay muchos errores que pueden ocurrir si no estableces correctamente los parámetros en el Android Studio como al momento de ejecutar el proyecto en Android quede en un bucle o que al generar la apk firmada indique pir ejemplo que te equivocates al momento de definir el alias:
e: C:/Users/andre/.gradle/caches/transforms-3/c1e3cec58f97b65c118bb2f68fab94a8/transformed/jetified-core-ktx-1.10.1/jars/classes.jar!/META-INF/core-ktx_release.kotlin_module: Module was compiled with an incompatible version of Kotlin. The binary version of its metadata is 1.8.0, expected version is 1.6.0.
e: C:/Users/andre/.gradle/caches/transforms-3/a3842a17fe7307c5bcdac869078c73a0/transformed/core-1.10.1/jars/classes.jar!/META-INF/core_release.kotlin_module: Module was compiled with an incompatible version of Kotlin. The binary version of its metadata is 1.8.0, expected version is 1.6.0.
e: C:/Users/andre/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-stdlib/1.8.22/636bf8b320e7627482771bbac9ed7246773c02bd/kotlin-stdlib-1.8.22.jar!/META-INF/kotlin-stdlib-jdk7.kotlin_module: Module was compiled with an incompatible version of Kotlin. The binary version of its metadata is 1.8.0, expected version is 1.6.0.
e: C:/Users/andre/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-stdlib/1.8.22/636bf8b320e7627482771bbac9ed7246773c02bd/kotlin-stdlib-1.8.22.jar!/META-INF/kotlin-stdlib.kotlin_module: Module was compiled with an incompatible version of Kotlin. The binary version of its metadata is 1.8.0, expected version is 1.6.0.
e: C:/Users/andre/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-stdlib/1.8.22/636bf8b320e7627482771bbac9ed7246773c02bd/kotlin-stdlib-1.8.22.jar!/META-INF/kotlin-stdlib-jdk8.kotlin_module: Module was compiled with an incompatible version of Kotlin. The binary version of its metadata is 1.8.0, expected version is 1.6.0.
e: C:/Users/andre/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-stdlib-common/1.8.22/1a8e3601703ae14bb58757ea6b2d8e8e5935a586/kotlin-stdlib-common-1.8.22.jar!/META-INF/kotlin-stdlib-common.kotlin_module: Module was compiled with an incompatible version of Kotlin. The binary version of its metadata is 1.8.0, expected version is 1.6.0.
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':app:packageRelease'.
> A failure occurred while executing com.android.build.gradle.tasks.PackageAndroidArtifact$IncrementalSplitterRunnable
> com.android.ide.common.signing.KeytoolException: Failed to read key upload from store "C:\Users\andre\flutter\release-key-flutter.jks": No key with alias 'upload' found in keystore C:\Users\andre\flutter\release-key-flutter.jks
* Try:
> Run with --stacktrace option to get the stack trace.
> Run with --info or --debug option to get more log output.
> Run with --scan to get full insights.
* Get more help at https://help.gradle.org
BUILD FAILED in 11s
Running Gradle task 'assembleRelease'... 12,5sEs decir:
key.properties
storePassword=your_keystore_password
keyPassword=your_key_password
keyAlias=my-key-alias
storeFile=release-key.jksQue obviamente debe de corresponder con el alias especificado al momento de generar el keystore.
App abre pero no carga datos
Otro error común es si la app requiere de conexión a internet para funcionar, en AndroidManifest.xml, debes de dejar los permisos:
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<applicationYa que al abrir la misma, verías que toda la data que se trae de internet no cargaría.
Finalmente, la app se generará en tu proyecto:
C:\Users\andre\OneDrive\Escritorio\proyectos\flutter\desarrollolibre\build\app\outputs\flutter-apkError de versionamiento en la Google Play
En la Google Play, si te da un error como:
You must use a different version code for your APK or your Android App Bundle because code 1 is already assigned to another APK or Android App Bundle.
Debes de cambiar la versión de la app publicada:
pubspec.yaml
***
version: 1.0.4+4APK vs AAB en Flutter: cuál usar y cuándo
Por qué Google Play exige AAB
- Descargas optimizadas
- Menor tamaño
- Mejor distribución por arquitectura
Si publicas en Google Play: usa AAB.
Cuándo sigue teniendo sentido el APK
- Pruebas manuales
- Distribución fuera de Play Store
- AppGallery u otras tiendas
Subir tu AAB firmado a Google Play Console
- Entra a Google Play Console
- Ve a Producción o Pruebas
- Crea un nuevo lanzamiento
- Sube el archivo .aab
- Revisa errores y advertencias
- Envía a revisión
Recomendaciones finales antes de publicar
- Guarda el keystore en un lugar seguro
- Haz backup del .jks
- Prueba siempre en dispositivo real
- Controla bien el versionado
- Usa AAB siempre que sea posible
Preguntas frecuentes sobre APK y AAB en Flutter
- ¿Es obligatorio firmar una app Flutter?
- Sí. Google Play no acepta apps sin firmar.
- ¿Puedo generar el AAB sin Android Studio?
- Sí. Con la línea de comandos (flutter build appbundle) es suficiente.
- ¿Qué pasa si pierdo el keystore?
- Podrías perder la posibilidad de actualizar la app. Por eso es crítico respaldarlo.
- ¿Google Play acepta APK hoy en día?
- Solo en casos muy específicos. Para nuevas apps, AAB es el estándar.
Acepto recibir anuncios de interes sobre este Blog.
Hablaremos sobre muchos pasos importantes al momento de generar una APK y ABB firmado en modo Release en Flutter mediante VSC que no son hablados en la documentación oficial.