flutter:打包apk及签名
一,从android studio打包

二,从命令行打包:
只打包
liuhongdi@liuhongdideMBP demo3 % flutter build apk
Running Gradle task 'assembleRelease'... 8.9s
✓ Built build/app/outputs/flutter-apk/app-release.apk (49.4MB)
指定环境
liuhongdi@liuhongdideMBP demo3 % flutter build apk --dart-define=MYENV=devel
Font asset "MaterialIcons-Regular.otf" was tree-shaken, reducing it from 1645184 to 1672 bytes (99.9% reduction). Tree-shaking can be disabled by providing the --no-tree-shake-icons flag when building your app.
Running Gradle task 'assembleRelease'... 71.3s
✓ Built build/app/outputs/flutter-apk/app-release.apk (49.4MB)
三,签名
1,创建keystore:
liuhongdi@liuhongdideMBP ~ % mkdir keystore
liuhongdi@liuhongdideMBP ~ % cd keystore
liuhongdi@liuhongdideMBP keystore % ls
liuhongdi@liuhongdideMBP keystore % keytool -genkey -v -keystore laoliudemo3.jks -keyalg RSA -keysize 2048 -validity 10000 -alias laoliudemo3
输入密钥库口令:
再次输入新口令:
您的名字与姓氏是什么?
[Unknown]: liu
您的组织单位名称是什么?
[Unknown]: liu
您的组织名称是什么?
[Unknown]: liu
您所在的城市或区域名称是什么?
[Unknown]: beijing
您所在的省/市/自治区名称是什么?
[Unknown]: beijing
该单位的双字母国家/地区代码是什么?
[Unknown]: cn
CN=liu, OU=liu, O=liu, L=beijing, ST=beijing, C=cn是否正确?
[否]: 是
正在为以下对象生成 2,048 位RSA密钥对和自签名证书 (SHA256withRSA) (有效期为 10,000 天):
CN=liu, OU=liu, O=liu, L=beijing, ST=beijing, C=cn
[正在存储laoliudemo3.jks]
查看创建的keystore
liuhongdi@liuhongdideMBP keystore % keytool -list -v -keystore laoliudemo3.jks
输入密钥库口令:
密钥库类型: PKCS12
密钥库提供方: SUN
您的密钥库包含 1 个条目
别名: laoliudemo3
创建日期: 2025年3月28日
条目类型: PrivateKeyEntry
证书链长度: 1
证书[1]:
所有者: CN=liu, OU=liu, O=liu, L=beijing, ST=beijing, C=cn
发布者: CN=liu, OU=liu, O=liu, L=beijing, ST=beijing, C=cn
序列号: ce45c3f224d605ad
生效时间: Fri Mar 28 11:49:04 CST 2025, 失效时间: Tue Aug 13 11:49:04 CST 2052
证书指纹:
SHA1: 9A:7D:43:20:97:9E:CD:DF:55:20:25:CD:50:07:FE:13:47:44:94:6B
SHA256: 87:B0:29:9E:E8:17:7F:36:5C:CE:97:18:E8:08:4B:40:0F:9A:E8:01:69:40:0D:8C:2A:05:01:31:73:63:34:9C
签名算法名称: SHA256withRSA
主体公共密钥算法: 2048 位 RSA 密钥
版本: 3
扩展:
#1: ObjectId: 2.5.29.14 Criticality=false
SubjectKeyIdentifier [
KeyIdentifier [
0000: E5 0D 0E E7 C7 44 A3 81 14 C0 C4 08 A8 16 99 D8 .....D..........
0010: 0F 2F 6A 3B ./j;
]
]
*******************************************
*******************************************
2,添加keystore到项目
复制laoliudemo3.jks到android/app目录下,
并在android目录下创建文件:key.properties
内容:
storePassword=laoliudemo3
keyPassword=laoliudemo3
keyAlias=laoliudemo3
storeFile=./laoliudemo3.jks
如图:

3,使keystore在打包时生效:
import java.util.Properties
import java.io.FileInputStream
plugins {
id("com.android.application")
id("kotlin-android")
// The Flutter Gradle Plugin must be applied after the Android and Kotlin Gradle plugins.
id("dev.flutter.flutter-gradle-plugin")
}
val keystoreProperties = Properties()
val keystorePropertiesFile = rootProject.file("key.properties")
if (keystorePropertiesFile.exists()) {
keystoreProperties.load(FileInputStream(keystorePropertiesFile))
}
android {
namespace = "com.example.demo3"
compileSdk = flutter.compileSdkVersion
ndkVersion = flutter.ndkVersion
//ndkVersion = "27.0.12077973"
compileOptions {
sourceCompatibility = JavaVersion.VERSION_11
targetCompatibility = JavaVersion.VERSION_11
}
kotlinOptions {
jvmTarget = JavaVersion.VERSION_11.toString()
}
defaultConfig {
// minSdkVersion = 24
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId = "com.example.demo3"
// You can update the following values to match your application needs.
// For more information, see: https://flutter.dev/to/review-gradle-config.
minSdk = flutter.minSdkVersion
targetSdk = flutter.targetSdkVersion
versionCode = flutter.versionCode
versionName = flutter.versionName
// ndkVersion = "27.0.12077973"
}
signingConfigs {
create("release") {
keyAlias = keystoreProperties["keyAlias"] as String
keyPassword = keystoreProperties["keyPassword"] as String
storeFile = keystoreProperties["storeFile"]?.let { file(it) }
storePassword = keystoreProperties["storePassword"] as String
}
}
buildTypes {
getByName("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.getByName("release")
//signingConfig = signingConfigs.release
}
}
}
flutter {
source = "../.."
}
参考文档地址:
https://docs.flutter.cn/deployment/android/index.html
代码中新增部分看截图:


4,测试keystore是否生效:
% /Users/liuhongdi/Library/Android/sdk/build-tools/36.0.0/apksigner verify --verbose build/app/outputs/flutter-apk/app-release.apk
Verifies
Verified using v1 scheme (JAR signing): false
Verified using v2 scheme (APK Signature Scheme v2): true
Verified using v3 scheme (APK Signature Scheme v3): false
Verified using v3.1 scheme (APK Signature Scheme v3.1): false
Verified using v4 scheme (APK Signature Scheme v4): false
Verified for SourceStamp: false
Number of signers: 1
不要用jarsigner验证,它版本太低,会验证不出来
% jarsigner -verify -verbose -certs build/app/outputs/flutter-apk/app-release.apk
s = 已验证签名
m = 在清单中列出条目
k = 在密钥库中至少找到了一个证书
没有清单。
jar 未签名。
浙公网安备 33010602011771号