安卓打包 谷歌key相关
This commit is contained in:
parent
af42c815cf
commit
906cfbf4d8
6
.gitignore
vendored
6
.gitignore
vendored
@ -31,7 +31,11 @@ migrate_working_dir/
|
|||||||
.flutter-plugins-dependencies
|
.flutter-plugins-dependencies
|
||||||
.pub-cache/
|
.pub-cache/
|
||||||
.pub/
|
.pub/
|
||||||
/build/
|
/build/
|
||||||
|
/dist/
|
||||||
|
/android/key.properties
|
||||||
|
/android/app/upload-keystore.jks
|
||||||
|
/android/app/upload_certificate.pem
|
||||||
|
|
||||||
# Symbolication related
|
# Symbolication related
|
||||||
app.*.symbols
|
app.*.symbols
|
||||||
|
|||||||
@ -1,6 +1,8 @@
|
|||||||
plugins {
|
import java.util.Properties
|
||||||
id("com.android.application")
|
|
||||||
id("kotlin-android")
|
plugins {
|
||||||
|
id("com.android.application")
|
||||||
|
id("kotlin-android")
|
||||||
// The Flutter Gradle Plugin must be applied after the Android and Kotlin Gradle plugins.
|
// The Flutter Gradle Plugin must be applied after the Android and Kotlin Gradle plugins.
|
||||||
id("dev.flutter.flutter-gradle-plugin")
|
id("dev.flutter.flutter-gradle-plugin")
|
||||||
id("com.google.gms.google-services")
|
id("com.google.gms.google-services")
|
||||||
@ -11,16 +13,23 @@ android {
|
|||||||
compileSdk = 36
|
compileSdk = 36
|
||||||
ndkVersion = "28.2.13676358"
|
ndkVersion = "28.2.13676358"
|
||||||
|
|
||||||
val releaseKeystoreFile = file("./yumi.jks")
|
val keystoreProperties = Properties()
|
||||||
|
val keystorePropertiesFile = rootProject.file("key.properties")
|
||||||
|
if (keystorePropertiesFile.exists()) {
|
||||||
|
keystorePropertiesFile.inputStream().use { keystoreProperties.load(it) }
|
||||||
|
}
|
||||||
|
|
||||||
|
val releaseKeystorePath = keystoreProperties.getProperty("storeFile")
|
||||||
|
val releaseKeystoreFile = releaseKeystorePath?.let { file(it) }
|
||||||
val debugKeystoreFile = file("./yumi_debug.jks")
|
val debugKeystoreFile = file("./yumi_debug.jks")
|
||||||
|
|
||||||
signingConfigs {
|
signingConfigs {
|
||||||
create("release") {
|
create("release") {
|
||||||
if (releaseKeystoreFile.exists()) {
|
if (releaseKeystoreFile?.exists() == true) {
|
||||||
storeFile = releaseKeystoreFile
|
storeFile = releaseKeystoreFile
|
||||||
storePassword = "2025abc"
|
storePassword = keystoreProperties.getProperty("storePassword")
|
||||||
keyAlias = "yumi"
|
keyAlias = keystoreProperties.getProperty("keyAlias")
|
||||||
keyPassword = "2025abc"
|
keyPassword = keystoreProperties.getProperty("keyPassword")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -68,11 +77,7 @@ android {
|
|||||||
getDefaultProguardFile("proguard-android-optimize.txt"),
|
getDefaultProguardFile("proguard-android-optimize.txt"),
|
||||||
"proguard-rules.pro"
|
"proguard-rules.pro"
|
||||||
)
|
)
|
||||||
signingConfig = if (releaseKeystoreFile.exists()) {
|
signingConfig = signingConfigs["release"]
|
||||||
signingConfigs["release"]
|
|
||||||
} else {
|
|
||||||
signingConfigs["debug"]
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
getByName("debug") {
|
getByName("debug") {
|
||||||
isMinifyEnabled = false
|
isMinifyEnabled = false
|
||||||
|
|||||||
@ -5,12 +5,15 @@
|
|||||||
<uses-permission android:name="android.permission.CAMERA" />
|
<uses-permission android:name="android.permission.CAMERA" />
|
||||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||||
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
|
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
|
||||||
<uses-permission android:name="android.permission.RECORD_AUDIO" />
|
<uses-permission android:name="android.permission.RECORD_AUDIO" />
|
||||||
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
|
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
|
||||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||||
<uses-permission android:name="android.permission.BLUETOOTH" />
|
<uses-permission android:name="android.permission.BLUETOOTH" />
|
||||||
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
|
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
|
||||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
||||||
|
<uses-permission
|
||||||
|
android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PROJECTION"
|
||||||
|
tools:node="remove" />
|
||||||
|
|
||||||
<!-- 谷歌支付权限 -->
|
<!-- 谷歌支付权限 -->
|
||||||
<uses-permission android:name="com.android.vending.BILLING" />
|
<uses-permission android:name="com.android.vending.BILLING" />
|
||||||
@ -100,10 +103,19 @@
|
|||||||
android:exported="false"
|
android:exported="false"
|
||||||
android:theme="@android:style/Theme.Translucent.NoTitleBar" />
|
android:theme="@android:style/Theme.Translucent.NoTitleBar" />
|
||||||
|
|
||||||
<activity
|
<activity
|
||||||
android:name="com.google.android.gms.auth.api.signin.GoogleSignInActivity"
|
android:name="com.google.android.gms.auth.api.signin.GoogleSignInActivity"
|
||||||
android:exported="true"
|
android:exported="true"
|
||||||
android:theme="@android:style/Theme.Translucent.NoTitleBar" />
|
android:theme="@android:style/Theme.Translucent.NoTitleBar" />
|
||||||
|
|
||||||
|
<!-- Remove Agora local screen sharing declarations; we do not ship this capability. -->
|
||||||
|
<activity
|
||||||
|
android:name="io.agora.rtc2.extensions.MediaProjectionMgr$LocalScreenCaptureAssistantActivity"
|
||||||
|
tools:node="remove" />
|
||||||
|
|
||||||
|
<service
|
||||||
|
android:name="io.agora.rtc2.extensions.MediaProjectionMgr$LocalScreenSharingService"
|
||||||
|
tools:node="remove" />
|
||||||
|
|
||||||
<meta-data
|
<meta-data
|
||||||
android:name="com.google.firebase.messaging.default_notification_channel_id"
|
android:name="com.google.firebase.messaging.default_notification_channel_id"
|
||||||
|
|||||||
@ -40,23 +40,28 @@ class SCLoginWithAccountPageState extends State<SCLoginWithAccountPage>
|
|||||||
///密码控制器
|
///密码控制器
|
||||||
TextEditingController passController = TextEditingController();
|
TextEditingController passController = TextEditingController();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
String account = DataPersistence.getString(
|
String account = DataPersistence.getString("Login_Account");
|
||||||
"Login_Account",
|
String pwd = DataPersistence.getString("Login_Pwd");
|
||||||
defaultValue: "123456",
|
// String account = DataPersistence.getString(
|
||||||
);
|
// "Login_Account",
|
||||||
String pwd = DataPersistence.getString("Login_Pwd", defaultValue: "123456");
|
// defaultValue: "123456",
|
||||||
if (account.isEmpty) {
|
// );
|
||||||
account = "123456";
|
// String pwd = DataPersistence.getString(
|
||||||
}
|
// "Login_Pwd",
|
||||||
if (pwd.isEmpty) {
|
// defaultValue: "123456",
|
||||||
pwd = "123456";
|
// );
|
||||||
}
|
// if (account.isEmpty) {
|
||||||
accountController.text = account;
|
// account = "123456";
|
||||||
passController.text = pwd;
|
// }
|
||||||
}
|
// if (pwd.isEmpty) {
|
||||||
|
// pwd = "123456";
|
||||||
|
// }
|
||||||
|
accountController.text = account;
|
||||||
|
passController.text = pwd;
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
|||||||
@ -286,135 +286,93 @@ class _MePage2State extends State<MePage2> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildMenuCard2() {
|
Widget _buildMenuCard2() {
|
||||||
final items = <_MenuRowData>[];
|
final userProfile = context.watch<SocialChatUserProfileManager>();
|
||||||
|
final items = <_MenuRowData>[];
|
||||||
/*
|
|
||||||
// 1. 主播相关
|
// 1. 主播相关
|
||||||
if (userProfile.userIdentity?.anchor ?? false) {
|
if (userProfile.userIdentity?.anchor ?? false) {
|
||||||
if (userProfile.userIdentity?.agent ?? false) {
|
if (userProfile.userIdentity?.agent ?? false) {
|
||||||
items.add(
|
items.add(
|
||||||
_MenuRowData(
|
_MenuRowData(
|
||||||
title: SCAppLocalizations.of(context)!.agentCenter,
|
title: SCAppLocalizations.of(context)!.agentCenter,
|
||||||
assetIcon: 'sc_images/index/at_icon_agent_center.png',
|
assetIcon: 'sc_images/index/at_icon_agent_center.png',
|
||||||
onTap: () {
|
onTap: () {
|
||||||
SCNavigatorUtils.push(
|
SCNavigatorUtils.push(
|
||||||
context,
|
context,
|
||||||
"${SCMainRoute.webViewPage}?url=${Uri.encodeComponent(SCGlobalConfig.agencyCenterUrl)}&showTitle=false",
|
"${SCMainRoute.webViewPage}?url=${Uri.encodeComponent(SCGlobalConfig.agencyCenterUrl)}&showTitle=false",
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
items.add(
|
items.add(
|
||||||
_MenuRowData(
|
_MenuRowData(
|
||||||
title: SCAppLocalizations.of(context)!.hostCenter,
|
title: SCAppLocalizations.of(context)!.hostCenter,
|
||||||
assetIcon: 'sc_images/index/at_icon_host_center.png',
|
assetIcon: 'sc_images/index/at_icon_host_center.png',
|
||||||
onTap: () {
|
onTap: () {
|
||||||
SCNavigatorUtils.push(
|
SCNavigatorUtils.push(
|
||||||
context,
|
context,
|
||||||
"${SCMainRoute.webViewPage}?url=${Uri.encodeComponent(SCGlobalConfig.hostCenterUrl)}&showTitle=false",
|
"${SCMainRoute.webViewPage}?url=${Uri.encodeComponent(SCGlobalConfig.hostCenterUrl)}&showTitle=false",
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2. BD 相关(非管理员时)
|
// 2. BD 相关(非管理员时)
|
||||||
if (!(userProfile.userIdentity?.admin ?? false)) {
|
if (!(userProfile.userIdentity?.admin ?? false)) {
|
||||||
if (userProfile.userIdentity?.bdLeader ?? false) {
|
if (userProfile.userIdentity?.bdLeader ?? false) {
|
||||||
items.add(
|
items.add(
|
||||||
_MenuRowData(
|
_MenuRowData(
|
||||||
title: SCAppLocalizations.of(context)!.bdLeader,
|
title: SCAppLocalizations.of(context)!.bdLeader,
|
||||||
assetIcon: 'sc_images/index/at_icon_bd_leader.png',
|
assetIcon: 'sc_images/index/at_icon_bd_leader.png',
|
||||||
onTap: () {
|
onTap: () {
|
||||||
SCNavigatorUtils.push(
|
SCNavigatorUtils.push(
|
||||||
context,
|
context,
|
||||||
"${SCMainRoute.webViewPage}?url=${Uri.encodeComponent(SCGlobalConfig.bdLeaderUrl)}&showTitle=false",
|
"${SCMainRoute.webViewPage}?url=${Uri.encodeComponent(SCGlobalConfig.bdLeaderUrl)}&showTitle=false",
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
} else if (userProfile.userIdentity?.bd ?? false) {
|
} else if (userProfile.userIdentity?.bd ?? false) {
|
||||||
items.add(
|
items.add(
|
||||||
_MenuRowData(
|
_MenuRowData(
|
||||||
title: SCAppLocalizations.of(context)!.bdCenter,
|
title: SCAppLocalizations.of(context)!.bdCenter,
|
||||||
assetIcon: 'sc_images/index/at_icon_bd_center.png',
|
assetIcon: 'sc_images/index/at_icon_bd_center.png',
|
||||||
onTap: () {
|
onTap: () {
|
||||||
SCNavigatorUtils.push(
|
SCNavigatorUtils.push(
|
||||||
context,
|
context,
|
||||||
"${SCMainRoute.webViewPage}?url=${Uri.encodeComponent(SCGlobalConfig.bdCenterUrl)}&showTitle=false",
|
"${SCMainRoute.webViewPage}?url=${Uri.encodeComponent(SCGlobalConfig.bdCenterUrl)}&showTitle=false",
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3. 货运代理
|
// 3. 货运代理
|
||||||
if (userProfile.userIdentity?.freightAgent ?? false) {
|
if (userProfile.userIdentity?.freightAgent ?? false) {
|
||||||
items.add(
|
items.add(
|
||||||
_MenuRowData(
|
_MenuRowData(
|
||||||
title: SCAppLocalizations.of(context)!.rechargeAgency,
|
title: SCAppLocalizations.of(context)!.rechargeAgency,
|
||||||
assetIcon: 'sc_images/index/at_icon_recharge_agency.png',
|
assetIcon: 'sc_images/index/at_icon_recharge_agency.png',
|
||||||
onTap: () {
|
onTap: () {
|
||||||
SCNavigatorUtils.push(
|
SCNavigatorUtils.push(
|
||||||
context,
|
context,
|
||||||
"${SCMainRoute.webViewPage}?url=${Uri.encodeComponent(SCGlobalConfig.coinSellerUrl)}&showTitle=false",
|
"${SCMainRoute.webViewPage}?url=${Uri.encodeComponent(SCGlobalConfig.coinSellerUrl)}&showTitle=false",
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
// 4. 管理员(注意:你的原逻辑中管理员和上面BD逻辑有重叠,这里按原样单独处理)
|
||||||
// Debug: 临时注释原判断逻辑,固定展示三个入口,便于调试各自 WebView。
|
if (userProfile.userIdentity?.admin ?? false) {
|
||||||
items.add(
|
items.add(
|
||||||
_MenuRowData(
|
_MenuRowData(
|
||||||
title: SCAppLocalizations.of(context)!.hostCenter,
|
title: SCAppLocalizations.of(context)!.adminCenter,
|
||||||
assetIcon: 'sc_images/index/sc_icon_host_center.png',
|
|
||||||
onTap: () {
|
|
||||||
SCNavigatorUtils.push(
|
|
||||||
context,
|
|
||||||
"${SCMainRoute.webViewPage}?url=${Uri.encodeComponent(SCGlobalConfig.hostCenterUrl)}&showTitle=false",
|
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
);
|
|
||||||
|
|
||||||
items.add(
|
|
||||||
_MenuRowData(
|
|
||||||
title: SCAppLocalizations.of(context)!.bdCenter,
|
|
||||||
assetIcon: 'sc_images/index/sc_icon_bd_center.png',
|
|
||||||
onTap: () {
|
|
||||||
SCNavigatorUtils.push(
|
|
||||||
context,
|
|
||||||
"${SCMainRoute.webViewPage}?url=${Uri.encodeComponent(SCGlobalConfig.bdCenterUrl)}&showTitle=false",
|
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
);
|
|
||||||
|
|
||||||
items.add(
|
|
||||||
_MenuRowData(
|
|
||||||
title: SCAppLocalizations.of(context)!.rechargeAgency,
|
|
||||||
assetIcon: 'sc_images/index/sc_icon_recharge_agency.png',
|
|
||||||
onTap: () {
|
|
||||||
SCNavigatorUtils.push(
|
|
||||||
context,
|
|
||||||
"${SCMainRoute.webViewPage}?url=${Uri.encodeComponent(SCGlobalConfig.coinSellerUrl)}&showTitle=false",
|
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
);
|
|
||||||
|
|
||||||
// 4. 管理员(注意:你的原逻辑中管理员和上面BD逻辑有重叠,这里按原样单独处理)
|
|
||||||
final userProfile = context.watch<SocialChatUserProfileManager>();
|
|
||||||
if (userProfile.userIdentity?.admin ?? false) {
|
|
||||||
items.add(
|
|
||||||
_MenuRowData(
|
|
||||||
title: SCAppLocalizations.of(context)!.adminCenter,
|
|
||||||
assetIcon: 'sc_images/index/at_icon_admin_center.png',
|
assetIcon: 'sc_images/index/at_icon_admin_center.png',
|
||||||
onTap: () {
|
onTap: () {
|
||||||
SCNavigatorUtils.push(
|
SCNavigatorUtils.push(
|
||||||
|
|||||||
87
需求进度.md
87
需求进度.md
@ -19,10 +19,20 @@
|
|||||||
- 已切换 Android `release` 为真正的瘦身模式:开启 `minify`、`shrinkResources`、`zipAlign`。
|
- 已切换 Android `release` 为真正的瘦身模式:开启 `minify`、`shrinkResources`、`zipAlign`。
|
||||||
- 已完成开启瘦身配置后的 Android release 复测,并接入 `split-debug-info` 保存 Dart symbols。
|
- 已完成开启瘦身配置后的 Android release 复测,并接入 `split-debug-info` 保存 Dart symbols。
|
||||||
- 已生成统一的 Python 打包脚本 `scripts/build_release.py`,开始接管 `AAB`、分 ABI APK 与 iOS 包流程。
|
- 已生成统一的 Python 打包脚本 `scripts/build_release.py`,开始接管 `AAB`、分 ABI APK 与 iOS 包流程。
|
||||||
|
- 已完成 `scripts/build_release.py` 的 Android / iOS 真机冒烟验证,产物归档目录与 manifest 均已生成。
|
||||||
|
- 已按当前需求再次完成正式 `AAB` 出包。
|
||||||
|
- 已定位 Google Play 上传阻塞点:当前 `AAB` 使用的是 `Android Debug` 证书签名,不是正式 upload key。
|
||||||
|
- 已确认当前项目属于“首次上架的新应用”,后续应走 Play App Signing 首发流程,而不是兼容老签名迁移流程。
|
||||||
|
- 已梳理 Google Play 首次上架所需的 `Play App Signing`、`upload key`、重新打包与提审步骤。
|
||||||
|
- 已澄清首次生成 `upload keystore` 时的“密钥库口令”是本地自行设置的密码,与 Google 提供的 `deployment_cert.der` 证书文件无关。
|
||||||
|
- 已为新应用生成正式 `upload keystore`,并接入工程的 release 签名配置。
|
||||||
|
- 已重新打出正式 `AAB`,并确认其签名已经从 `Android Debug` 切换到新的 upload key。
|
||||||
|
- 已定位 `FOREGROUND_SERVICE_MEDIA_PROJECTION` 的来源为 Agora `full-screen-sharing` 依赖,并开始从主 Manifest 覆盖移除。
|
||||||
|
- 已移除 `FOREGROUND_SERVICE_MEDIA_PROJECTION` 相关声明并重新打出正式 `AAB`。
|
||||||
|
- 已按当前需求打出正式 `arm64-v8a` 单架构 `APK`。
|
||||||
|
|
||||||
## 进行中模块
|
## 进行中模块
|
||||||
- 开启并验证 Android release 的 `minify`、`shrinkResources`、`zipAlign` 瘦身配置。
|
- 评估 iOS 正式签名参数接入后导出 `.ipa` 的流程。
|
||||||
- 生成统一的 Python 打包脚本,流程化产出 `AAB`、分 ABI APK 与 iOS 包。
|
|
||||||
- 继续评估 Agora 扩展 so 与 release shrink 策略是否还能进一步裁剪。
|
- 继续评估 Agora 扩展 so 与 release shrink 策略是否还能进一步裁剪。
|
||||||
- 评估 12 张 TinyPNG 不支持解码的特殊 `webp` 是否需要改格式或换工具处理。
|
- 评估 12 张 TinyPNG 不支持解码的特殊 `webp` 是否需要改格式或换工具处理。
|
||||||
|
|
||||||
@ -38,6 +48,8 @@
|
|||||||
|
|
||||||
## 已改动文件
|
## 已改动文件
|
||||||
- `需求进度.md`
|
- `需求进度.md`
|
||||||
|
- `.gitignore`
|
||||||
|
- `android/key.properties`
|
||||||
- `pubspec.yaml`
|
- `pubspec.yaml`
|
||||||
- `pubspec.lock`
|
- `pubspec.lock`
|
||||||
- `lib/ui_kit/components/dialog/dialog.dart`
|
- `lib/ui_kit/components/dialog/dialog.dart`
|
||||||
@ -50,7 +62,12 @@
|
|||||||
- `local_packages/image_cropper-5.0.1-patched/android/src/main/java/vn/hunghd/flutter/plugins/imagecropper/ImageCropperPlugin.java`
|
- `local_packages/image_cropper-5.0.1-patched/android/src/main/java/vn/hunghd/flutter/plugins/imagecropper/ImageCropperPlugin.java`
|
||||||
- `local_packages/image_cropper-5.0.1-patched/`
|
- `local_packages/image_cropper-5.0.1-patched/`
|
||||||
- `android/app/build.gradle.kts`
|
- `android/app/build.gradle.kts`
|
||||||
|
- `android/app/upload-keystore.jks`
|
||||||
|
- `android/app/upload_certificate.pem`
|
||||||
- `build/symbols/android/`
|
- `build/symbols/android/`
|
||||||
|
- `build/symbols/ios/`
|
||||||
|
- `dist/release/smoke-android/`
|
||||||
|
- `dist/release/smoke-ios/`
|
||||||
- `sc_images/`
|
- `sc_images/`
|
||||||
- `assets/`
|
- `assets/`
|
||||||
|
|
||||||
@ -88,15 +105,77 @@
|
|||||||
- `app-armeabi-v7a-release.apk` 约 `105.8MB`,比上一轮 `112.6MB` 再少 `6.8MB`
|
- `app-armeabi-v7a-release.apk` 约 `105.8MB`,比上一轮 `112.6MB` 再少 `6.8MB`
|
||||||
- `app-x86_64-release.apk` 约 `115.8MB`,比上一轮 `122.4MB` 再少 `6.6MB`
|
- `app-x86_64-release.apk` 约 `115.8MB`,比上一轮 `122.4MB` 再少 `6.6MB`
|
||||||
- `build/symbols/android` 已生成 3 份符号文件,总计约 `14MB`,后续可用于 Dart 堆栈还原。
|
- `build/symbols/android` 已生成 3 份符号文件,总计约 `14MB`,后续可用于 Dart 堆栈还原。
|
||||||
|
- `scripts/build_release.py --platform android --output-dir dist/release/smoke-android` 已验证通过,归档结果为:
|
||||||
|
- `android/google-play/` 下输出 `yumi-v1.0.0-b1-google-play.aab` 与 Dart symbols
|
||||||
|
- `android/local/` 下输出 `arm64-v8a.apk` 与 `armeabi-v7a.apk`
|
||||||
|
- `android/testing/` 下单独输出 `x86_64-test.apk`
|
||||||
|
- 同时生成 `build_manifest.json`,已记录产物路径、大小和 `sha256`
|
||||||
|
- `scripts/build_release.py --platform ios --output-dir dist/release/smoke-ios` 已验证通过,当前无签名模式下输出:
|
||||||
|
- `ios/archive/yumi-v1.0.0-b1.xcarchive`
|
||||||
|
- `ios/symbols/app.ios-arm64.symbols`
|
||||||
|
- 当前 iOS 无签名构建会跳过 `.ipa` 导出;如需正式 `.ipa`,脚本需追加 `--ios-codesign`
|
||||||
|
- 已将 `dist/` 加入 `.gitignore`,避免打包产物持续污染工作区状态
|
||||||
|
- 本轮按需执行 `flutter build appbundle --release --split-debug-info=build/symbols/android` 已成功,产物为:
|
||||||
|
- `build/app/outputs/bundle/release/app-release.aab`
|
||||||
|
- 当前 AAB 体积约 `181.8MB`
|
||||||
|
- 本地校验 `app-release.aab` 证书后确认:
|
||||||
|
- 证书所有者为 `C=US, O=Android, CN=Android Debug`
|
||||||
|
- 当前 AAB 的 `SHA1` 为 `6B:72:BF:6F:D1:7A:F2:99:CD:F3:14:EE:18:A6:29:67:F8:05:E6:B4`
|
||||||
|
- 这说明当前 release 构建仍在回退使用 debug signing,无法直接作为 Google Play 正式发布包
|
||||||
|
- 已生成新的 upload 证书文件:
|
||||||
|
- `android/app/upload-keystore.jks`
|
||||||
|
- `android/app/upload_certificate.pem`
|
||||||
|
- 新 upload key 当前指纹为:
|
||||||
|
- `SHA1: C1:80:AF:BF:6E:1F:F2:F4:49:58:72:87:A2:BC:54:07:E7:D2:D9:A3`
|
||||||
|
- `SHA256: 81:D6:3A:43:31:FA:83:87:0E:C3:5B:52:B8:C1:05:7C:3A:32:EC:24:37:0B:11:E4:2F:8C:62:4E:D4:AC:0C:3B`
|
||||||
|
- release 构建已改为从 `android/key.properties` 读取正式 upload keystore,不再依赖当前的 debug 回退配置
|
||||||
|
- `flutter build appbundle --release --split-debug-info=build/symbols/android` 已重新执行,当前正式产物仍为:
|
||||||
|
- `build/app/outputs/bundle/release/app-release.aab`
|
||||||
|
- 当前 AAB 体积约 `181.8MB`
|
||||||
|
- 重新校验该 AAB 后,签名者已变为:
|
||||||
|
- `CN=Yumi Upload, OU=Mobile, O=Yumi, L=Shanghai, ST=Shanghai, C=CN`
|
||||||
|
- `deployment_cert.der` 已核实为 Google 侧 app signing 证书,指纹为:
|
||||||
|
- `SHA1: 3F:E1:78:DC:C3:29:4F:74:20:DF:27:54:CF:AF:46:46:D6:A1:94:78`
|
||||||
|
- `SHA256: F9:BF:D0:89:F9:D7:FD:B2:53:24:A7:DB:59:E1:52:6F:54:A3:93:95:4E:88:7F:1C:4B:D6:03:66:E7:1A:1F:85`
|
||||||
|
- 已确认当前存在两套不同证书:
|
||||||
|
- 本地 `upload key`:用于你上传 AAB 到 Google Play
|
||||||
|
- Google `app signing key`:用于 Google Play 最终给用户分发签名包
|
||||||
|
- `FOREGROUND_SERVICE_MEDIA_PROJECTION` 在当前 release 合并报告中的来源已确认是 `io.agora.rtc:full-screen-sharing:4.5.2`
|
||||||
|
- 该依赖同时还带入了:
|
||||||
|
- `io.agora.rtc2.extensions.MediaProjectionMgr$LocalScreenCaptureAssistantActivity`
|
||||||
|
- `io.agora.rtc2.extensions.MediaProjectionMgr$LocalScreenSharingService`
|
||||||
|
- 主 Manifest 已添加 `tools:node="remove"` 覆盖规则,准备重新打包验证最终合并结果
|
||||||
|
- 重新打包后,release manifest merger 报告已显示:
|
||||||
|
- `uses-permission#android.permission.FOREGROUND_SERVICE_MEDIA_PROJECTION`
|
||||||
|
- `REJECTED from [io.agora.rtc:full-screen-sharing:4.5.2]`
|
||||||
|
- 当前 release 中已不再检测到以下声明:
|
||||||
|
- `android.permission.FOREGROUND_SERVICE_MEDIA_PROJECTION`
|
||||||
|
- `io.agora.rtc2.extensions.MediaProjectionMgr$LocalScreenCaptureAssistantActivity`
|
||||||
|
- `io.agora.rtc2.extensions.MediaProjectionMgr$LocalScreenSharingService`
|
||||||
|
- 新的正式产物已重新生成:
|
||||||
|
- `build/app/outputs/bundle/release/app-release.aab`
|
||||||
|
- 当前 AAB 体积仍约 `181.8MB`
|
||||||
|
- 新 AAB 证书仍为本地 upload key:
|
||||||
|
- `SHA1: C1:80:AF:BF:6E:1F:F2:F4:49:58:72:87:A2:BC:54:07:E7:D2:D9:A3`
|
||||||
|
- 本轮按需执行 `flutter build apk --release --split-per-abi --target-platform android-arm64 --split-debug-info=build/symbols/android` 已成功,产物为:
|
||||||
|
- `build/app/outputs/flutter-apk/app-arm64-v8a-release.apk`
|
||||||
|
- 当前 `arm64-v8a` APK 体积约 `128.7MB`
|
||||||
|
|
||||||
## 已知问题
|
## 已知问题
|
||||||
- `ios/Podfile.lock` 还保留旧插件记录,因为本轮未执行 `pod install`;但 Flutter 当前依赖链路已经不再包含已移除插件。
|
- `ios/Podfile.lock` 还保留旧插件记录,因为本轮未执行 `pod install`;但 Flutter 当前依赖链路已经不再包含已移除插件。
|
||||||
- universal APK 仍然会非常大;当前正确发包方式应优先使用 `--split-per-abi` 或直接产出 `aab`。
|
- universal APK 仍然会非常大;当前正确发包方式应优先使用 `--split-per-abi` 或直接产出 `aab`。
|
||||||
- 仍有 `12` 张 `webp` 被 TinyPNG 拒绝解码,推测是动画或特殊编码格式,不能继续直接走 TinyPNG 常规压缩。
|
- 仍有 `12` 张 `webp` 被 TinyPNG 拒绝解码,推测是动画或特殊编码格式,不能继续直接走 TinyPNG 常规压缩。
|
||||||
- `split-debug-info` 会把 Dart symbols 额外落到构建目录,发包时需要和正式包一起留档,不能丢。
|
- `split-debug-info` 会把 Dart symbols 额外落到构建目录,发包时需要和正式包一起留档,不能丢。
|
||||||
|
- iOS 当前验证走的是 `--no-codesign`,因此只产出 `.xcarchive`,不会自动导出可直接分发的 `.ipa`。
|
||||||
|
- Flutter/Xcode 当前给出两条 iOS 提醒:
|
||||||
|
- 未来 iOS 版本将要求 `UIScene` 生命周期支持
|
||||||
|
- Launch image 仍是默认占位资源,提交前建议替换
|
||||||
|
- `android/key.properties` 保存了本地 upload keystore 口令,必须自行妥善备份,且不要提交到仓库
|
||||||
|
- 由于已显式移除 Agora 本地屏幕共享相关组件,如果业务后续要启用“屏幕共享/录屏推流”,需要再单独恢复相关 manifest 声明
|
||||||
|
|
||||||
## 下一步要做什么
|
## 下一步要做什么
|
||||||
- 将新的 Android release 瘦身参数固化进统一打包脚本,并整理产物目录。
|
- 将新的 `AAB` 上传到 Play Console,并在首发流程中继续使用 Google 管理的 app signing key。
|
||||||
- 验证 Python 打包脚本的 Android 产物归档结果,再补 iOS 流程验证。
|
- 在需要配置 Google 登录、Firebase、支付等生产环境指纹时,优先登记 Google 的 `deployment_cert.der` 指纹;如平台要求上传者证书,再额外登记本地 upload key 指纹。
|
||||||
|
- 如果需要正式 iOS 分发包,为 `scripts/build_release.py` 补入 `--ios-codesign` 所需签名参数并导出 `.ipa`。
|
||||||
- 继续评估 Agora 扩展库是否都需要,优先核查 `lip sync`、`spatial audio`、`clear vision`、`segmentation`、`face capture` 等扩展 so 能否裁剪。
|
- 继续评估 Agora 扩展库是否都需要,优先核查 `lip sync`、`spatial audio`、`clear vision`、`segmentation`、`face capture` 等扩展 so 能否裁剪。
|
||||||
- 决定是否处理剩余 12 张特殊 `webp`:改格式、换压缩工具,或维持现状。
|
- 决定是否处理剩余 12 张特殊 `webp`:改格式、换压缩工具,或维持现状。
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user