Publicación de una aplicación Android con la línea de comandos

Para distribuir una aplicación .NET Multi-platform App UI (.NET MAUI) de Android, deberás firmarla con una clave del almacén de claves. Un almacén de claves es una base de datos de certificados de seguridad que se crea con keytool del kit de desarrollo de Java (JDK). Se requiere un almacén de claves al publicar una aplicación .NET MAUI para Android, ya que Android no ejecuta aplicaciones que no se hayan firmado.

Creación de un almacén de claves

Durante el desarrollo, .NET para Android usa un almacén de claves de depuración para firmar la aplicación, lo que permite implementarla directamente en un emulador o en dispositivos configurados para ejecutar aplicaciones depurables. Sin embargo, este almacén de claves no se reconoce como un almacén de claves válido para la distribución de aplicaciones. Por lo tanto, se debe crear un almacén de claves privado y usarlo para firmar compilaciones de versión. Este es un paso que solo debe realizarse una vez, dado que la misma clave se usará para publicar actualizaciones y puede usarse para firmar otras aplicaciones. Después de generar un archivo de almacén de claves, deberás proporcionar sus detalles desde la línea de comandos al compilar la aplicación o configurar el archivo de proyecto para hacer referencia a él.

Realiza los siguientes pasos para crear un almacén de claves:

  1. Abre un terminal y navega hasta la carpeta de tu proyecto.

    Sugerencia

    Si Visual Studio está abierto, usa el menú Vista>Terminal para abrir un terminal en la ubicación de la solución o proyecto. Vaya a la carpeta del proyecto.

  2. Ejecuta la herramienta keytool con los siguientes parámetros:

    keytool -genkeypair -v -keystore {filename}.keystore -alias {keyname} -keyalg RSA -keysize 2048 -validity 10000
    

    Importante

    Si tienes varias versiones del JDK instaladas en tu equipo, asegúrate de ejecutar keytool desde la última versión del JDK.

    Se te pedirá que proporciones y confirmes una contraseña, seguida de tu nombre completo, unidad organizativa, organización, ciudad o localidad, estado o provincia y código de país. Esta información no se muestra en la aplicación, pero se incluye en tu certificado.

    Por ejemplo, para generar un archivo myapp.keystore en la misma carpeta que tu proyecto, con un alias de myapp, usa el siguiente comando:

    keytool -genkeypair -v -keystore myapp.keystore -alias myapp -keyalg RSA -keysize 2048 -validity 10000
    

    Sugerencia

    Haz una copia de seguridad de tu almacén de claves y contraseña. Si lo pierdes, no podrás firmar la aplicación con la misma identidad de firma.

Búsqueda de la firma de tu almacén de claves

Para enumerar las claves que se almacenan en un almacén de claves, usa keytool con la opción -list:

keytool -list -keystore {filename}.keystore

Por ejemplo, para enumerar las claves de un almacén de claves denominado myapp.keystore, usa el siguiente comando:

keytool -list -keystore myapp.keystore

Compilación y firma de tu aplicación

Para compilar la aplicación desde la línea de comandos y firmarla con el almacén de claves, abre un terminal y ve a la carpeta de tu proyecto de aplicación de .NET MAUI. Ejecuta el comando dotnet publish, proporcionando los siguientes parámetros:

Parámetro Valor
-f o --framework .NET Framework de destino, que es net8.0-android.
-c o --configuration La configuración de compilación, que es Release.

Advertencia

El intento de publicar una solución de .NET MAUI tendrá como resultado que el comando dotnet publish intente publicar cada proyecto de la solución de forma individual, lo que puede causar problemas cuando hayas agregado otros tipos de proyecto a tu solución. Por lo tanto, el comando dotnet publish debe tener como ámbito tu proyecto de aplicación de .NET MAUI.

Se pueden especificar parámetros de compilación adicionales en la línea de comandos, si no se proporcionan en <PropertyGroup> en tu archivo de proyecto. En la tabla siguiente se enumeran algunos de los parámetros comunes:

