23

I would like to change the APK output folder and this is what I used to do:

applicationVariants.all { variant ->
    variant.outputs.all {
        def filePath = "${rootProject.rootDir.absolutePath}/apks/${variant.name}"
        println("My Path: " + filePath)
        outputFileName = filePath
    }
}

However, it didn't work in Gradle 4.1 (Android studio 3.0 preview). Instead of generating the folder as the path above, it generated the above path inside old debug folder like image below:

enter image description here

Does anyone have a solution for this? Thanks.

azizbekian
  • 60,783
  • 13
  • 169
  • 249
Kingfisher Phuoc
  • 8,052
  • 9
  • 46
  • 86
  • 1
    Did the output directory change between `gradle` 3 and 4? `platforms/android/build/outputs/apk/android-release.apk` and `platforms/android/build/outputs/release/android-release.apk`. This difference is breaking our builds and we're not sure if it is Gradle. – Robula Nov 14 '17 at 13:00

3 Answers3

25

This is a workaround to keep the output path same after upgrade to gradle 4.x.

applicationVariants.all { variant ->
    variant.outputs.all {
        outputFileName = "../" + outputFileName
    }
}

now apk is generated at platforms/android/build/outputs/apk/android-release.apk

Harry Han
  • 271
  • 4
  • 7
  • This is what I am looking for. – Aman Jain Apr 11 '18 at 06:17
  • This stopped working after upgrading to `com.android.tools.build:gradle:7.4.0`. Now the builder drops this warning and ignores location change: Setting outputFileName to '../../myfilename.apk' can result in incorrect behavior. Relative paths are not supported when setting an output file name. The outputFileName API supports changing the output file's name, but not its location. – Alexey Ozerov Jan 19 '23 at 02:51
22

From migration guide:

Using the Variant API to manipulate variant outputs is broken with the new plugin. It still works for simple tasks, such as changing the APK name during build time, as shown below:


    android.applicationVariants.all { variant ->
        variant.outputs.all {
            outputFileName = "${variant.name}-${variant.versionName}.apk"
        }
    }

However, more complicated tasks that involve accessing outputFile objects no longer work. That's because variant-specific tasks are no longer created during the configuration stage. This results in the plugin not knowing all of its outputs up front, but it also means faster configuration times.

azizbekian
  • 60,783
  • 13
  • 169
  • 249
13

I had a similar issue, because I needed the output apk in a known folder and not in a folder depending on the computer user name. So I have fixed like this:

applicationVariants.all { variant ->
    variant.outputs.all {
        def apk = output.outputFile;
        def newName = apk.name.replace(".apk", "-v" + variant.versionName + "-RELEASE.apk");
        newName = newName.replace("-" + variant.buildType.name, "");

        outputFileName = "./" + newName
    }
}

With this I get the apk in: ".../outputs/apk/flavorName/buildTypeName/xxx.apk"

Hope it helps you.

Marta Rodriguez
  • 1,944
  • 2
  • 16
  • 30
  • This solution worked for me - looks like it should be marked as the answer – Gene Bo Dec 25 '17 at 00:28
  • This code throw an exception as "Gradle sync failed: Could not get unknown property 'output' for ApkVariantOutputImpl_Decorated" on Gradle v4.4. `output.outputFile` should be changed as `outputFileName`. – wonsuc Apr 07 '18 at 22:40
  • And last code will throw "Absolute path are not supported when setting an output file name." – wonsuc Apr 07 '18 at 22:42
  • I have edited the answer to work with the last version of gradle. – Marta Rodriguez Apr 09 '18 at 06:07