Delphi 10.4.2 CE 社区版支持 Android API-30,之二

news/2025/2/2 5:48:17/

前情回顾

话说直接修改程序项目的 AndroidManifest.template.xml,将  API-level 从通配符改为写死的 30 后,可以编译发布出 AAB 文件,而且这个 AAB 文件上传到 Google play 它没提示 API-level 是 29 不合格,算是通过了。但是,如果选择程序项目的 Configuration 为 Development,手机插上电脑,重新编译发布安装到手机上,安装失败,错误提示:INSTALL_PARSE_FAILED_NO_CERTIFICATES

解决方法

俺满世界搜索,用尽了各种搜索工具,搜了一堆东西出来,有类似的问题,但都是 Xamarin 的或者其它什么鬼开发工具的,没有 Delphi 的。找不到答案。

然后去了一个德国的 Delphi 论坛发了个帖子提问,然后有个大神给出了解决方案。一试,果然有效。这是那个德国网站我发的帖子的地址:

https://en.delphipraxis.net/topic/5883-delphi-1042-ce-support-android-api-30/

这里总结一下具体的原因和做法:

原因:

It's because Delphi 10.4.2 is using Jarsigner instead of APKSigner

解决办法:

For sign apk by Jarsigner ( APK Signature Scheme v2 ) you need: 

1. Edit CodeGear.Deployment.Targets  add section:

  <Target Name="_AndroidApkSigner" Condition="('$(Platform)'=='$(cAndroid32ArmPlatform)' Or '$(Platform)'=='$(cAndroid64ArmPlatform)') And '$(KeyStoreFile)'!='' And '$(AndroidAppBundle)'=='false'"><Message Text="Start Apk Signer."/><Exec Command="&quot;$(ApkSigner)&quot; sign --ks $(KeyStoreFile) --ks-pass pass:$(KeyStorePass) $(SIGNED_APK_FILENAME)" ContinueOnError="True"><Output TaskParameter="ExitCode" PropertyName="ErrorCode"/><Output TaskParameter="StdOutEncoding" PropertyName="StdOut"/></Exec></Target>

2. add line _AndroidApkSigner; in section <DeployDependsOnTargets>

  <PropertyGroup><DeployDependsOnTargets>..._CheckKeyStore;_AndroidSign;_AndroidZipAlign;_AndroidApkSigner; _CheckAPKFileOutputResult;_CheckAABFileOutputResult;_DeleteAndroidAssetsInfoFile;...</DeployDependsOnTargets>

备注:CodeGear.Deployment.Targets 这个文件,在 Delphi 的安装目录底下。

3. Create New IDE Environment Variable ApkSigner with value (SDK path)\android-sdk-windows\build-tools\29.0.2\apksigner.bat

比较修改前和修改后的 CodeGear.Deployment.Targets 文件

 

总结一下

简单说来,对于 Delphi 10.4.2 编译发布的 Android 程序,要支持到 API-level 30,需要做:

1. 修改 AndroidManifest.template.xml,将原本的:

<uses-sdk android:minSdkVersion="%minSdkVersion%" android:targetSdkVersion="%targetSdkVersion%" />

修改为:

<uses-sdk android:minSdkVersion="%minSdkVersion%" android:targetSdkVersion="30" />

然后 Build 以后,创建的 AndroidManifest.xml 文件的内容就从原本的:

<uses-sdk android:minSdkVersion="%minSdkVersion%" android:targetSdkVersion="29" />

自动变成了:

<uses-sdk android:minSdkVersion="%minSdkVersion%" android:targetSdkVersion="30" />

2. Delphi 原本安装时带来的 SDK 支持的平台只有29,路径如下:

C:\Users\Public\Documents\Embarcadero\Studio\21.0\CatalogRepository\AndroidSDK-2525-21.0.40680.4203\platforms\android-29

需要执行 SDKManager.bat 去下载升级30的,升级方法见上一篇文章,升级后在以下路径:

C:\Users\Public\Documents\Embarcadero\Studio\21.0\CatalogRepository\AndroidSDK-2525-21.0.40680.4203\platforms

底下有两个文件夹,一个是原来就有的 android-29,一个是新增的 android-30

然后修改 DELPHI IDE 菜单里面关于安卓的 SDK 的 API-level 的指向的配置。做法见上一篇文章。

