使用 Adobe AIR 重新打包 APK



有一个用Flash制作的Android游戏是使用Adobe AIR打包的,但它不再适用于7以上的Android版本。我想知道是否可以使用哈曼的Adobe AIR重新打包这款游戏?

我已经下载了 HARMAN 的 Adobe AIR,并尝试使用 ADT 打包命令重新打包应用程序。我使用了APKassets/META-INF/AIR/文件夹中存在的application.xml文件。但是,此应用程序使用扩展名,并且似乎 ADT 需要 ANE(AIR 本机扩展)文件,或者还有其他方法?

我无法在线找到 ANE 文件。但是一些中国黑客能够在Android 10中重新打包该应用程序,并且文件夹assets/META-INF/AIR/extensions文件夹与原始apk相比没有任何变化。但是,文件夹中的文件lib/armeabi-v7a已更新,并包括一个名为libX86Bridge.so的新文件。

原始应用使用的扩展程序包括:

  • com.adobe.ane.social
  • com.milkmangames.extensions.AndroidIAB
  • com.chartboost.plugin.air
  • com.milkmangames.extensions.CoreMobile
  • com.jirbo.airadc.airAdColony
  • com.milkmangames.extensions.GoViral

所以我终于能够重新打包APK,它适用于最近的Android版本!

首先,我使用存档管理器打开了APK文件(APK是一个ZIP文件),然后使用dex2jar工具将APK中的classes.dex文件转换为JAR文件。JAR 文件(也是 ZIP 文件)内部是应用程序使用的 AIR 本机扩展中编译的 Java 类。

然后,在 Adobe AIR by HARMAN 的bin目录中,我为每个扩展创建了一个目录:

AIRSDK_Windowsbin
├── com.adobe.ane.social
├── com.milkmangames.extensions.AndroidIAB
├── com.chartboost.plugin.air
├── com.milkmangames.extensions.CoreMobile
├── com.jirbo.airadc.AirAdColony
├── com.milkmangames.extensions.GoViral

解压缩的扩展 ANE 可以在 APK 内部的路径/assets/META-INF/AIR/extensions/中找到。

对于每个扩展名,将catalog.xmllibrary.swf添加到 ZIP 文件中,并将 ZIP 扩展名重命名为 SWC(例如:com.adobe.ane.social.swc)。然后,将 SWC 文件放在相应扩展名的目录中。

在APK的每个扩展名的目录中,都有一个路径META-INF/ANE/,可以在其中找到文件extension.xml和其他文件(例如:/assets/META-INF/AIR/extensions/com.adobe.ane.social/META-INF/ANE/)。我将这些目录中的所有文件放在我在bin目录中创建的相应扩展名的目录中。例如,对于com.chartboost.plugin.air扩展,目录结构如下所示:

AIRSDK_Windowsbin
├── com.adobe.ane.social
├── com.milkmangames.extensions.AndroidIAB
├── com.chartboost.plugin.air
│   ├── com.chartboost.plugin.air.swc
│   ├── extension.xml
│   ├── Android-ARM
├── com.milkmangames.extensions.CoreMobile
├── com.jirbo.airadc.AirAdColony
├── com.milkmangames.extensions.GoViral

我打开了extension.xml文件,以下是它的内容:

<extension xmlns="http://ns.adobe.com/air/extension/16.0">
<id>com.chartboost.plugin.air</id>
<versionNumber>5.5.0</versionNumber>
<platforms>
<platform name="Android-ARM">
<applicationDeployment>
<nativeLibrary>libChartboostAir.jar</nativeLibrary>
<initializer>com.chartboost.plugin.air.ChartboostExtension</initializer>
<finalizer>com.chartboost.plugin.air.ChartboostExtension</finalizer>
</applicationDeployment>
</platform>

<platform name="iPhone-ARM">
<applicationDeployment>
<nativeLibrary>libChartboostAir.a</nativeLibrary>
<initializer>ChartboostExtInitializer</initializer>
<finalizer>ChartboostExtFinalizer</finalizer>
</applicationDeployment>
</platform>

<platform name="default">
<applicationDeployment/>
</platform>

</platforms>
</extension>

由于我不是为了iPhone-ARM打包游戏,也没有libChartboostAir.a文件,所以我评论说platform使用 XML 注释阻止<!-- -->

我们可以看到有一个default平台(我注意到所有扩展都有一个)。因此,我为default平台创建了一个目录,并将library.swfAndroid-ARM目录复制到其中。然后将两个目录放在一个platform目录中。目录结构现在如下所示:

AIRSDK_Windowsbin
├── com.adobe.ane.social
├── com.milkmangames.extensions.AndroidIAB
├── com.chartboost.plugin.air
│   ├── com.chartboost.plugin.air.swc
│   ├── extension.xml
│   ├── platform
│   │   ├── Android-ARM
│   │   │   ├── library.swf
│   │   │   ├── <other bunch of files>
│   │   ├── default
│   │   │   ├── library.swf
├── com.milkmangames.extensions.CoreMobile
├── com.jirbo.airadc.AirAdColony
├── com.milkmangames.extensions.GoViral