Parámetro Valor
-p:ApplicationTitle El nombre visible del usuario para la aplicación.
-p:ApplicationId El identificador único de la aplicación, como com.companyname.mymauiapp.
-p:ApplicationVersion La versión de la compilación que identifica una iteración de la aplicación.
-p:ApplicationDisplayVersion El número de versión de la aplicación.
-p:AndroidKeyStore Un valor booleano que indica si la aplicación debe estar firmada. El valor predeterminado es false.
-p:AndroidPackageFormats Propiedad delimitada por punto y coma que indica si quieres empaquetar la aplicación como un archivo APK o AAB. Se establece en aab o apk para generar solo un formato. El valor predeterminado para las compilaciones de versión es aab;apk.
-p:AndroidSigningKeyAlias Especifica el alias de la clave en el almacén de claves. Es el valor keytool -alias usado al crear el almacén de claves.
-p:AndroidSigningKeyPass Especifica la contraseña de la clave en el archivo de almacén de claves. Es el valor proporcionado a keytool al crear el archivo de almacén de claves y cuando se pide que se escriba la contraseña del almacén de claves. Esto se debe a que el tipo de almacén de claves predeterminado supone que la contraseña de clave y la contraseña del almacén de claves son idénticas. Esta propiedad también admite los prefijos env: y file: que se pueden usar para especificar una variable de entorno o un archivo que contiene la contraseña. Estas opciones proporcionan una manera de evitar que la contraseña aparezca en los registros de compilación.
-p:AndroidSigningKeyStore El nombre del archivo del archivo de almacén de claves que crea keytool. Es el valor keytool -keystore usado al crear el almacén de claves.
-p:AndroidSigningStorePass La contraseña para el archivo de almacén de claves. Es el valor proporcionado a keytool al crear el archivo de almacén de claves y cuando se pide que se escriba la contraseña del almacén de claves. Esto se debe a que el tipo de almacén de claves predeterminado supone que la contraseña del almacén de claves y la contraseña de clave son idénticas. Esta propiedad también admite los prefijos env: y file: que se pueden usar para especificar una variable de entorno o un archivo que contiene la contraseña. Estas opciones proporcionan una manera de evitar que la contraseña aparezca en los registros de compilación.
-p:PublishTrimmed Un valor booleano que indica si se debe recortar la aplicación. El valor predeterminado es true para las compilaciones de versión.

Debes usar la misma contraseña que los valores de los parámetros AndroidSigningKeyPass y AndroidSigningStorePass.

Para obtener una lista completa de propiedades de compilación, consulta Propiedades de compilación.

Importante

Los valores de estos parámetros no tienen que proporcionarse en la línea de comandos. También se pueden proporcionar en el archivo del proyecto. Cuando se proporciona un parámetro en la línea de comandos y en el archivo del proyecto, el parámetro de línea de comandos tiene prioridad. Para obtener más información sobre cómo proporcionar propiedades de compilación en el archivo de proyecto, consulta Definición de propiedades de compilación en el archivo de proyecto.

Ejecuta el comando dotnet publish con los siguientes parámetros para compilar y firmar la aplicación:

dotnet publish -f net8.0-android -c Release -p:AndroidKeyStore=true -p:AndroidSigningKeyStore={filename}.keystore -p:AndroidSigningKeyAlias={keyname} -p:AndroidSigningKeyPass={password} -p:AndroidSigningStorePass={password}

Nota:

En .NET 8, el comando dotnet publish tiene como valor predeterminado la configuración Release. Por lo tanto, la configuración de compilación se puede omitir desde la línea de comandos.

Por ejemplo, usa el siguiente comando para compilar y firmar la aplicación mediante el almacén de claves creado anteriormente:

dotnet publish -f net8.0-android -c Release -p:AndroidKeyStore=true -p:AndroidSigningKeyStore=myapp.keystore -p:AndroidSigningKeyAlias=myapp -p:AndroidSigningKeyPass=mypassword -p:AndroidSigningStorePass=mypassword

Las propiedades AndroidSigningKeyPass y AndroidSigningStorePass admiten los prefijos env: y file: que se pueden usar para especificar una variable de entorno o un archivo que contiene la contraseña. Especificar la contraseña de esta manera impide que aparezca en los registros de compilación. Por ejemplo, para usar una variable de entorno denominada AndroidSigningPassword:

