19

My project has dynamic feature module and I would like to generate debug or release APK including the dynamic feature. Currently I can get only base APK file.

Basically I would generate an APK file like normal application. But I couldn't do with dynamic feature. Yes, I know dynamic feature will work based on AAB.

Is there any ways to make a normal(base + all modules) APK file?. Please help on this.

Thanks

chain
  • 649
  • 10
  • 22

3 Answers3

29

I don't see it documented anywhere, but the Android Gradle build tools include tasks to extract the universal APK for you. You can use something similar to:

./gradlew :yourmodule:packageDebugUniversalApk

Under the hood it uses bundletool and does essentially the same thing as the other answer, but it's nice to be able to do it from Gradle.

kabuko
  • 36,028
  • 10
  • 80
  • 93
  • 2
    Does this generate an apk with all modules or only the modules marked with `` – May Rest in Peace Jul 24 '20 at 10:15
  • 1
    According to the resulting apk-size and a runtime check for installed modules only modules with `` will be included. – Phil Oct 14 '20 at 14:08
  • Yes, only those modules are included. This is specified in the [bundletool docs](https://developer.android.com/studio/command-line/bundletool#generate_apks): "Note: bundletool includes only feature modules that specify `` in their manifest in a universal APK." – kabuko Oct 14 '20 at 17:34
22

You can specify if your on demand module needs to be included in the universal APK that is usually generated for older devices, and then you can use bundletool to generate an Universal APK from the App Bundle:.

In this particular case, you can use something like:

bundletool build-apks --bundle <bundle_file> --output <APKS file> --ks <key_store> --key-pass <jks password> --ks-key-alias <key_alias> --ks-pass <key password> --overwrite --mode=universal

The key point is to include the --mode=universal this instruct bundletool to generate an Universal APK that will include all modules that have <dist:fusing dist:include="true"/> in the manifest.

In a similar way, when you run your project from Android Studio on a device, using the default configuration for Run (Deploy = Default APK) it includes all of your on demand modules.
Instead, when you run the application from Studio using the Run configuration (Deploy = APK from AppBundle) you can pick and choose which modules are installed.

However, in both cases, you cannot test on demand module downloads if you don't go through the Play store.

Note (November 2020)

As reported in another answer below, the Android Gradle Plugin includes a couple of undocumented tasks that can be used to generate Debug and unsigned Release universal APKs of your application.

The task related to the Debug version can be a quick alternative if you just need this type of build:

./gradlew :app:packageDebugUniversalApk

This task will generate (by default) app/build/outputs/universal_apk/debug/app-debug-universal.apk.

Update June 2019

Google introduced at I/O Internal App Sharing that allows to allow testing easily your App Bundles and APKs, including debug builds:

With internal app sharing, you can quickly share an app bundle or APK with your internal team and testers by uploading an APK or app bundle on the internal app sharing upload page.

pfmaggi
  • 6,116
  • 22
  • 43
  • @pfmaggi, Do I need to upload apk+aab to playstore to check how demand module works ? – Lucifer Jun 04 '19 at 05:47
  • 1
    No, you just need to upload the android App Bundle. You can follow this codelab to see how to do it: https://codelabs.developers.google.com/codelabs/on-demand-dynamic-delivery/index.html – pfmaggi Jun 05 '19 at 08:45
  • @pfmaggi How can I share this for testing rather than Google Play Store Beta? – Chathura Wijesinghe Jun 28 '19 at 08:53
  • I've updated the answer with information about internal app sharing. – pfmaggi Jun 28 '19 at 09:31
  • 1
    When generating with the `--mode=universal` option, there is APK generated that inside that contain another APK, and only the inside APK is the correct one and can be installed on real device. – jazzyjester Oct 07 '19 at 09:25
  • With the `build-apks` command you generate an APKS archive that includes all the APK files. But because you are building an universal APK, inside the archive you just have one APK, plus a metadata file. – pfmaggi Oct 07 '19 at 12:03
  • is there a way to extract-apps without a device configuration specified? just found it, you can just use `unzip` :) – jacoballenwood Jun 15 '21 at 15:15
1

Download bundletool jar file from Github (Latest release > Assets > bundletool-all-version.jar file). Rename that file to bundletool.jar

  1. Generate your aab file from Android Studio eg: myapp-release.aab
  2. Run following command:

java -jar "path/to/bundletool.jar" build-apks --bundle=myapp-release.aab --output=myapp.apks --ks="/path/to/myapp-release.keystore" --ks-pass=pass:myapp-keystore-pass --ks-key-alias=myapp-alias --key-pass=pass:myapp-alias-pass

  1. myapp.apks file will be generated
  2. below is the command to generate the universal apk

java -jar bundletool.jar build-apks --bundle=nhl.aab --output=nhl.apks --mode=universal

`

Vivek Samele
  • 340
  • 4
  • 8