1

I am looking to generate a second debug.apk in a different file location within the project path. Is it possible to create a second file path location for the .apk build within gradle?

The current build path is:

C:\..\app\build\outputs\apk\debug\debug.apk

I would like to create a second apk location after the build, for example:

C:\..\app\debug_apk\debug.apk

I am currently changing the names of the output files in gradle with:

applicationVariants.all { variant ->
    variant.outputs.all { output ->
        def appVersionName = "company_name_${versionName}"
        switch (buildType.name) {
            case "debug": {
                outputFileName = "${appVersionName}_debug.apk"
                break
            }
            case "release": {
                outputFileName = "${appVersionName}_release.apk"
                break
            }
        }
    }
}
Eugene H
  • 3,520
  • 3
  • 22
  • 39

2 Answers2

1

Here's an app module build script that provides the following:

  • Creates copy*Apk task that collects the APK for each build variant.
  • Creates copyApks task that collects the APKs for all build variants.
  • (Optional) Causes assemble* tasks to also collect their specific APKs.
build.gradle.kts
// Create an umbrella task that will collect APKs from all build variants.
val copyApks = tasks.register("copyApks")

android {
    applicationVariants.all {
        val variantName = name

        // Create variant-specific task that collects the APK.
        val copyApk = tasks.register<Copy>("copy${variantName.capitalize()}Apk") {

            // Copy output files from the task that produces the APK...
            from(packageApplicationProvider)

            // ...into a directory relative to module source root.
            into(file("${variantName}_apk"))

            // Filter out any metadata files, only include APKs.
            include { it.name.endsWith(".apk") }

            // Change the output file name.
            // Only works if there's a single APK for each variant.
            // This will not work with APK splits enabled.
            rename { "${variantName}.apk" }
        }

        // Register the variant-specific task under the umbrella task.
        copyApks.dependsOn(copyApk)

        // (Optional) collect variant-specific APKs when assemble task is invoked.
        assembleProvider.dependsOn(copyApk)
    }
}
build.gradle

If you're using Groovy these are the lines that would be different:

def copyApks = tasks.register("copyApks")
// ...
def variantName = name
// ...
def copyApk = tasks.register("copy${variantName.capitalize()}Apk", Copy) { // ...

Usage

./gradlew copyApks
./gradlew app:copyDebugApk
./gradlew app:copyReleaseApk
./gradlew app:assemble

Result

Output file hierarchy 1 Output file hierarchy 2

Differences

  • Original APK paths aren't hardcoded. Instead they're derived from whatever Android Gradle Plugin uses. It automatically supports product flavors.
  • The collecting tasks depend on the original packaging tasks and participate in Gradle up-to-date checks. When the sources/APKs don't change, they're not re-collected.
  • The clean task doesn't delete the collected APKs.
Eugen Pechanec
  • 37,669
  • 7
  • 103
  • 124
0
apply plugin: 'android'

def outputPathName = "D:\build.apk"
def secondDir= "D:\backup\build.apk"

android {
    compileSdkVersion 19
    buildToolsVersion "19.0.3"

    defaultConfig {
        minSdkVersion 8
        targetSdkVersion 19
        versionCode 1
        versionName "1.0"
    }
    buildTypes {
        release {
            runProguard false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
        }
    }

    def publish = project.tasks.create("publishAll")
    android.applicationVariants.all { variant ->
    variant.outputFile = file(outputPathName)
    def task = project.tasks.create("publish${variant.name}Apk", Copy)
    task.from(variant.outputFile)
    task.into(secondDir)

    task.dependsOn variant.assemble
    publish.dependsOn task
  }

}

dependencies {
    compile 'com.android.support:appcompat-v7:19.+'
    compile fileTree(dir: 'libs', include: ['*.jar'])
}

task cleanExtra(type: Delete) {
    delete outputPathName
}

clean.dependsOn(cleanExtra)

This code is combination from this resource and this answer

user16930239
  • 6,319
  • 2
  • 9
  • 33