How to set library version with gradle plugin 3.2? - android

In my android library project I used to do this:
android.libraryVariants.all { variant ->
def flavourName = variant.productFlavors.get(0).name
def buildTypeName = variant.buildType.name
def buildVersion = calculateVersion( flavourName, buildTypeName )
variant.mergedFlavor.versionName = buildVersion
}
And this worked fine up until gradle plugin 3.1.3. Now I am trying out 3.2.0-beta04 (as its much much faster when using vanilla cmake) and I am getting this error:
versionName cannot be set on a mergedFlavor directly.
versionNameOverride can instead be set for variant outputs using the following syntax:
android {
applicationVariants.all { variant ->
variant.outputs.each { output ->
output.versionNameOverride = "6.12.0"
}
}
}
OK, I apply the suggestion:
android.libraryVariants.all { variant ->
def flavourName = variant.productFlavors.get(0).name
def buildTypeName = variant.buildType.name
def buildVersion = calculateVersion( flavourName, buildTypeName )
variant.outputs.each { output ->
output.versionNameOverride = buildVersion
}
}
and now I get this error:
Could not set unknown property 'versionNameOverride' for object of type com.android.build.gradle.internal.api.LibraryVariantOutputImpl.
It appears that versionNameOverride property is implemented only for application variants, not for the library variants. Does that mean that support for setting Android AAR version is now deprecated? Or is there another way to achieve that?
EDIT: Note that setting versionName field in defaultConfig section works for my library project - it just does not work setting up programmatically with the method described above.

Try to change variant.productFlavors.get(0).name to def flavor = variant.mergedFlavor, than set name and version code for flavour like that
flavor.versionName = versionName
flavor.versionCode = versionCode
variant.outputs.all { output ->
output.setVersionNameOverride(versionName)
output.setVersionCodeOverride(versionCode)
}

Related

Apk rename with the Gradle plugin v4.10.1

