Events
Mar 17, 11 PM - Mar 21, 11 PM
Join the meetup series to build scalable AI solutions based on real-world use cases with fellow developers and experts.
Register nowThis browser is no longer supported.
Upgrade to Microsoft Edge to take advantage of the latest features, security updates, and technical support.
To distribute a .NET Multi-platform App UI (.NET MAUI) Android app, you'll need to sign it with a key from your keystore. A keystore is a database of security certificates that's created by using keytool
from the Java Development Kit (JDK). A keystore is required when publishing a .NET MAUI Android app, as Android won't run apps that haven't been signed.
During development, .NET for Android uses a debug keystore to sign the app, which allows it to be deployed directly to an emulator or to devices configured to run debuggable apps. However, this keystore isn't recognized as a valid keystore for the purposes of distributing apps. Therefore, a private keystore must be created and used for signing release builds. This is a step that should only be performed once, as the same key will be used for publishing updates and can be used to sign other apps. After generating a keystore file, you'll supply its details from the command line when building the app, or configure your project file to reference it.
Perform the following steps to create a keystore file:
Open a terminal and navigate to the folder of your project.
Tip
If Visual Studio is open, use the View > Terminal menu to open a terminal at the location of the solution or project. Navigate to the project folder.
Run the keytool tool with the following parameters:
keytool -genkeypair -v -keystore {filename}.keystore -alias {keyname} -keyalg RSA -keysize 2048 -validity 10000
Important
If you have multiple versions of the JDK installed on your computer, ensure that you run keytool
from the latest version of the JDK.
You'll be prompted to provide and confirm a password, followed by your full name, organization unit, organization, city or locality, state or province, and country code. This information isn't displayed in your app, but is included in your certificate.
For example, to generate a myapp.keystore file in the same folder as your project, with an alias of myapp
, use the following command:
keytool -genkeypair -v -keystore myapp.keystore -alias myapp -keyalg RSA -keysize 2048 -validity 10000
Tip
Backup your keystore and password. If you lose it you'll be unable to sign your app with the same signing identity.
To list the keys that are stored in a keystore, use keytool
with the -list
option:
keytool -list -keystore {filename}.keystore
For example, to list the keys in a keystore named myapp.keystore, use the following command:
keytool -list -keystore myapp.keystore
To build your app from the command line, and sign it using your keystore, open a terminal and navigate to the folder for your .NET MAUI app project. Run the dotnet publish
command, providing the following parameters:
Parameter | Value |
---|---|
-f or --framework |
The target framework, which is net8.0-android . |
-c or --configuration |
The build configuration, which is Release . |
Warning
Attempting to publish a .NET MAUI solution will result in the dotnet publish
command attempting to publish each project in the solution individually, which can cause issues when you've added other project types to your solution. Therefore, the dotnet publish
command should be scoped to your .NET MAUI app project.
Additional build parameters can be specified on the command line, if they aren't provided in a <PropertyGroup>
in your project file. The following table lists some of the common parameters:
Parameter | Value |
---|---|
-p:ApplicationTitle |
The user-visible name for the app. |
-p:ApplicationId |
The unique identifier for the app, such as com.companyname.mymauiapp . |
-p:ApplicationVersion |
The version of the build that identifies an iteration of the app. |
-p:ApplicationDisplayVersion |
The version number of the app. |
-p:AndroidKeyStore |
A boolean value that indicates whether the app should be signed. The default value is false . |
-p:AndroidPackageFormats |
A semi-colon delimited property that indicates if you want to package the app as an APK file or AAB. Set to either aab or apk to generate only one format. The default value for release builds is aab;apk . |
-p:AndroidSigningKeyAlias |
The alias for the key in the keystore. This is the keytool -alias value used when creating the keystore. |
-p:AndroidSigningKeyPass |
The password of the key within the keystore file. This is the value provided to keytool when creating the keystore file and you're asked to enter the keystore password. This is because the default keystore type assumes that the key password and keystore password are identical. This property also supports env: and file: prefixes that can be used to specify an environment variable or file that contains the password. These options provide a way to prevent the password from appearing in build logs. |
-p:AndroidSigningKeyStore |
The filename of the keystore file created by keytool . This is the keytool -keystore value used when creating the keystore. |
-p:AndroidSigningStorePass |
The password for the keystore file. This is the value provided to keytool when creating the keystore file and you're asked to enter the keystore password. This is because the default keystore type assumes that the keystore password and key password are identical. This property also supports env: and file: prefixes that can be used to specify an environment variable or file that contains the password. These options provide a way to prevent the password from appearing in build logs. |
-p:PublishTrimmed |
A boolean value that indicates whether the app should be trimmed. The default value is true for release builds. |
You should use the same password as the values of the AndroidSigningKeyPass
and AndroidSigningStorePass
parameters.
For a full list of build properties, see Build properties.
Important
Values for these parameters don't have to be provided on the command line. They can also be provided in the project file. When a parameter is provided on the command line and in the project file, the command line parameter takes precedence. For more information about providing build properties in your project file, see Define build properties in your project file.
Run the dotnet publish
command with the following parameters to build and sign your app:
dotnet publish -f net8.0-android -c Release -p:AndroidKeyStore=true -p:AndroidSigningKeyStore={filename}.keystore -p:AndroidSigningKeyAlias={keyname} -p:AndroidSigningKeyPass={password} -p:AndroidSigningStorePass={password}
Note
In .NET 8, the dotnet publish
command defaults to the Release
configuration. Therefore, the build configuration can be omitted from the command line.
For example, use the following command to build and sign your app using the previously created keystore:
dotnet publish -f net8.0-android -c Release -p:AndroidKeyStore=true -p:AndroidSigningKeyStore=myapp.keystore -p:AndroidSigningKeyAlias=myapp -p:AndroidSigningKeyPass=mypassword -p:AndroidSigningStorePass=mypassword
Both the AndroidSigningKeyPass
and AndroidSigningStorePass
properties support env:
and file:
prefixes that can be used to specify an environment variable or file that contains the password. Specifying the password in this way prevents it from appearing in build logs. For example, to use an environment variable named 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
Important
The env: prefix isn't supported when $(AndroidPackageFormat)
is set to aab
.
To use a file located at 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
Publishing builds and signs the app, and then copies the AAB and APK files to the bin\Release\net8.0-android\publish folder. There are two AAB files - one unsigned and another signed. The signed variant has -signed in the file name.
For more information about the dotnet publish
command, see dotnet publish.
Note
For Android apps, dotnet build
can also be used to build and sign your app. However, AAB and APK files will be created in the bin\Release\net8.0-android folder rather than the publish subfolder. dotnet build
also defaults to a Debug
configuration, so the -c
parameter is required to specify the Release
configuration.
An alternative to specifying build parameters on the command line is to specify them in your project file in a <PropertyGroup>
. The following table lists some of the common build properties:
Property | Value |
---|---|
<ApplicationTitle> |
The user-visible name for the app. |
<ApplicationId> |
The unique identifier for the app, such as com.companyname.mymauiapp . |
<ApplicationVersion> |
The version of the build that identifies an iteration of the app. |
<ApplicationDisplayVersion> |
The version number of the app. |
<AndroidKeyStore> |
A boolean value that indicates whether the app should be signed. The default value is false . |
<AndroidPackageFormats> |
A semi-colon delimited property that indicates if you want to package the app as an APK file or AAB. Set to either aab or apk to generate only one format. The default value for release builds is aab;apk . |
<AndroidSigningKeyAlias> |
The alias for the key in the keystore. This is the keytool -alias value used when creating the keystore. |
<AndroidSigningKeyPass> |
The password of the key within the keystore file. This is the value provided to keytool when creating the keystore file and you're asked to enter the keystore password. This is because the default keystore type assumes that the key password and keystore password are identical. This property also supports env: and file: prefixes that can be used to specify an environment variable or file that contains the password. These options provide a way to prevent the password from appearing in build logs. |
<AndroidSigningKeyStore> |
The filename of the keystore file created by keytool . This is the keytool -keystore value used when creating the keystore. |
<AndroidSigningStorePass> |
The password for the keystore file. This is the value provided to keytool when creating the keystore file and you're asked to enter the keystore password. This is because the default keystore type assumes that the keystore password and key password are identical. This property also supports env: and file: prefixes that can be used to specify an environment variable or file that contains the password. These options provide a way to prevent the password from appearing in build logs. |
<PublishTrimmed> |
A boolean value that indicates whether the app should be trimmed. The default value is true for release builds. |
For a full list of build properties, see Build properties.
Important
Values for these build properties don't have to be provided in the project file. They can also be provided on the command line when you publish the app. This enables you to omit specific values from your project file.
The following example shows a typical property group for building and signing your Android app:
<PropertyGroup Condition="$(TargetFramework.Contains('-android')) and '$(Configuration)' == 'Release'">
<AndroidSigningKeyStore>myapp.keystore</AndroidSigningKeyStore>
<AndroidSigningKeyAlias>myapp</AndroidSigningKeyAlias>
</PropertyGroup>
This example <PropertyGroup>
adds a condition check, preventing those settings from being processed unless the condition check passes. The condition check looks for two things:
-android
.Release
.If either of those conditions fail, the settings aren't processed. More importantly, the <AndroidSigningKeyStore>
and <AndroidSigningKeyAlias>
settings aren't set, preventing the app from being signed.
For security reasons, you shouldn't supply a value for <AndroidSigningKeyPass>
and <AndroidSigningStorePass>
in the project file. You can provide these values on the command line when you publish the app, or use the env:
or file:
prefixes to prevent the password from appearing in build logs. For example, to use an environment variable named 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>
Important
The env: prefix isn't supported when $(AndroidPackageFormat)
is set to aab
.
Alternatively, to use a file located at 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>
The signed APK or AAB file can be distributed with one of the following approaches:
.NET MAUI feedback
.NET MAUI is an open source project. Select a link to provide feedback:
Events
Mar 17, 11 PM - Mar 21, 11 PM
Join the meetup series to build scalable AI solutions based on real-world use cases with fellow developers and experts.
Register nowTraining
Module
Publish an ASP.NET Core app - Training
Learn how to publish an ASP.NET Core app for deployment to a web server or cloud service.
Documentation
Publish a .NET MAUI Android app for ad-hoc distribution - .NET MAUI
Learn how to publish a .NET MAUI Android app for ad-hoc distribution.
Publish a .NET MAUI Android app for Google Play distribution - .NET MAUI
Learn how to publish a .NET MAUI Android app for Google Play distribution.
Easily Archive & Publish .NET MAUI apps with VS Code
András (Bandi) joins James to show off a super nifty extension he created to help developer easily archive and publish .NET MAUI apps from a user-friendly interface in Visual Studio Code. Let's take a look! Chapters 00:00 - Introduction & VS Code Extensions 02:14 - Getting started with .NET MAUI Archive and Publishe Extension 05:10 - Publish iOS .NET MAUI apps in VS Code 09:00 - Publish Android .NET MAUI Apps in VS Code 11:30 - Future plans and wrap-up Recommended resources Extension GitHub