然后,从我们一开始得到的 JAR 文件(从classes.dex转换而来)中,我得到了与com.chartboost.plugin.air相关的所有类,并将它们放在一个名为libChartboostAir.jar的 ZIP 存档中。然后我把libChartboostAir.jar放在Android-ARM目录中。

最后,对于此扩展,我运行以下命令来生成 ANE 文件:

..adt.bat -package -target ane com.chartboost.plugin.air.ane extension.xml -swc com.chartboost.plugin.air.swc -platform Android-ARM -C platform/Android-ARM . -platform default -C platform/default library.swf

我按照上述步骤为其他扩展名生成了 ANE 文件。最后,JAR文件中有一些类(从classes.dex生成)我没有从任何扩展名放在JAR文件中,因为我不知道它们属于哪里。因此,我只是将它们放在随机扩展名的JAR文件中。这不是问题,因为重要的是所有类最终都放置在新的classes.dex文件中,使用与原始类相同的目录结构。

编译完所有 ANE 文件后,我在bin目录中为要重新打包的应用程序创建了一个目录。

在原始APK的assets目录中,有该应用程序的SWF文件和一个带有该应用程序图标的_Pic_Gen目录。我将它们都放在刚刚创建的目录中。在原始APK的/assets/META-INF/AIR/目录中,有一个application.xml文件和一个extensions目录(带有解压缩的ANE)。我将application.xml文件放在bin目录中为应用程序创建的目录中。在这个目录中,我还创建了一个extensions目录,并将编译的 ANE 文件放在其中。因此,此应用的目录结构现在如下所示:

AIRSDK_Windowsbin
├── MyApp
│   ├── application.xml
│   ├── _Pic_Gen
│   ├── MyApp.swf
│   ├── extensions
│   │   ├── com.adobe.ane.social.ane
│   │   ├── com.milkmangames.extensions.AndroidIAB.ane
│   │   ├── com.chartboost.plugin.air.ane
│   │   ├── com.milkmangames.extensions.CoreMobile.ane
│   │   ├── com.jirbo.airadc.AirAdColony.ane
│   │   └── com.milkmangames.extensions.GoViral.ane

我将application.xml内部清单中的targetSdkVersion更改为 30,以支持 Android 11(目前是最新的)。安卓版本与SDK关联:https://developer.android.com/studio/releases/platforms

我还<application xmlns="http://ns.adobe.com/air/application/17.0">更改为<application xmlns="http://ns.adobe.com/air/application/33.1">,以便它使用最新的 Flash Player 版本(33.1 来自 HARMAN )。

然后,我使用 OpenSSL 创建了一个自签名证书(为此我使用 Linux):

openssl req -newkey rsa:2048 -x509 -keyout cakey.pem -out cacert.pem -days 10000
# entered my password
openssl pkcs12 -export -in cacert.pem -inkey cakey.pem -out myapp.p12

最后,我可以使用以下方法打包新的APK:

..adt.bat -package -target apk -storetype pkcs12 -keystore myapp.p12 MyApp.apk application.xml -extdir extensions MyApp.swf _Pic_Gen
# entered certificate's password

编辑2021-05-19 (编辑 2022-02-19:最新的Adobe AIR by HARMAN 不再需要此步骤。

但是,对于 Android 11 及更高版本,APK 现在必须使用 APK 签名方案 v2 或更高版本进行签名(请参阅此内容:https://stackoverflow.com/a/66041713/3049315)。使用apksigner(在 Android SDK 中可用),您可以按如下方式执行此操作:

C:Users<user>AppDataLocalAndroidSdkbuild-tools<version>apksigner.bat sign -v --out MyApp_v2signed.apk --ks myapp.p12 MyApp.apk

然后生成APK,我可以在最近的Android版本上玩游戏。

编辑 2021-06-25

显然,在某些设备上,打开APK时会出现错误,说"解析此软件包时出现问题"。

使用Android Studio分析APK时遇到的错误是:INSTALL_PARSE_FAILED_RESOURCES_ARSC_COMPRESSED

然后我在 AIR SDK 中遇到了这个问题。打开AIRSDK_Windowslibadt.cfg向我展示了注释的行:#UncompressedExtensions=emd,tfl,tflite,pb我取消了注释,并添加了arsc扩展名,这是Android Studio抱怨的文件resources.arsc的扩展名。这修复了使用新配置重新打包 APK 后的问题。

编辑 2022-02-11

对于最新的Adobe AIR,如果不希望使用Android SDK进行构建,则应将以下行添加到application.xml<android>部分下的文件中。请参阅:https://github.com/airsdk/Adobe-Runtime-Support/issues/1527#issuecomment-1007293682

<BuildLegacyAPK>true</BuildLegacyAPK>

另一种选择是使用 Android SDK 进行构建,在这种情况下,应在文件AIRSDK_Windowslibadt.cfg中添加以下行(替换为正确的路径):

AndroidPlatformSDK=C:/Users/<user>/AppData/Local/Android/Sdk
JAVA_HOME=C:/Program Files/Java/jdk-11.0.14

请注意,必须使用 Java 11 或更高版本。

此外,Android 12 现在要求具有意图过滤器的接收器具有android:exported属性 .例:

<receiver android:name="com.milkmangames.extensions.android.CMBootReceiver" android:exported="false">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
</intent-filter>
</receiver>

最新更新