dotnet publish -f net8.0-android -c Release -p:AndroidKeyStore=true -p:AndroidSigningKeyStore=myapp.keystore -p:AndroidSigningKeyAlias=myapp -p:AndroidSigningKeyPass=env:AndroidSigningPassword -p:AndroidSigningStorePass=env:AndroidSigningPassword

Importante

El prefijo env: no se admite cuando $(AndroidPackageFormat) está establecido en aab.

Para usar un archivo ubicado en C:\Users\user1\AndroidSigningPassword.txt:

dotnet publish -f net8.0-android -c Release -p:AndroidKeyStore=true -p:AndroidSigningKeyStore=myapp.keystore -p:AndroidSigningKeyAlias=myapp -p:AndroidSigningKeyPass=file:C:\Users\user1\AndroidSigningPassword.txt -p:AndroidSigningStorePass=file:C:\Users\user1\AndroidSigningPassword.txt

La publicación compila y firma la aplicación y, después, copia los archivos AAB y APK en la carpeta bin\Release\net8.0-android\publish. Hay dos archivos AAB: uno sin firmar y otro firmado. La variante firmada tiene -signed en el nombre de archivo.

Para obtener más información sobre el comando dotnet publish, consulta Dotnet publish.

Nota:

En el caso de las aplicaciones Android, dotnet build también se puede usar para compilar y firmar la aplicación. Sin embargo, los archivos AAB y APK se crearán en la carpeta bin\Release\net8.0-android en lugar de en la subcarpeta publish. dotnet build también tiene como valor predeterminado una configuración Debug, por lo que el parámetro -c es necesario para especificar la configuración Release.

Definición de propiedades de compilación en el archivo de proyecto

Una alternativa a especificar parámetros de compilación en la línea de comandos es especificarlos en el archivo del proyecto en <PropertyGroup>. En la tabla siguiente se enumeran algunas de las propiedades de compilación comunes:

Propiedad Valor
<ApplicationTitle> El nombre visible del usuario para la aplicación.
<ApplicationId> El identificador único de la aplicación, como com.companyname.mymauiapp.
<ApplicationVersion> La versión de la compilación que identifica una iteración de la aplicación.
<ApplicationDisplayVersion> El número de versión de la aplicación.
<AndroidKeyStore> Un valor booleano que indica si la aplicación debe estar firmada. El valor predeterminado es false.
<AndroidPackageFormats> Propiedad delimitada por punto y coma que indica si quieres empaquetar la aplicación como un archivo APK o AAB. Se establece en aab o apk para generar solo un formato. El valor predeterminado para las compilaciones de versión es aab;apk.
<AndroidSigningKeyAlias> Especifica el alias de la clave en el almacén de claves. Es el valor keytool -alias usado al crear el almacén de claves.
<AndroidSigningKeyPass> Especifica la contraseña de la clave en el archivo de almacén de claves. Es el valor proporcionado a keytool al crear el archivo de almacén de claves y cuando se pide que se escriba la contraseña del almacén de claves. Esto se debe a que el tipo de almacén de claves predeterminado supone que la contraseña de clave y la contraseña del almacén de claves son idénticas. Esta propiedad también admite los prefijos env: y file: que se pueden usar para especificar una variable de entorno o un archivo que contiene la contraseña. Estas opciones proporcionan una manera de evitar que la contraseña aparezca en los registros de compilación.
<AndroidSigningKeyStore> El nombre del archivo del archivo de almacén de claves que crea keytool. Es el valor keytool -keystore usado al crear el almacén de claves.
<AndroidSigningStorePass> La contraseña para el archivo de almacén de claves. Es el valor proporcionado a keytool al crear el archivo de almacén de claves y cuando se pide que se escriba la contraseña del almacén de claves. Esto se debe a que el tipo de almacén de claves predeterminado supone que la contraseña del almacén de claves y la contraseña de clave son idénticas. Esta propiedad también admite los prefijos env: y file: que se pueden usar para especificar una variable de entorno o un archivo que contiene la contraseña. Estas opciones proporcionan una manera de evitar que la contraseña aparezca en los registros de compilación.
<PublishTrimmed> Un valor booleano que indica si se debe recortar la aplicación. El valor predeterminado es true para las compilaciones de versión.

