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

51 篇文章 6 订阅
44 篇文章 0 订阅

前情回顾

话说直接修改程序项目的 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 编译器的默认。

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值