I´ve updated my Android Studio today to the 3.3 version which came with Gradle plugin version 4.10.1.
Previously, my build.gradle was renaming my apk´s with this code to the following structure:
app-{buildType[release|debug]}-{flavor[prod|stage]}-{versionName[1.2.4]-{versionCode[43]}.apk
app-release-prod-1.1.4-45.apk.
applicationVariants.all { variant ->
variant.outputs.all { output ->
outputFileName = output.outputFile.name.replace(".apk", "-${variant.versionName}-${variant.versionCode}.apk").replace("-unsigned", "")
}
}
But I got this error after updating.
WARNING: API 'variantOutput.getPackageApplication()' is obsolete and has been replaced with 'variant.getPackageApplicationProvider()'.
It will be removed at the end of 2019.
For more information, see https://d.android.com/r/tools/task-configuration-avoidance.
To determine what is calling variantOutput.getPackageApplication(), use -Pandroid.debug.obsoleteApi=true on the command line to display a stack trace.
Affected Modules: app
The problem is at output.outputFile.name since you can't access output data on this plugin version.
So far I´ve tried this approach without success.
applicationVariants.all { variant ->
variant.flavors*.name.all { flavor ->
outputFileName = "${flavor}-${variant.buildType.name}-${variant.versionName}-${variant.versionCode}.apk".replace("-unsigned", "")
}
}
Any idea?
=======================================================
UPDATE
I took a retake on this matter, I´ve tried the following snippet, but I'm having issues retrieving the flavor of that variant.
android.applicationVariants.all { variant ->
def flavor = variant.flavorName
variant.outputs.all { output ->
def builtType = variant.buildType.name
def versionName = variant.versionName
def versionCode = variant.versionCode
outputFileName = "app-${flavor}-${builtType}-${versionName}-${versionCode}.apk"
}
}
outputs: app--release-1.0.4-88.apk
Thanks
Try this:
android.applicationVariants.all { variant ->
variant.outputs.all { output ->
def builtType = variant.buildType.name
def versionName = variant.versionName
def versionCode = variant.versionCode
def flavor = variant.flavorName
outputFileName = "app-${flavor}-${builtType}-${versionName}-${versionCode}.apk"
}
}
This outputs the following apk name : app-release-myFlavor-0.0.1-1.apk.
Using setProperty method you can rename your .apk name.
You can do this.
android {
compileSdkVersion 28
defaultConfig {
applicationId "com.expertBrains.abc"
minSdkVersion 17
targetSdkVersion 28
versionCode 75
versionName "2.6.15"
multiDexEnabled true
setProperty("archivesBaseName", "(" + versionName + ") "+ new Date().format( 'yyyy-MM-dd HH:mm' ))
}
}
You can do it like this:
defaultConfig {
...
project.ext.set("archivesBaseName", applicationId + "_V" + versionName + "("+versionCode+")_" + new Date().format('dd-MM mm'));
}
As mentioned in the comments, the right way was to use ${variant.getFlavorName()}.apk or variant.baseName.
Can you try below.
applicationVariants.all { variant ->
variant.outputs.all { output ->
outputFileName = outputFileName.replace(".apk", "-${variant.versionName}-${variant.versionCode}.apk").replace("-unsigned", "")
}
}
I hope this could help. I can't say this is the best way but it works.
productFlavour{
uat {
versionName "2.8.74"
buildConfigField("String", "ENVIRONMENT", '"uat"')
setProperty("archivesBaseName", "iotg-uat-v" + versionName)
}
staging {
versionName "2.9.4"
buildConfigField("String", "ENVIRONMENT", '"staging"')
setProperty("archivesBaseName", "iotg-staging-v" + versionName)
}
}
applicationVariants.all { variant ->
variant.outputs.all {
def appName = "AppName"
def buildType = variant.variantData.variantConfiguration.buildType.name
def newName = "${appName}${defaultConfig.versionName}_${buildType}.apk"
outputFileName = newName
}
}
Below code will generate apk file name as
AppName1.2.0_buildType.apk

Android APK artifact name with respective ABI architecture

I am trying to extract and use the architecture of the artifact to compose the output file name:
void defineDefaultVariantsAPK(String appName) {
defineVariantsAPK({ variant, output ->
def versionName = variant.versionName
def versionCode = "-(${variant.versionCode}"
def buildLetter = variant.buildType.name == "release" ? "-R" : "-D"
def flavor = variant.productFlavors.size() > 0 ? "-${variant.productFlavors[0].name}" : ""
def architecture = "-" + output.getFilter(com.android.build.OutputFile.ABI)
"v${versionName}${versionCode}${buildLetter}${flavor}${architecture}--${appName}.apk"
})
}
void defineVariantsAPK(Closure nameBuild) {
android {
applicationVariants.all { variant ->
variant.outputs.each { output ->
output.outputFile = new File((String) output.outputFile.parent, nameBuild(variant, output))
}
}
}
}
for some reason many posts says that that is the solution, but my gradle fails on:
> Could not get unknown property 'com' for project ':app' of type org.gradle.api.Project.
I've tried to use import:
unable to resolve class com.android.build.OutputFile
configuration:
com.android.tools.build:gradle:2.3.3
Gradle version 3.5
So I really wonder, what am I doing different that it doesn't work?
Beggining with Gradle 3.0.0 you can do it like this:
applicationVariants.all { variant ->
variant.outputs.all { output ->
def appName = "AppName_"
def buildType = variant.variantData.variantConfiguration.buildType.name
def architecture = output.getFilter(com.android.build.OutputFile.ABI)
def newName
if (buildType == 'debug') {
newName = "${appName}debug_${defaultConfig.versionName}_${architecture}.apk"
} else {
newName = "${appName}release_${defaultConfig.versionName}_${architecture}.apk"
}
outputFileName = newName
}
}
*put this in your module(app) build.gradle file.
This code works for me with gradle 3+ for android
android.applicationVariants.all { variant ->
variant.outputs.all { output ->
def architecture = output.filters[0].identifier
outputFileName = "myapp-${architecture}-${variant.versionName}.apk"
}
}
Where did you define this function? Try to move it you your app/build.gradle file as that is where buildscript is and gradle loads classes from it into classpath.
So following #blazsolar suggestion I've moved the method to the app build gradle file, the move itself was not the solution, when I tried to add the import:
import com.android.build.OutputFile
for some reason the IDE (Android studio) has decided to delete the import..
but once I've this import:
import com.android.build.OutputFile.FilterType
it was just fine!
but that is not the end of it... I want the method to be in a common gradle file, that all my project can reuse.
once I've added the last import to the common gradle file... the import figging disappeared again..
I am left with yet another question
update:
So I've update Android plugin and gradle version to 3.0.1 and 4.1 respectively, and now... things have change.. now there is no
com.android.build.OutputFile.FilterType
Now you need to use:
com.android.build.VariantOutput.ABI
Just in case anyone wonder...

Cannot set the value of read-only property 'outputFile' for ApkVariantOutputImpl_Decorated

I was using the following code in my gradle script to rename the apks generated with AndroidStudio:
applicationVariants.all { variant ->
variant.outputs.each { output ->
output.outputFile = new File(output.outputFile.parent, defaultConfig.versionCode + "_" + output.outputFile.name)
}
}
So it was generating apks with names like: 345-app-release.apk, where 345 is the versionCode.
But after updating to AndroidStudio 3.0 it returns the following error:
Cannot set the value of read-only property 'outputFile' for
ApkVariantOutputImpl_Decorated{apkData=Main{type=MAIN, fullName=debug,
filters=[]}} of type
com.android.build.gradle.internal.api.ApkVariantOutputImpl.
How can I achieve a similar renaming with the new build tools.
Use output.outputFileName instead of output.outputFile
2019 - Simple Solution for Gradle 3.0+** and 3.1.0
To change the name of the APK in Android
android { //add inside the android {}
......
applicationVariants.all { variant ->
variant.outputs.all {
def flavor = variant.name
def versionName = variant.versionName
outputFileName = "prefix_${flavor}_${versionName}.apk"
}
}
}
prefix_release_1.0.1.apk
Try this code :
buildTypes {
applicationVariants.all { variant ->
variant.outputs.each { output ->
def name = "myapp_v${variant.versionName}(${variant.versionCode}).apk"
output.outputFileName = name
}
}
}
In or After gradle 3.1.0
try below code
applicationVariants.all { variant ->
variant.outputs.all { output ->
outputFileName = new File(
"release_build", // here you can change the name
output.outputFile.name)
}
}
In my case I resolved it by just refusing to update to Gradle 4.4 (in my case).So when Studio asks (when you open your project for the first time) you to update Gradle to support instant run,etc just simply refuse and you should be fine.
What worked for me was to
1. change each to "all"
2. change output.outputFile to "outputFileName"
3. Run $./gradlew clean build in terminal
For example, if your artifacts.gradle settings were this:
android.applicationVariants.all { variant ->
variant.outputs.each { output ->
def finalVersionCode = 10000 + versionCode
output.versionCodeOverride = finalVersionCode
output.outputFile = new File(
output.outputFile.parent, output.outputFile.name.replace(".apk","-${finalVersion}.apk"))
}
}
Then you would want to change it to this:
android.applicationVariants.all { variant ->
variant.outputs.all { output ->
def finalVersionCode = 10000 + versionCode
output.versionCodeOverride = finalVersionCode
outputFileName = new File(
output.outputFile.parent,
outputFileName.replace(".apk", "-${finalVersionCode}.apk"))
}
}
change your code into:-
applicationVariants.all { variant ->
variant.outputs.each { output ->
output.outputFile = new File(output.outputFile.parent, "${variant.applicationId}-${variant.versionName}.apk")
}
}

Gradle warning: variant.getOutputFile() and variant.setOutputFile() are deprecated

I am using the following simplified configuration in an Android application project.
android {
compileSdkVersion 20
buildToolsVersion "20.0.0"
defaultConfig {
minSdkVersion 8
targetSdkVersion 20
versionCode 1
versionName "1.0.0"
applicationVariants.all { variant ->
def file = variant.outputFile
def fileName = file.name.replace(".apk", "-" + versionName + ".apk")
variant.outputFile = new File(file.parent, fileName)
}
}
}
Now that I updated the Gradle plug-in to v.0.13.0 and Gradle to v.2.1. the following warnings appear:
WARNING [Project: :MyApp] variant.getOutputFile() is deprecated.
Call it on one of variant.getOutputs() instead.
WARNING [Project: :MyApp] variant.setOutputFile() is deprecated.
Call it on one of variant.getOutputs() instead.
WARNING [Project: :MyApp] variant.getOutputFile() is deprecated.
Call it on one of variant.getOutputs() instead.
WARNING [Project: :MyApp] variant.setOutputFile() is deprecated.
Call it on one of variant.getOutputs() instead.
How can I rewrite the Groovy script to get rid of the deprecation warnings?
Building on the answer from Larry Schiefer you can change the script to something like this:
android {
applicationVariants.all { variant ->
variant.outputs.each { output ->
def outputFile = output.outputFile
if (outputFile != null && outputFile.name.endsWith('.apk')) {
def fileName = outputFile.name.replace('.apk', "-${versionName}.apk")
output.outputFile = new File(outputFile.parent, fileName)
}
}
}
}
The complete code snippet looks like that one:
// Customize generated apk's name with version number
applicationVariants.all { variant ->
variant.outputs.each { output ->
def outputFile = output.outputFile
if (outputFile != null && outputFile.name.endsWith('.apk')) {
def manifestParser = new com.android.builder.core.DefaultManifestParser()
def fileName = outputFile.name.replace(".apk", "-DEBUG-" + manifestParser.getVersionName(android.sourceSets.main.manifest.srcFile) + ".apk")
output.outputFile = new File(outputFile.parent, fileName)
}
}
}
The build variant output API has changed in the latest Android Gradle plugin. It now allows multiple output files (or directories), which is why this method has been marked as deprecated. If you use variant.outputs instead, it will give you a Collection you can then iterate over and get each output file. You'll have to verify the file object is non-null and that it matches your criteria (e.g. has a '.apk' extension.) Then you can create a new File object and add it to the output within the collection.
Android Plugin for Gradle 3.0.0
You can use like this
android.applicationVariants.all { variant ->
variant.outputs.all {
outputFileName = "${variant.name}-${variant.versionName}.apk"
}
}
you can get more on the features and new changes in android documentation
https://developer.android.com/studio/build/gradle-plugin-3-0-0-migration.html#update_gradle

How to set name of AAR output from Gradle

I have a project with several modules in it one of which is a Android Library named (poorly) as sdk. When I build the project it outputs an AAR named sdk.aar.
I haven't been able to find anything in the Android or Gradle documentation that allows me to change the name of the AAR output. I would like it to have a basename + version number like the Jar tasks do, but I can't work out how to do the same for the AAR because all the config for it seems to be hidden in the android.library plugin.
Renaming the module isn't an option at this stage and that still wouldn't add the version number to the final AAR.
How can I change the name of the AAR generated by com.android.library in Gradle?
Gradle solution
defaultConfig {
minSdkVersion 9
targetSdkVersion 19
versionCode 4
versionName '1.3'
testFunctionalTest true
project.archivesBaseName = "Project name"
project.version = android.defaultConfig.versionName
}
As mentioned in comments below and another answer, the original answer here doesn't work with Gradle 3+. Per the docs, something like the following should work:
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:
// If you use each() to iterate through the variant objects,
// you need to start using all(). That's because each() iterates
// through only the objects that already exist during configuration time—
// but those object don't exist at configuration time with the new model.
// However, all() adapts to the new model by picking up object as they are
// added during execution.
android.applicationVariants.all { variant ->
variant.outputs.all {
outputFileName = "${variant.name}-${variant.versionName}.apk"
}
}
OLD ANSWER:
I am unable to get archivesBaseName & version to work for me w/ Android Studio 0.8.13 / Gradle 2.1. While I can set archivesBaseName and version in my defaultConfig, it doesn't seem to affect the output name. In the end, adding the following libraryVariants block to my android {} scope finally worked for me:
libraryVariants.all { variant ->
variant.outputs.each { output ->
def outputFile = output.outputFile
if (outputFile != null && outputFile.name.endsWith('.aar')) {
def fileName = "${archivesBaseName}-${version}.aar"
output.outputFile = new File(outputFile.parent, fileName)
}
}
}
For Android Studio 3 with Gradle 4 and Android Plugin for Gradle 3.0.0 you have to change the answer of qix to the following:
android {
...
libraryVariants.all { variant ->
variant.outputs.all { output ->
if (outputFile != null && outputFileName.endsWith('.aar')) {
outputFileName = "${archivesBaseName}-${version}.aar"
}
}
}
}
In my case, ${version} result in "unspecified", finnally I found ${defaultConfig.versionName} works.
android {
...
libraryVariants.all { variant ->
variant.outputs.all {
outputFileName = "${variant.name}-${defaultConfig.versionName}.aar"
}
}
}
with the build-plugin 1.5.0 it is now possible to use archivesBaseName in the defaultConfig
For the latest version of Gradle 5+, this is the best answer following #frouo answer:
defaultConfig {
...
versionName "some-version-name-or-number"
setProperty("archivesBaseName", "${archivesBaseName}-$versionName")
...
}
AAR extension will be added automatically.
In addition to qix answer here the info that you can add multiple output paths by this method by an regular string as well:
libraryVariants.all { variant ->
variant.outputs.each { output ->
def outputFile = output.outputFile
if (outputFile != null && outputFile.name.endsWith('.aar')) {
def fileName = "${archivesBaseName}-${version}.aar"
output.outputFile = new File(outputFile.parent, fileName)
output.outputFile = new File("/home/pepperonas/IdeaProjects/Libraries/Base/testapp/libs", fileName)
}
}
}
(Upvotes belong to qix - I just wrote this as an answer because of the readability).
Using Gradle 6+ and AGP 4+, an alternative answer that allows full control of the name is:
afterEvaluate {
android.libraryVariants.all { variant ->
variant.variantData.outputFactory.apkDataList.each { apkData ->
if (apkData.outputFileName.endsWith('.aar')) {
apkData.outputFileName = "${project.name}-${buildType.name}-anything-you-want.aar"
}
}
}
}
For Gradle 5+:
android.libraryVariants.all { variant ->
variant.variantData.outputFactory.output.apkDatas.each { apkData ->
apkData.outputFileName = "YourNewFileName.aar"
}
}
For Gradle 4+:
android.libraryVariants.all { variant ->
variant.outputs.each { output ->
output.outputFileName = "YourNewFileName.aar"
}
}
For Gradle 2+ and Gradle 3+:
android.libraryVariants.all { variant ->
variant.outputs.each { output ->
output.outputFile = new File(file.parent, "YourNewFileName.aar")
}
}

Categories

Resources