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 未签名。

 

posted @ 2025-04-04 13:17  刘宏缔的架构森林  阅读(589)  评论(0)    收藏  举报