After searching 2 days on the internet I wasn't able to find a way to rename the output file name of android-test.apk (for instrumented tests). I am building debug and instrumented tests apk with assembleAndroidTest and assembleDebug.
For debug build I managed to change the name and add version, but I couldn't do it for androidTest.apk. How can I add the same version and other name for test apk?
Here is my build.gradle (module)
android {
compileSdkVersion 29
buildToolsVersion "29.0.0"
project.archivesBaseName = "Automator"
defaultConfig {
applicationId "com.xxx.automator"
minSdkVersion 18
targetSdkVersion 29
versionCode 1
versionName "1.1"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
debug {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
android.applicationVariants.all { variant ->
variant.outputs.all {
def appName = "Automator"
outputFileName = appName + "-${variant.versionName}.apk"
}
}
}
}
}
Add this code to your app build.gradle:
android {
// Make custom APK name for test builds
testVariants.all { testVariant ->
testVariant.outputs.all { output ->
outputFileName = "CustomNameTest.apk"
}
}
}
Put the following code in your app 'build.gradle' file
android {
buildTypes {
applicationVariants.all { variant ->
variant.outputs.all {
outputFileName = "Your_Desired_Name.apk"
}
}
}
This will work with latest sdk as well as latest os version.
Related
As I have tried these 2 ways (using a single at a time) to rename the APK
Option - One
// To Change the APK and Bundle Name
archivesBaseName = "${name}-v${versionCode}_${versionName}-${new Date().format('ddMMMyyyy_HH-mm')}"
Option - Two
(for this also tried to change the - variant.outputs.all to variant.outputs.each)
android.applicationVariants.all { variant ->
variant.outputs.all { output ->
output.outputFileName = "${variant.buildType.name}-v${versionCode}_${versionName}-${new Date().format('ddMMMyyyy_HH-mm')}.apk"
}
}
When I use option One,
Issue - it generates all splits but it overrides the flavor config with the
last flavor written in Gradle.
Also, try to put option One only once in defaultConfig but as productFlavours written after that it returns the null value in versionCode and versionName.
productFlavors {
aFlavor {
applicationId "com.a"
versionCode 5
versionName "1.0.5"
signingConfig signingConfigs.signingA
// To Change the APK and Bundle Name
archivesBaseName = "${name}-v${versionCode}_${versionName}-${new Date().format('ddMMMyyyy_HH-mm')}"
}
bFlavor {
applicationId "com.b"
versionCode 5
versionName "1.0.5"
signingConfig signingConfigs.signingB
// To Change the APK and Bundle Name
archivesBaseName = "${name}-v${versionCode}_${versionName}-${new Date().format('ddMMMyyyy_HH-mm')}"
}
cFlavor {
applicationId "com.c"
versionCode 3
versionName "1.0.3"
signingConfig signingConfigs.signingC
// To Change the APK and Bundle Name
archivesBaseName = "${name}-v${versionCode}_${versionName}-${new Date().format('ddMMMyyyy_HH-mm')}"
}
}
When I use option Two,
Issue - it generates the correct name but generates a single APK file.
splits {
abi {
enable true
reset()
include 'arm64-v8a', 'x86', 'x86_64'
universalApk false
}
}
android.applicationVariants.all { variant ->
variant.outputs.all { output ->
output.outputFileName = "${variant.buildType.name}-v${versionCode}_${versionName}-${new Date().format('ddMMMyyyy_HH-mm')}.apk"
}
}
Issue for bundle - not able to rename the bundle using option Two.
As per This answer, you can go with Option - Two with minor changes as mention below only works for APK, not the Bundle / AAB files
splits {
abi {
enable true
reset()
include 'arm64-v8a', 'x86', 'x86_64'
universalApk false
}
}
android.applicationVariants.all { variant ->
variant.outputs.all { output ->
// New one or Updated one
output.outputFileName = "${variant.getFlavorName()}-${variant.buildType.name}-v${versionCode}_${versionName}-${new Date().format('ddMMMyyyy_HH-mm')}-${output.getFilter(com.android.build.OutputFile.ABI)}.apk"
// Old one
// output.outputFileName = "${variant.buildType.name}-v${versionCode}_${versionName}-${new Date().format('ddMMMyyyy_HH-mm')}.apk"
}
}
Also, remove the line from each Flavor's block
// To Change the APK and Bundle Name
archivesBaseName = "${name}-v${versionCode}_${versionName}-${new Date().format('ddMMMyyyy_HH-mm')}"
By this, you get the output file name like this
For aFlvour
Release
aFlavor-release-v5_1.0.5-16Jan2020_21-26-arm64-v8a.apk
aFlavor-release-v5_1.0.5-16Jan2020_21-26-x86_64.apk
aFlavor-release-v5_1.0.5-16Jan2020_21-26-x86.apk
Debug
aFlavor-debug-v5_1.0.5-16Jan2020_21-26-arm64-v8a.apk
aFlavor-debug-v5_1.0.5-16Jan2020_21-26-x86_64.apk
aFlavor-debug-v5_1.0.5-16Jan2020_21-26-x86.apk
For bFlavor
Similar name as above just change the prefix aFlavor with bFlavor like
bFlavor-release-v5_1.0.5-16Jan2020_21-26-arm64-v8a.apk
For cFlavor
Similar name as above just change the prefix aFlavor with cFlavor
and, versionCode and versionName as respected
cFlavor-release-v3_1.0.3-16Jan2020_21-26-arm64-v8a.apk
Because you are using universalApk false, Gradle generates different output apk for each ABI. So you have to add ABI name to your output filename. The output.getFilter(com.android.build.OutputFile.ABI) expression returns current ABI name.
Please look at the following example:
android.applicationVariants.all { variant ->
variant.outputs.all { output ->
output.outputFileName = "${variant.buildType.name}-${output.getFilter(com.android.build.OutputFile.ABI)}-v${versionCode}_${versionName}-${new Date().format('ddMMMyyyy_HH-mm')}.apk"
}
}
Remove app_name from string.xml file
apply plugin: 'com.android.application'
android {
signingConfigs {
release {
keyAlias 'your key alias'
keyPassword 'your password'
storeFile file('path of your keystore')
storePassword 'your password'
}
}
compileSdkVersion 28
flavorDimensions "default"
project.archivesBaseName = "ProjectName";
defaultConfig {
applicationId "Your package name"
minSdkVersion 16
targetSdkVersion 28
multiDexEnabled true
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
vectorDrawables.useSupportLibrary = true
signingConfig signingConfigs.release
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
applicationVariants.all { variant ->
variant.outputs.all { //output ->
outputFileName = "YourAppName-${variant.baseName}-${variant.versionName}.apk"
}
}
}
debug {
}
}
productFlavors {
dev {
versionCode 778899 // your versioncode
versionName "v.1.1.BUILD_NUM" // your version name
applicationIdPrefix ".dev" // your application package name like as com.a
resValue "string", "app_name", "Your App Name"
}
live {
versionCode 778899 // your versioncode
versionName "v.1.1.BUILD_NUM" // your version name
applicationIdPrefix ".dev" // your application package name like as com.a
resValue "string", "app_name", "Your App Name"
}
}
compileOptions {
targetCompatibility 1.8
sourceCompatibility 1.8
}
}
dependencies {
// Here your application gradle
}
These solutions do not work for aab (bundle). Only APK.
You have to set different flavors if you want to have different output apks.
I have recently upgraded to Gradle 3.0 and now find that the feature to rename the output APK has changed. I think I can get around that, but what I am wondering is whether I can still choose the target directory for the APK. We have existing software that uses a specific APK naming convention and directory structure that I want to maintain. Is there a way to do this?
Here is my current gradle build structure (simplified and renamed to protect the innocent):
android {
compileSdkVersion 25
buildToolsVersion '25.0.3'
defaultConfig {
applicationId "com.mycompany.myapp"
minSdkVersion 15
targetSdkVersion 23
versionCode 23
versionName "23.23.23"
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_7
targetCompatibility JavaVersion.VERSION_1_7 }
signingConfig signingConfigs.config
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
signingConfig signingConfigs.config
}
}
productFlavors.whenObjectAdded { flavor ->
// Add the property 'myCustomProperty' to each product flavor and set the default value to 'customPropertyValue'
flavor.ext.set('directoryPath', '')
flavor.ext.set('apkName', '')
}
productFlavors {
MyCompany {
signingConfig signingConfigs.config
directoryPath = mycompany
}
Copper {
applicationId c
signingConfig signingConfigs.config
directoryPath = 'copper'
}
Steel {
applicationId 'com.company2.steel'
signingConfig signingConfigs.config
directoryPath = 'steel'
}
Lead {
applicationId 'com.company3.coal'
signingConfig signingConfigs.config
directoryPath = 'coal'
}
}
applicationVariants.all { variant ->
variant.outputs.each { output ->
def path = "C:/AndroidBuilds/MyBuilds/" + variant.productFlavors[0].directoryPath + "/"
logger.error("Path = " + path)
def SEP = "-"
def apkName = variant.productFlavors[0].apkName
def flavor = variant.productFlavors[0].name
if (apkName != '')
flavor = apkName;
def version = variant.versionCode
def newApkName = path + version + SEP + flavor
logger.error("newApkName = " + newApkName)
output.outputFile = new File(newApkName + ".apk")
}
}
}
I know that there is now a "Flavor Dimension" which I will just default (I removed that just to make the code a wee bit clearer). The results of running this build should be that 4 different APKs would be generated and placed in their own directory structures, prefixed with the version number (eg "64-Iron.apk").
The naming is working by replacing with "outputfile", but the directory structure does not. Is there a new way to do this under the latest Gradle?
UPDATE (FIXED)
Thanks to the info provided by selected solution, for completeness, here is the final gradle config (again, cleaned to protect the innocent):
android {
compileSdkVersion 26
defaultConfig {
applicationId "com.mycompany.myapp"
minSdkVersion 15
targetSdkVersion 23
versionCode 23
versionName "23.23.23"
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_7
targetCompatibility JavaVersion.VERSION_1_7 }
signingConfig signingConfigs.config
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
signingConfig signingConfigs.config
}
}
productFlavors.whenObjectAdded { flavor ->
// Add the property 'myCustomProperty' to each product flavor and set the default value to 'customPropertyValue'
flavor.ext.set('directoryPath', '')
flavor.ext.set('apkName', '')
}
productFlavors {
MyCompany {
signingConfig signingConfigs.config
directoryPath = mycompany
}
Copper {
applicationId c
signingConfig signingConfigs.config
directoryPath = 'copper'
}
Steel {
applicationId 'com.company2.steel'
signingConfig signingConfigs.config
directoryPath = 'steel'
}
Lead {
applicationId 'com.company3.coal'
signingConfig signingConfigs.config
directoryPath = 'coal'
}
}
applicationVariants.all { variant ->
variant.outputs.all {
def apkName = variant.productFlavors[0].apkName
def flavor = variant.productFlavors[0].name
if (apkName != '')
flavor = apkName;
//add here your logic to customize the name of the apk
outputFileName = "${variant.versionCode}-${flavor}.apk"
}
variant.assemble.doLast { assemble ->
//copy the apk in another directory, add here your
//logic to customize the destination folder
copy {
from variant.outputs*.outputFile
into "C:/AndroidBuilds/MyBuilds//${variant.productFlavors[0].directoryPath}"
}
//if you don't want to delete the file after copying it comment the line below
delete variant.outputs*.outputFile
}
}
}
Thanks again MatPag!
UPDATE: Starting from Gradle 3.3.0 assemble property is deprecated. This is the new way to do this:
applicationVariants.all { variant ->
variant.outputs.all {
//add here your logic to customize the name of the apk
outputFileName = "${variant.name}-${variant.versionName}.apk"
}
variant.assembleProvider.configure { assemble ->
assemble.doLast {
//copy the apk in another directory, add here your
//logic to customize the destination folder
copy {
from variant.outputs*.outputFile
//for Windows
into "C:/my_apks/${variant.dirName}"
}
//if you don't want to delete the file after copying it comment the line below
delete variant.outputs*.outputFile
}
}
}
in macOS/Linux you can use something like this for the destination
path:
into "${System.properties['user.home']}/my_apks/${variant.dirName}"
OLD ANSWER (for AGP < 3.3.0):
I've played a bit with Gradle 4.2.1 and AGP 3.0.0, and a possible solution is this one
applicationVariants.all { variant ->
variant.outputs.all {
//add here your logic to customize the name of the apk
outputFileName = "${variant.name}-${variant.versionName}.apk"
}
variant.assemble.doLast { assemble ->
//copy the apk in another directory, add here your
//logic to customize the destination folder
copy {
from variant.outputs*.outputFile
into "C:/my_apks/${variant.dirName}"
}
//if you don't want to delete the file after copying it comment the line below
delete variant.outputs*.outputFile
}
}
I think it's a good starting point to customize the folders based on your needs :)
I have follow the instruction to add jar library but when i am going to synchronize the build grade then getting error.
Could not find property 'file' on org.gradle.api.internal.artifacts.dsl.dependencies.DefaultDependencyHandler_Decorated#1a9bd9bb.
I am not getting what is error. please suggest.
build gradle
apply plugin: 'com.android.application'
android {
compileSdkVersion 22
buildToolsVersion "22.0.1"
defaultConfig {
applicationId "com.example.cws.myapplication"
minSdkVersion 11
targetSdkVersion 22
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
applicationVariants.all { variant ->
variant.outputs.each { output ->
output.outputFile = new File(file.parent, file.name.replace(".apk", "-" + defaultConfig.versionName + ".apk"));
}
}
}
sourceSets { main { res.srcDirs = ['src/main/res', 'src/main/res/layout'] } }
}
def var = dependencies {
compile 'com.android.support:appcompat-v7:22.0.0'
compile file 'libs/library-2.1.1.jar'
}
In Build.Gradle file the code to add the library is
compile files('libs/acra-4.6.0RC1.jar')
The letter 's' in 'files' is missing from the command.
I'd like to apply different VersionCode to make apk file.
For debug only fix it to 1, and for release whatever number specified in defaultConfig.
Below code gives mypackage-release-1.apk file as assembleRelease artifact, which is not expected. I expected mypackage-release-10111.apk for that.
why the line debug { defaultConfig.versionCode=1 } affects assembleRelease artifact?
defaultConfig {
versionCode 10111
versionName '2.5.4'
minSdkVersion 10
targetSdkVersion 21
}
signingConfigs {
debug {
project.ext.loadSign = false
defaultConfig.versionCode = 1 // Why this value applied to assembleRelease?
}
release {
project.ext.loadSign = true
applicationVariants.all { variant ->
variant.outputs.each { output ->
def file = output.outputFile
output.outputFile = new File(file.parent, file.name.replace(".apk", "-" + defaultConfig.versionCode + ".apk"))
}
}
}
}
buildTypes {
debug {
signingConfig signingConfigs.debug
}
release {
signingConfig signingConfigs.release
}
}
Here's an updated version:
android {
defaultConfig { ... }
applicationVariants.all { variant ->
if (variant.name == 'debug') {
variant.outputs.each { output ->
output.versionCodeOverride = 1
}
}
}
}
Late on the party...
The entire gradle file evaluated before any task execution, so you are basically changing the default versionCode while declaring debug configs. There is no direct way to reset versionCode from buildType, but the link on the other answer do the trick by declaring a task on build variants.
android {
...
defaultConfig {
...
}
buildTypes {
...
}
applicationVariants.all { variant ->
def flavor = variant.mergedFlavor
def versionCode = flavor.versionCode
if (variant.buildType.isDebuggable()) {
versionCode += 1
}
flavor.versionCode = versionCode
}
}
The easiest solution is moving versionCode and versionName variables from defaultConfig to debug and release respectively.
android {
...
defaultConfig {
// without versionCode and versionName
...
}
buildTypes {
debug {
defaultConfig.versionCode X
defaultConfig.versionName 'X.Y.Z'
}
release {
defaultConfig.versionCode A
defaultConfig.versionName 'A.B.C'
}
}
...
}
Me too, but I think defaultConfig.versionCode was set when build.gradle be compiling. It's global static variable, and assigned at compiletime, not runtime.
I think we can intercept gradle task execution, and modify defaultConfig.versionCode at runtime.
After goooooooogle, I found this one works for me: https://gist.github.com/keyboardsurfer/a6a5bcf2b62f9aa41ae2
To use with Flavors:
applicationVariants.all { variant ->
def flavor = variant.mergedFlavor
def name = flavor.getVersionName()
def code = flavor.getVersionCode()
if (variant.buildType.isDebuggable()) {
name += '-d'
code = 1
}
variant.outputs.each { output ->
output.versionNameOverride = name
output.versionCodeOverride = code
}
}
applicationVariants.all { variant ->
variant.outputs.each { output ->
if (variant.buildType.isDebuggable()) {
output.versionCodeOverride = 26
output.versionNameOverride = "2.2.6"
}
}
}
put it in android{}
So recently I had to deal with the same scenario and all the examples I could find use the applicationVariants property which is ill-documented imo.
So after some digging through the source code a bit, I realized that in the end versionCode and versionName properties from ProductFlavor get merged into the AndroidManifest which got me thinking: couldn't we just inject them by ourselves, cause we have manifestPlaceholders property on ProductFlavor AND on BuildType DSL objects, so I came up with this -- don't hesitate to give feedback and tell me why it's wrong
In build.gradle(app)
android {
...
buildTypes {
debug {
manifestPlaceholder = [versionCode: X, versionName: "X.Y.Z"]
}
release {
manifestPlaceholder = [versionCode: A, versionName: "A.B.C"]
}
}
...
}
In AndroidManifest.xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="..."
android:versionCode="${versionCode}"
android:versionName="${versionName}">
...
</manifest>
I'm trying to set a specific version number in the gradle auto-generated APK filename.
Now gradle generates myapp-release.apk but I want it to look something like myapp-release-1.0.apk.
I have tried renaming options that seems messy. Is there a simple way to do this?
buildTypes {
release {
signingConfig signingConfigs.release
applicationVariants.each { variant ->
def file = variant.outputFile
variant.outputFile = new File(file.parent, file.name.replace(".apk", "-" + defaultConfig.versionName + ".apk"))
}
}
I have tried the code above with no luck. Any suggestions?
(using gradle 1.6)
I only have to change the version name in one place. The code is simple too.
The examples below will create apk files named named MyCompany-MyAppName-1.4.8-debug.apk or MyCompany-MyAppName-1.4.8-release.apk depending on the build variant selected.
Note that this solution works on both APK and App Bundles (.aab files).
See Also: How to change the proguard mapping file name in gradle for Android project
#Solution for Recent Gradle Plugin
android {
compileSdkVersion 22
buildToolsVersion "22.0.1"
defaultConfig {
applicationId "com.company.app"
minSdkVersion 13
targetSdkVersion 21
versionCode 14 // increment with every release
versionName '1.4.8' // change with every release
setProperty("archivesBaseName", "MyCompany-MyAppName-$versionName")
}
}
The above solution has been tested with the following Android Gradle Plugin Versions:
3.6.4 (August 2020)
3.5.2 (November 2019)
3.3.0 (January 2019)
3.1.0 (March 2018)
3.0.1 (November 2017)
3.0.0 (October 2017)
2.3.2 (May 2017)
2.3.1 (April 2017)
2.3.0 (February 2017)
2.2.3 (December 2016)
2.2.2
2.2.0 (September 2016)
2.1.3 (August 2016)
2.1.2
2.0.0 (April 2016)
1.5.0 (2015/11/12)
1.4.0-beta6 (2015/10/05)
1.3.1 (2015/08/11)
I'll update this post as new versions come out.
#Solution Tested Only on versions 1.1.3-1.3.0
The following solution has been tested with the following Android Gradle Plugin Versions:
1.3.0 (2015/07/30) - Not Working, bug scheduled to be fixed in 1.3.1
1.2.3 (2015/07/21)
1.2.2 (2015/04/28)
1.2.1 (2015/04/27)
1.2.0 (2015/04/26)
1.2.0-beta1 (2015/03/25)
1.1.3 (2015/03/06)
app gradle file:
apply plugin: 'com.android.application'
android {
compileSdkVersion 21
buildToolsVersion "21.1.2"
defaultConfig {
applicationId "com.company.app"
minSdkVersion 13
targetSdkVersion 21
versionCode 14 // increment with every release
versionName '1.4.8' // change with every release
archivesBaseName = "MyCompany-MyAppName-$versionName"
}
}
This solved my problem: using applicationVariants.all instead of applicationVariants.each
buildTypes {
release {
signingConfig signingConfigs.release
applicationVariants.all { variant ->
def file = variant.outputFile
variant.outputFile = new File(file.parent, file.name.replace(".apk", "-" + defaultConfig.versionName + ".apk"))
}
}
}
Update:
So it seems this does not work with 0.14+ versions of android studio gradle plugin.
This does the trick (Reference from this question
) :
android {
applicationVariants.all { variant ->
variant.outputs.each { output ->
output.outputFile = new File(
output.outputFile.parent,
output.outputFile.name.replace(".apk", "-${variant.versionName}.apk"))
}
}
}
(EDITED to work with Android Studio 3.0 and Gradle 4)
I was looking for a more complex apk filename renaming option and I wrote this one in the hope it is helpfull for anyone else. It renames the apk with the following data:
flavor
build type
version
date
It took me a bit of research in gradle classes and a bit of copy/paste from other answers. I am using gradle 3.1.3.
In the build.gradle:
android {
...
buildTypes {
release {
minifyEnabled true
...
}
debug {
minifyEnabled false
}
}
productFlavors {
prod {
applicationId "com.feraguiba.myproject"
versionCode 3
versionName "1.2.0"
}
dev {
applicationId "com.feraguiba.myproject.dev"
versionCode 15
versionName "1.3.6"
}
}
applicationVariants.all { variant ->
variant.outputs.all { output ->
def project = "myProject"
def SEP = "_"
def flavor = variant.productFlavors[0].name
def buildType = variant.variantData.variantConfiguration.buildType.name
def version = variant.versionName
def date = new Date();
def formattedDate = date.format('ddMMyy_HHmm')
def newApkName = project + SEP + flavor + SEP + buildType + SEP + version + SEP + formattedDate + ".apk"
outputFileName = new File(newApkName)
}
}
}
If you compile today (13-10-2016) at 10:47, you get the following file names depending on the flavor and build type you have choosen:
dev debug: myProject_dev_debug_1.3.6_131016_1047.apk
dev release: myProject_dev_release_1.3.6_131016_1047.apk
prod debug: myProject_prod_debug_1.2.0_131016_1047.apk
prod release: myProject_prod_release_1.2.0_131016_1047.apk
Note: the unaligned version apk name is still the default one.
To sum up, for those don't know how to import package in build.gradle(like me), use the following buildTypes,
buildTypes {
release {
signingConfig signingConfigs.release
applicationVariants.all { variant ->
def file = variant.outputFile
def manifestParser = new com.android.builder.core.DefaultManifestParser()
variant.outputFile = new File(file.parent, file.name.replace(".apk", "-" + manifestParser.getVersionName(android.sourceSets.main.manifest.srcFile) + ".apk"))
}
}
}
===== EDIT =====
If you set your versionCode and versionName in your build.gradle file like this:
defaultConfig {
minSdkVersion 15
targetSdkVersion 19
versionCode 1
versionName "1.0.0"
}
You should set it like this:
buildTypes {
release {
signingConfig signingConfigs.releaseConfig
applicationVariants.all { variant ->
def file = variant.outputFile
variant.outputFile = new File(file.parent, file.name.replace(".apk", "-" + defaultConfig.versionName + ".apk"))
}
}
}
====== EDIT with Android Studio 1.0 ======
If you are using Android Studio 1.0, you will get an error like this:
Error:(78, 0) Could not find property 'outputFile' on com.android.build.gradle.internal.api.ApplicationVariantImpl_Decorated#67e7625f.
You should change the build.Types part to this:
buildTypes {
release {
signingConfig signingConfigs.releaseConfig
applicationVariants.all { variant ->
variant.outputs.each { output ->
output.outputFile = new File(output.outputFile.parent, output.outputFile.name.replace(".apk", "-" + defaultConfig.versionName + ".apk"))
}
}
}
}
If you don't specify versionName in defaultConfig block then defaultConfig.versionName will result in null
to get versionName from manifest you can write following code in build.gradle:
import com.android.builder.DefaultManifestParser
def manifestParser = new DefaultManifestParser()
println manifestParser.getVersionName(android.sourceSets.main.manifest.srcFile)
Gradle 6+
I'm now using the following in Android Studio 4.0 and Gradle 6.4:
android {
defaultConfig {
applicationId "com.mycompany.myapplication"
minSdkVersion 21
targetSdkVersion 29
versionCode 15
versionName "2.1.1"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
applicationVariants.all { variant ->
variant.outputs.all {
outputFileName = "ApplicationName-${variant.name}-${variant.versionName}.apk"
}
}
}
}
}
Gradle 4
Syntax has changed a bit in Gradle 4 (Android Studio 3+) (from output.outputFile to outputFileName, idea from this answer is now:
android {
applicationVariants.all { variant ->
variant.outputs.each { output ->
def newName = outputFileName
newName.replace(".apk", "-${variant.versionName}.apk")
outputFileName = new File(newName)
}
}
}
In my case, I just wanted to find a way to automate the generation of different apk name for release and debug variants. I managed to do this easily by putting this snippet as a child of android:
applicationVariants.all { variant ->
variant.outputs.each { output ->
def appName = "My_nice_name_"
def buildType = variant.variantData.variantConfiguration.buildType.name
def newName
if (buildType == 'debug'){
newName = "${appName}${defaultConfig.versionName}_dbg.apk"
} else {
newName = "${appName}${defaultConfig.versionName}_prd.apk"
}
output.outputFile = new File(output.outputFile.parent, newName)
}
}
For the new Android gradle plugin 3.0.0 you can do something like that:
applicationVariants.all { variant ->
variant.outputs.all {
def appName = "My_nice_name_"
def buildType = variant.variantData.variantConfiguration.buildType.name
def newName
if (buildType == 'debug'){
newName = "${appName}${defaultConfig.versionName}_dbg.apk"
} else {
newName = "${appName}${defaultConfig.versionName}_prd.apk"
}
outputFileName = newName
}
}
This produce something like : My_nice_name_3.2.31_dbg.apk
Another alternative is to use the following:
String APK_NAME = "appname"
int VERSION_CODE = 1
String VERSION_NAME = "1.0.0"
project.archivesBaseName = APK_NAME + "-" + VERSION_NAME;
android {
compileSdkVersion 21
buildToolsVersion "21.1.1"
defaultConfig {
applicationId "com.myapp"
minSdkVersion 15
targetSdkVersion 21
versionCode VERSION_CODE
versionName VERSION_NAME
}
.... // Rest of your config
}
This will set "appname-1.0.0" to all your apk outputs.
The right way to rename apk, as per #Jon answer
defaultConfig {
applicationId "com.irisvision.patientapp"
minSdkVersion 24
targetSdkVersion 22
versionCode 2 // increment with every release
versionName "0.2" // change with every release
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
//add this line
archivesBaseName = "AppName-${versionName}-${new Date().format('yyMMdd')}"
}
Or another way you can achieve same results with
android {
...
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
applicationVariants.all { variant ->
variant.outputs.all { output ->
def formattedDate = new Date().format('yyMMdd')
outputFileName = "${outputFileName.replace(".apk","")}-v${defaultConfig.versionCode}-${formattedDate}.apk"
}
}
}
There are many answers that are correct either in full or after some modifications. But I am going to add mine anyway since I was having the problem with all of them because I was using scripts to generate VersionName and VersionCode dynamically by hooking into the preBuild task.
If you are using some similar approach this is the the code that will work:
project.android.applicationVariants.all { variant ->
variant.preBuild.doLast {
variant.outputs.each { output ->
output.outputFile = new File(
output.outputFile.parent,
output.outputFile.name.replace(".apk", "-${variant.versionName}#${variant.versionCode}.apk"))
}
}
}
To explain: Since I am overriding version code and name in the first action of preBuild I have to add the file renaming to the end of this task. So what gradle will do in this case is:
Inject version code/name-> do preBuild actions -> replace name for apk
applicationVariants.all { variant ->
variant.outputs.all { output ->
output.outputFileName = output.outputFileName.replace(".apk", "-${variant.versionName}.apk")
}
}
In my case I solve this error this way
adding a SUFFIX to the Debug version, in this case I adding the "-DEBUG" text to my Debug deploy
buildTypes {
release {
signingConfig signingConfigs.release
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
debug {
defaultConfig {
debuggable true
versionNameSuffix "-DEBUG"
}
}
}
For latest gradle versions you can use following snippet:
Set your application manifest location first
sourceSets {
main {
manifest.srcFile 'src/main/AndroidManifest.xml'
{
}
And later on in build.gradle
import com.android.builder.core.DefaultManifestParser
def getVersionName(manifestFile) {
def manifestParser = new DefaultManifestParser();
return manifestParser.getVersionName(manifestFile);
}
def manifestFile = file(android.sourceSets.main.manifest.srcFile);
def version = getVersionName(manifestFile)
buildTypes {
release {
signingConfig signingConfigs.release
applicationVariants.each { variant ->
def file = variant.outputFile
variant.outputFile = new File(file.parent, file.name.replace(".apk", "-" + versionName + ".apk"))
}
}
Adjust if you have different manifests per build type. but since I have the single one - works perfectly for me.
As of Android Studio 1.1.0, I found this combination worked in the android body of the build.gradle file. This is if you can't figure out how to import the manifest xml file data. I wish it was more supported by Android Studio, but just play around with the values until you get the desired apk name output:
defaultConfig {
applicationId "com.package.name"
minSdkVersion 14
targetSdkVersion 21
versionCode 6
versionName "2"
}
signingConfigs {
release {
keyAlias = "your key name"
}
}
buildTypes {
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.release
applicationVariants.all { variant ->
variant.outputs.each { output ->
output.outputFile = new File(output.outputFile.parent, output.outputFile.name.replace("app-release.apk", "appName_" + versionName + ".apk"))
}
}
}
}
As I answered here If you want to append the version name and version code to the output file do it like:
applicationVariants.all { variant ->
variant.outputs.all {
def versionName = variant.versionName
def versionCode = variant.versionCode
def variantName = variant.name
outputFileName = "${rootProject.name}" + '_' + variantName + '_' + versionName + '_' + versionCode + '.apk'
}
}
You can also add formatted build time to apk name as below:
setProperty("archivesBaseName", "data-$versionName " + (new Date().format("HH-mm-ss")))
Here is how you can do it in the Kotlin DSL:
applicationVariants.all {
outputs.all {
this as com.android.build.gradle.internal.api.ApkVariantOutputImpl
val apkName = outputFileName.replace(".apk", "-" + defaultConfig.versionName + ".apk")
outputFileName = apkName
}
}