Para obtener una lista completa de propiedades de compilación, consulta Propiedades de compilación.

Importante

Los valores de estas propiedades de compilación no tienen que proporcionarse en el archivo del proyecto. También se pueden proporcionar en la línea de comandos al publicar la aplicación. Esto te permite omitir valores específicos del archivo de proyecto.

En el ejemplo siguiente se muestra un grupo de propiedades típico para compilar y firmar la aplicación Android:

<PropertyGroup Condition="$(TargetFramework.Contains('-android')) and '$(Configuration)' == 'Release'">
    <AndroidSigningKeyStore>myapp.keystore</AndroidSigningKeyStore>
    <AndroidSigningKeyAlias>myapp</AndroidSigningKeyAlias>
</PropertyGroup>

En este ejemplo <PropertyGroup> agrega una comprobación de condición, lo que impide que se procesen esas configuraciones a menos que se supere la comprobación de condición. La comprobación de condición busca dos cosas:

  1. El marco de destino se establece en algo que contiene el texto -android.
  2. La configuración de compilación se establece en Release.

Si se produce un error en cualquiera de esas condiciones, la configuración no se procesa. Lo más importante es que la configuraciones <AndroidSigningKeyStore> y <AndroidSigningKeyAlias> no estén establecidas, lo que impide que la aplicación se firme.

Por motivos de seguridad, no debes proporcionar un valor para <AndroidSigningKeyPass> y <AndroidSigningStorePass> en el archivo del proyecto. Puedes proporcionar estos valores en la línea de comandos al publicar la aplicación o usar los prefijos env: o file: para evitar que la contraseña aparezca en los registros de compilación. Por ejemplo, para usar una variable de entorno denominada AndroidSigningPassword:

<PropertyGroup Condition="$(TargetFramework.Contains('-android')) and '$(Configuration)' == 'Release'">
    <AndroidSigningKeyStore>myapp.keystore</AndroidSigningKeyStore>
    <AndroidSigningKeyAlias>myapp</AndroidSigningKeyAlias>
    <AndroidSigningKeyPass>env:AndroidSigningPassword</AndroidSigningKeyPass>
    <AndroidSigningStorePass>env:AndroidSigningPassword</AndroidSigningStorePass>
</PropertyGroup>

Importante

El prefijo env: no se admite cuando $(AndroidPackageFormat) está establecido en aab.

Como alternativa, para usar un archivo ubicado en C:\Users\user1\AndroidSigningPassword.txt:

<PropertyGroup Condition="$(TargetFramework.Contains('-android')) and '$(Configuration)' == 'Release'">
    <AndroidSigningKeyStore>myapp.keystore</AndroidSigningKeyStore>
    <AndroidSigningKeyAlias>key</AndroidSigningKeyAlias>
    <AndroidSigningKeyPass>file:C:\Users\user1\AndroidSigningPassword.txt</AndroidSigningKeyPass>
    <AndroidSigningStorePass>file:C:\Users\user1\AndroidSigningPassword.txt</AndroidSigningStorePass>
</PropertyGroup>

Distribuir la aplicación

El archivo APK o AAB firmado se puede distribuir con uno de los enfoques siguientes:

  • El enfoque más común para distribuir aplicaciones Android a los usuarios es a través de Google Play. Google Play requiere que envíes tu aplicación como un Android App Bundle (AAB). Para obtener más información, consulta Upload your app to the Play Console en developer.android.com
  • Los archivos APK se pueden distribuir a dispositivos Android a través de un sitio web o servidor. Cuando los usuarios navegan hasta un vínculo de descarga desde su dispositivo Android, se descarga el archivo. Android inicia automáticamente la instalación en el dispositivo, si el usuario ha configurado sus configuraciones para permitir la instalación de aplicaciones desde orígenes desconocidos. Para obtener más información sobre cómo permitir aplicaciones de orígenes desconocidos, consulta Aceptación de los usuarios para aplicaciones y fuentes desconocidas en developer.android.com.

Consulte también