3. 最后就是修改签名方式,如本文前面所述。

最后一个坑

按照上述方式,新建一个 FireMonkey 工程,编译目标选择安卓64,没有任何问题。不管是 Development 模式下直接安装到手机里面,还是 Application store 模式下编译发布为 AAB 文件,一切顺利。

但对于我的一个老的工程,在 debug 模式下没有问题,在 Release 模式下,用 Development 方式编译安装到手机里面,INSTALL_PARSE_FAILED_NO_CERTIFICATES 这个错误依然存在,安装失败。拿它的 xml 文件和安装成功的工程的 xml 文件仔细来回对比,看不出哪里有不对。

于是,俺干脆重建一个新的工程,把老工程的所有代码都加进去,对于这个新工程,同样做如上描述的修改,编译发布安装到手机成功,并且 APP 运行也很正常。

备注一个小问题

我的老工程,有个函数里面,定义了一个局部变量,整数类型。该函数里面用到那个变量之前,没有做初始化。通常 Delphi 会自动把整数初始化为 0. 之前在安卓下,API level 为 29,程序运行没有任何问题。但只要改为 30,就有问题。追查好久才发现是该变量没有初始化导致。在函数一开始给该变量赋值 0,然后在 API level 30 下编译跑起来,问题消失。

经验教训总结:局部变量一定要自己用代码初始化,不要依赖 Delphi 编译器的默认。


http://www.ppmy.cn/news/345958.html

相关文章

网络套接字编程

之前我们粗浅的认识了一下网络的一些知识&#xff0c;比如OSI七层模型&#xff0c;TCP/IP四层模型&#xff0c;那么我们具体怎么实现两台主机的交互呢&#xff1f; 在学习这些之前&#xff0c;我们需要准备一些预备知识。 目录 预备知识 1:认识源IP地址和目的IP地址 2&…

Linux环境下,使用ssh测试TCP端口是否开放

在工作中&#xff0c;一些软硬件的工程师去现场安装软件后&#xff0c;发现出现各种异常&#xff0c;然后忙前忙后排查&#xff0c;最后才发现原来是现场的防火墙端口没有开放。 其实网络上也有很多排查端口是否开放的方法&#xff0c;我这里只写一下咱们怎么在Linux操作系统之…

ArcGIS距离分析—规划最低成本路径

先给自己搞一个存放操作结果的数据库&#xff0c;然后把它设置为临时存放操作结果的位置。 把用到的数据加载进来&#xff1a;起点、终点、DEM、土地分类数据。 计算成本数据&#xff1a;包括重分类的坡度、起伏度数据。 首先使用DEM数据生成坡度数据。 坡度数据的像元大小…

zzuli 2525: 咕咕的搜索序列(dfs合法序列)

2525: 咕咕的搜索序列 时间限制: 1 Sec 内存限制: 128 MB 提交: 371 解决: 40 [提交] [状态] [讨论版] [命题人:外部导入] 题目描述 咕咕已经学到树上的深度优先搜索 (dfs) 啦&#xff01;由于同一棵树不同的 dfs 访问结点的次序不一样&#xff0c;咕咕干脆定义 了一个搜索序列…

分布式架构之EasyES---和 Mybatis用法相似,太方便了

一、EasyES是什么&#xff1f; Easy-Es&#xff08;简称EE&#xff09;是一款基于ElasticSearch(简称Es)官方提供的RestHighLevelClient打造的ORM开发框架&#xff0c;在 RestHighLevelClient 的基础上,只做增强不做改变&#xff0c;为简化开发、提高效率而生,您如果有用过Myb…

python基本语法知识(五)——面向对象

类和对象 例子1 class Student:name Nonegender Nonenationality Nonenative_place None # 籍贯age None# 类内的成员方法,第一个参数必须为 self,# self相当于是当前对象def say_hi(self):print(f"大家好,我是{self.name}")def say_hi2(self, msg):print(f&q…

1.2 几种常用的数制

学习目标&#xff1a; 学习几种常用的数制可以通过以下步骤进行&#xff1a; 1. 确定目标数制&#xff1a;常用的数制包括十进制、二进制、八进制和十六进制。首先&#xff0c;确定你想要学习的数制是哪一种。 2. 理解基本概念&#xff1a;了解每种数制的基本概念是非常重要…