Generating a universal APK from an AAB to distribute it via AppCenter

Learn to convert an AAB to a universal APK for easy distribution via AppCenter.

TL;DR

Install bundletool:

brew install bundletool

Generate APK set from AAB containing a universal APK:

bundletool build-apks --bundle=[path_to_aab] --ks="[keystore].keystore" --ks-pass=[keystore_password] --ks-key-alias="[keystore_alias]" --key-pass=[key_password] --mode=universal --output=output.apks

Unzip the APK set:

unzip -o [path_to_apk_set].apks

Introduction

In 2017, Google introduced the Android App Bundle – AAB as the new format to deliver your app to Google Play. It replaces the old APK file format, with good reason. There are thousands of different Android devices out there, with each of them having its own specifications (screen size, screen resolution etc.). Before the deployment as an Android App Bundle, when building your app for release there was one artifact (APK) created that had to work for all kinds of devices.

By uploading an Android App Bundle (AAB) to Google Play, you enable Google to generate several highly optimized APKs for all the different devices.

Now, there is one problem when before to uploading your app for release to Google Play you want to deploy it to testers via Microsoft AppCenter: AppCenter still only accepts artifacts in APK format. So in this article, I describe a way to generate a universal APK from an AAB that you can then upload to AppCenter.

The solution

The solution to this problem is in fact quite simple: Using a tool called bundletool you take an AAB and generate an APK from it that you can then upload to AppCenter.

In fact, bundletool, which is a tool from Google, is the exact tool Google uses to generate the different APKs from the AAB you upload to Google Play.

Getting bundletool

Other than you might think, bundletool is not preinstalled with the Android SDK. There are different ways to get it. A quite convenient way I recommend is to download it via the package manager Homebrew, using it's install command:

brew install bundletool

After the installation I like to double-check whether everything went well by just calling bundletool version. This should output the current version of bundletool, which by the time writing this article is 1.9.1:

> bundletool version
1.9.1

Finally, Now that bundletool is installed, in the next step you can actually generate the APK file.

Generating APK from AAB

At this point I assume that you already build your AAB, probably using some kind of release configuration. The next step is to generate the APK from the AAB.

At first, I want to give you the complete command and dissect it afterwards:

bundletool build-apks --bundle=[path_to_aab] --ks="[keystore].keystore" --ks-pass=[keystore_password] --ks-key-alias="[keystore_alias]" --key-pass=[key_password] --mode=universal --output=output.apks

Alright, that might look quite intimidating at first. But let’s look at it one piece at the time.

The first thing that is passed to bundletool is the build-apks subcommand. bundletool itself has in fact several capabilities, or say subcommands, that can do all kinds of things. It is a general tool to work with AABs.

It can do things like validate an AAB, compute the sizes of APKs generated from it, or print out the device specs of a connected Android device. The subcommand we are using at this point is the build-apks subcommand which, as the name suggests, can build APKs from an AAB.

The next parameter that is passed is the --bundle parameter. With it you must pass the path to the created AAB file of your app.

The next parameter is very important: --mode=universal. Now, as stated above, using an AAB enables Google to generate highly optimized APKs for different devices. However, at this point this is not what we want. We do not need several different APKs. We just want one “old-fashioned" APK that works for every device and that can be uploaded to AppCenter. By passing the -–mode=universal parameter, bundletool does exactly that. Since the version that is deployed via AppCenter is only for testing purposes, I’m ok with the fact that this APK might be larger than the one users will later download from Google Play.

Extracting the APK from the APK Set

As you might have already seen, the command executed above did not directly generate the APK you need but a file with the extension .apks. It generated what is called an APK set. Since the build-apks subcommand was executed using the mode=universal parameter, this APK set should only contain a single APK file that works for every kind of device.

Technically, an APK set is just a zip archive. So, to unpack the APK set you can simply use the unzip command on the command line:

unzip -o [path_to_apk_set].apks

After unzipping the APK set, you should find a universal.apk in the folder.

Now that you unpacked the APK set you might be thinking about signing the APK. Well, then I have good news for you: Since we already passed all the signing credentials to bundletool earlier, the APK that was contained in the APK set is already signed and thus ready to be uploaded to AppCenter.

Conclusion

In this article, I described how to generate an upload signed, universal APK from an Android App Bundle (AAB) to be distributed to testers via Microsoft AppCenter.

Thanks for reading this article! If you liked it and it helped you in any way getting a grasp on a new topic, the best way to support this blog is just by sharing it with others. However, if you would like to support me and my work more directly you can just buy me a cup of coffee (which as we know will eventually be converted into code):

Additional resources

https://github.com/google/bundletool

https://developer.android.com/studio/command-line/bundletool