若要将 .NET 多平台应用 UI (.NET MAUI) Android 应用分发,需要使用密钥存储中的密钥对其进行签名。
密钥存储
是使用
keytool
Java 开发工具包 (JDK) 创建的安全证书数据库。 发布 .NET MAUI Android 应用时需要密钥存储,因为 Android 不会运行尚未签名的应用。
创建密钥存储文件
在开发期间,适用于 Android 的 .NET 使用调试密钥存储对应用进行签名,从而允许将其直接部署到模拟器或配置为运行可调试应用的设备。 但是,出于分发应用的目的,无法将此密钥存储识别为有效的密钥存储。 因此,必须创建私钥存储并将其用于对发布版本进行签名。 此步骤仅应执行一次,因为相同的密钥将用于发布更新,并可用于对其他应用进行签名。 生成密钥存储文件后,你将在生成应用时从命令行提供其详细信息,或者将项目文件配置为引用它。
执行以下步骤创建密钥存储文件:
打开终端并导航到项目的文件夹。
如果 Visual Studio 处于打开状态,请使用“
查看
>
终端
”菜单在解决方案或项目的位置打开终端。 导航到项目文件夹。
使用以下参数运行
keytool
工具:
keytool -genkeypair -v -keystore {filename}.keystore -alias {keyname} -keyalg RSA -keysize 2048 -validity 10000
如果计算机上安装了多个版本的 JDK,请确保从最新版本的 JDK 运行 keytool
。
系统会提示你提供并确认密码,后跟你的全名、组织单位、组织、城市或地区、州或省/自治区/直辖市/自治区/地区代码。 此信息不会显示在应用中,但会包含在证书中。
例如,若要在项目所在的文件夹中生成 myapp.keystore 文件(别名为 myapp
),请使用以下命令:
keytool -genkeypair -v -keystore myapp.keystore -alias myapp -keyalg RSA -keysize 2048 -validity 10000
备份密钥存储和密码。 如果丢失了,将无法使用相同的签名标识对应用进行签名。
查找密钥存储的签名
若要列出存储在密钥存储中的密钥,请使用 keytool
选项 -list
:
keytool -list -keystore {filename}.keystore
例如,若要列出名为 myapp.keystore 的密钥存储中的密钥,请使用以下命令:
keytool -list -keystore myapp.keystore
生成应用并签名
若要从命令行生成应用并使用密钥存储对其进行签名,请打开终端并导航到 .NET MAUI 应用项目的文件夹。 运行 命令 dotnet publish
,提供以下参数:
尝试发布 .NET MAUI 解决方案将导致 dotnet publish
命令尝试单独发布解决方案中的每个项目,这可能会导致将其他项目类型添加到解决方案时出现问题。 因此,命令 dotnet publish
的范围应限定为 .NET MAUI 应用项目。
如果在项目文件的 中未提供其他生成参数,则可以在命令行上 <PropertyGroup>
指定这些参数。 下表列出了一些常见参数:
-p:AndroidPackageFormats
一个分号分隔的属性,指示是要将应用打包为 APK 文件还是 AAB。 设置为 aab
或 apk
仅生成一种格式。 发布版本的默认值为 aab;apk
。
-p:AndroidSigningKeyAlias
密钥存储中密钥的别名。 这是创建 keytool -alias
密钥存储时使用的值。
-p:AndroidSigningKeyPass
密钥存储文件中密钥的密码。 这是创建密钥存储文件时提供给 keytool
的值,系统会要求你输入密钥存储密码。 这是因为默认密钥存储类型假定密钥密码和密钥存储密码相同。 此属性还支持 env:
和 file:
前缀,这些前缀可用于指定包含密码的环境变量或文件。 通过这些选项,可以防止密码显示在生成日志中。
-p:AndroidSigningKeyStore
创建的 keytool
密钥存储文件的文件名。 这是创建 keytool -keystore
密钥存储时使用的值。
-p:AndroidSigningStorePass
密钥存储文件的密码。 这是创建密钥存储文件时提供给 keytool
的值,系统会要求你输入密钥存储密码。 这是因为默认密钥存储类型假定密钥存储密码和密钥密码相同。 此属性还支持 env:
和 file:
前缀,这些前缀可用于指定包含密码的环境变量或文件。 通过这些选项,可以防止密码显示在生成日志中。
-p:PublishTrimmed
一个布尔值,指示是否应剪裁应用。 默认值 true
适用于发布版本。
应使用与 和 AndroidSigningStorePass
参数的值AndroidSigningKeyPass
相同的密码。
有关生成属性的完整列表,请参阅 生成属性。
无需在命令行上提供这些参数的值。 还可以在项目文件中提供它们。 在命令行和项目文件中提供参数时,命令行参数优先。 有关在项目文件中提供生成属性的详细信息,请参阅 在项目文件中定义生成属性。
dotnet publish
使用以下参数运行 命令以生成应用并签名:
dotnet publish -f net7.0-android -c Release -p:AndroidSigningKeyStore={filename}.keystore -p:AndroidSigningKeyAlias={keyname} -p:AndroidSigningKeyPass={password} -p:AndroidSigningStorePass={password}
例如,使用以下命令使用之前创建的密钥存储生成应用并签名:
dotnet publish -f net7.0-android -c Release -p:AndroidSigningKeyStore=myapp.keystore -p:AndroidSigningKeyAlias=myapp -p:AndroidSigningKeyPass=mypassword -p:AndroidSigningStorePass=mypassword
AndroidSigningKeyPass
和 AndroidSigningStorePass
属性都支持env:
和file:
前缀,可用于指定包含密码的环境变量或文件。 以这种方式指定密码可防止它出现在生成日志中。 例如,使用名为 的 AndroidSigningPassword
环境变量:
dotnet publish -f net7.0-android -c Release -p:AndroidSigningKeyStore=myapp.keystore -p:AndroidSigningKeyAlias=myapp -p:AndroidSigningKeyPass=env:AndroidSigningPassword -p:AndroidSigningStorePass=env:AndroidSigningPassword
设置为 时$(AndroidPackageFormat)
aab
,不支持 env: 前缀。
使用位于 C:\Users\user1\AndroidSigningPassword.txt的文件:
dotnet publish -f net7.0-android -c Release -p:AndroidSigningKeyStore=myapp.keystore -p:AndroidSigningKeyAlias=myapp -p:AndroidSigningKeyPass=file:C:\Users\user1\AndroidSigningPassword.txt -p:AndroidSigningStorePass=file:C:\Users\user1\AndroidSigningPassword.txt
发布生成应用并签名,然后将 AAB 和 APK 文件复制到 bin\Release\net7.0-android\publish 文件夹。 有两个 AAB 文件 - 一个未签名文件,另一个已签名文件。 带符号的变体在文件名中具有 -signed 。
有关命令的详细信息 dotnet publish
,请参阅 dotnet publish。
在项目文件中定义生成属性
在命令行上指定生成参数的替代方法是在 的项目文件中 <PropertyGroup>
指定它们。 下表列出了一些常见的生成属性:
<AndroidPackageFormats>
一个分号分隔的属性,指示是要将应用打包为 APK 文件还是 AAB。 将 设置为 aab
或 apk
以仅生成一种格式。 发布版本的默认值为 aab;apk
。
<AndroidSigningKeyAlias>
密钥存储中密钥的别名。 这是创建 keytool -alias
密钥存储时使用的值。
<AndroidSigningKeyPass>
密钥存储文件中密钥的密码。 这是创建密钥存储文件时提供给 keytool
的值,系统会要求你输入密钥存储密码。 这是因为默认密钥存储类型假定密钥密码和密钥存储密码相同。 此属性还支持 env:
和 file:
前缀,这些前缀可用于指定包含密码的环境变量或文件。 通过这些选项,可以防止密码显示在生成日志中。
<AndroidSigningKeyStore>
创建的 keytool
密钥存储文件的文件名。 这是创建 keytool -keystore
密钥存储时使用的值。
<AndroidSigningStorePass>
密钥存储文件的密码。 这是创建密钥存储文件时提供给 keytool
的值,系统会要求你输入密钥存储密码。 这是因为默认密钥存储类型假定密钥存储密码和密钥密码相同。 此属性还支持 env:
和 file:
前缀,这些前缀可用于指定包含密码的环境变量或文件。 通过这些选项,可以防止密码显示在生成日志中。
<PublishTrimmed>
一个布尔值,指示是否应剪裁应用。 对于发布版本,默认值 true
为 。
有关生成属性的完整列表,请参阅 生成属性。
无需在项目文件中提供这些生成属性的值。 发布应用时,还可以在命令行上提供它们。 这使你可以省略项目文件中的特定值。
以下示例演示用于生成 Android 应用并为其签名的典型属性组:
<PropertyGroup Condition="$(TargetFramework.Contains('-android')) and '$(Configuration)' == 'Release'">
<AndroidSigningKeyStore>myapp.keystore</AndroidSigningKeyStore>
<AndroidSigningKeyAlias>myapp</AndroidSigningKeyAlias>
</PropertyGroup>
此示例<PropertyGroup>
添加条件检查,以防止处理这些设置,除非条件检查通过。 条件检查查找两项内容:
目标框架设置为包含文本 -android
的内容。
生成配置设置为 Release
。
如果上述任一条件失败,则不会处理设置。 更重要的是, <AndroidSigningKeyStore>
未设置 和 <AndroidSigningKeyAlias>
设置,从而阻止对应用进行签名。
出于安全原因,不应在项目文件中为 <AndroidSigningKeyPass>
和 <AndroidSigningStorePass>
提供值。 发布应用时,可以在命令行上提供这些值,或使用 env:
或 file:
前缀来防止密码显示在生成日志中。 例如,若要使用名为 的 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>
当 设置为 aab
时$(AndroidPackageFormat)
,不支持 env: 前缀。
或者,使用位于 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>
可以使用以下方法之一分发已签名的 APK 或 AAB 文件:
向用户分发 Android 应用最常见的方法是通过 Google Play。 Google Play 要求将应用作为 Android App Bundle (AAB) 提交。 有关详细信息,请参阅在 developer.android.com 上将应用上传到 Play Console
APK 文件可以通过网站或服务器分发到 Android 设备。 当用户从 Android 设备浏览到下载链接时,会下载该文件。 Android 将自动开始在设备上安装它,前提是用户已配置其设置以允许安装来自未知来源的应用。 有关选择允许来自未知源的应用的详细信息,请参阅 用户选择加入 developer.android.com 上的未知应用和源 。
关于 developer.android.com 上的 Android 应用程序包