Consider app.gradleincludes the following:
defaultConfig {
versionName "2.1.6"
}
debug {
debuggable true
versionNameSuffix "-debug"
}
Is it possible to get the version name without the suffix? When using PackageInfo pInfo = applicationContext.getPackageManager().getPackageInfo(applicationContext.getPackageName(), 0);
pInfo.versionName returns 2.1.6-debug is there a way to get only 2.1.6 without doing some string or regex matching.
Thank you!
I would do it using generated BuildConfig:
Gradle
defaultConfig {
def version = "2.1.6"
versionName version
buildConfigField "String", "VERSION", "\"$version\""
}
Java
String version = BuildConfig.VERSION;
Question is old, but it might help someone - I have looked for something similar recently and used this:
debug{
buildConfigField "String", "APP_VER", "\"" + android.defaultConfig.versionName + "\""
}
OR for all buidTypes
buildTypes.each {
it.buildConfigField "String", "APP_VER", "\"" + android.defaultConfig.versionName + "\""
}
OR for all app variants:
applicationVariants.all { variant ->
variant.buildConfigField "String", "APP_VER", "\"" + android.defaultConfig.versionName + "\""
}
Related
I updated gradle 4.0.1 to 7.0.3 because I need the support of new gradle.
I let the auto updater run and after it was done, when I run the code I get the following error:
C:\Users\me\Projects\proj\proj\proj\app\build\generated\source\buildConfig\stage\debug\proj\BuildConfig.java:22: error: illegal forward reference
public static final String APPLICATION_LIST_URL = BACKEND_HOST + "/page";
In build.gradle the buildConfigField is declared like this:
defaultConfig {
applicationId "my.app.id"
minSdkVersion 21
versionCode getBuildTimestamp()
versionName "2.0.0"
buildConfigField 'String', 'APPLICATION_LIST_URL', 'BACKEND_HOST + "/page"'
}
I tried Invaldiate cache/restart and I do not know what else I can try.
EDIT
BACKEND_HOST is also defined:
productFlavors {
local {
dimension "type"
targetSdkVersion 30
buildConfigField 'String', 'APK_DOWNLOAD_RESOLVE_URL', 'BACKEND_HOST + "DOES_NOT_EXIST"'
...
}
remote {
dimension "type"
targetSdkVersion 30
applicationIdSuffix ".remote"
buildConfigField 'String', 'APK_DOWNLOAD_RESOLVE_URL', 'BACKEND_HOST + "/remote/download"'
}
def backendRemote= '"https://myUrl"'
android.applicationVariants.all {
variant ->
def appName = "myApp"
def backendHost = backendRemote
variant.resValue "string", "app_name", appName
resValue "string", "app_version", "${appName} ${variant.versionName}"
variant.buildConfigField "String", "AUTH_HOST", backendHost
variant.buildConfigField "String", "BACKEND_HOST", backendHost
}
}
And I was building it with remote flavor
It's unclear how the build tools determine the order of the field declarations in the BuildConfig. What works though is this (note the BuildConfig.BACKEND_HOST instead of just BACKEND_HOST):
buildConfigField 'String', 'BACKEND_HOST', 'my.backend.host.com'
buildConfigField 'String', 'APPLICATION_LIST_URL', 'BuildConfig.BACKEND_HOST + "/page"'
Chapter 8.3.3 of https://docs.oracle.com/javase/specs/jls/se8/html/jls-8.html explains what forward references are legal and which ones are illegal.
Here's a minimal code sample showing how the BACKEND_HOST can be defined in each flavor:
defaultConfig {
applicationId "com.example.myapplication"
minSdk 30
targetSdk 31
versionCode 1
versionName "1.0"
buildConfigField 'String', 'APPLICATION_LIST_URL', 'BuildConfig.BACKEND_HOST + "/page"'
}
flavorDimensions "version"
productFlavors {
free {
dimension "version"
buildConfigField "String", "BACKEND_HOST", '"www.free.com"'
}
paid {
dimension "version"
buildConfigField "String", "BACKEND_HOST", '"www.paid.com"'
}
}
This works because more specific BuildConfig fields (flavors) are evaluated first before the less specific ones (defaultConfig).
This code is copied from the OP's question and modified to compile by making the references to BACKEND_HOST static:
defaultConfig {
applicationId "my.app.id"
minSdkVersion 21
versionCode getBuildTimestamp()
versionName "2.0.0"
buildConfigField 'String', 'APPLICATION_LIST_URL', 'BuildConfig.BACKEND_HOST + "/page"'
buildConfigField "String", "BACKEND_HOST", '"www.paid.com"'
}
flavorDimensions "type"
productFlavors {
local {
dimension "type"
targetSdkVersion 30
buildConfigField 'String', 'APK_DOWNLOAD_RESOLVE_URL', 'BuildConfig.BACKEND_HOST + "DOES_NOT_EXIST"'
}
remote {
dimension "type"
targetSdkVersion 30
applicationIdSuffix ".remote"
buildConfigField 'String', 'APK_DOWNLOAD_RESOLVE_URL', 'BuildConfig.BACKEND_HOST + "/remote/download"'
}
}
def backendRemote= '"https://myUrl"'
android.applicationVariants.all {
variant ->
def backendHost = backendRemote
variant.buildConfigField "String", "AUTH_HOST", backendHost
variant.buildConfigField "String", "BACKEND_HOST", backendHost
}
In my Gradle file I declare the VersionName and VersionCode like
defaultConfig {
minSdkVersion 17
targetSdkVersion 25
versionCode 2
versionName "1.0"
versionNameSuffix ".alpha1"
setProperty("archivesBaseName", "MyApp.$versionName.$versionCode$versionNameSuffix")
signingConfig signingConfigs.config
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
and in my application I can retreive the versionCode and versionName with
applicationInformation.VERSIONNAME = BuildConfig.VERSION_NAME;
applicationInformation.VERSIONCODE = BuildConfig.VERSION_CODE;
But how can I get the versionNameSuffix? There isn't a field in BuildConfig for it.
BuildConfig.VERSION_NAME contains the concatenation of versionName and versionNameSuffix like :
public static final String VERSION_NAME = "0.71.alpha1";
If you need only the versionNameSuffix, you can create a new BuildConfig variable in your build.gradle like this :
buildTypes {
debug {
buildConfigField "String", "VERSION_NAME_SUFFIX", "\"" + defaultConfig.versionNameSuffix + "\""
}
release {
buildConfigField "String", "VERSION_NAME_SUFFIX", "\"" + defaultConfig.versionNameSuffix + "\""
}
}
You can now get VERSION_NAME_SUFFIX from BuildConfig.VERSION_NAME_SUFFIX which features :
public static final String VERSION_NAME_SUFFIX = ".alpha1";
I need to install 2 versions of my project (Production and Development). I need 2 apps. I'm trying to achive it by using flavors, but when I sign the apk, it always generate the same app, with the same packageName (com.company.project). I've tried removing the applicationId from the defaultConfig but it doesn't work neither.In the manifest, the package name is com.company.project.
Anyone knows how to do that?
This is the build.gradle
defaultConfig {
multiDexEnabled true
minSdkVersion 16
targetSdkVersion 23
versionCode 1
versionName "1.0"
applicationId "com.company.project"
}
productFlavors {
development {
applicationId
"com.company.project.DEV"
versionName "1.0-dev"
resValue "string", "app_name", "Project-Dev"
}
production {
applicationId
"com.company.project.PROD"
resValue "string", "app_name", "Project-Prod"
versionName "1.0-prod"
}
}
When you create productFlavors then the corresponding gradle tasks also changes.
For instance, originally you have only assembleDebug and assembleRelease. But, after implementing productFlavors, the gradle tasks will change. Taking your example in consideration, it will be
assembleDevelopmentDebug
assembleDevelopmentRelease
assembleProductionDebug
assembleProductionRelease
If you are using Android Studio, then you do not have to worry about the gradle tasks. Just select the Build Variant from the menu and build the project. It will run the corresponding gradle tasks and install the build.
I have written a blog explaining this, Product Flavors in Android. A sample project is also available on GitHub.
I'm doing a similar thing and my build.gradle looks like this and it works:
flavorDimensions 'Level'
productFlavors {
alpha {
dimension 'Level'
applicationIdSuffix '.alpha'
}
beta {
dimension 'Level'
applicationIdSuffix '.beta'
}
major {
dimension 'Level'
}
}
I actually set this up in Build -> Edit Flavors and it generated everything for me.
Finally I did it like this:
def appName = 'AppName'
productFlavors {
devel {
applicationIdSuffix ".devel"
def buildId, appNameLabel
buildId = androidApplicationId + '.devel' + androidVersionCode
appNameLabel = appName + 'd' + androidVersionName
buildConfigField "String", "BUILD_ID", '"' + buildId + '"'
manifestPlaceholders = [app_name_label: appNameLabel, buildId: buildId] }
QA {
applicationIdSuffix ".qa"
def buildId, appNameLabel
buildId = androidApplicationId + '.qa' + androidVersionCode
appNameLabel = appName + 'q' + androidVersionName
buildConfigField "String", "BUILD_ID", '"' + buildId + '"'
manifestPlaceholders = [app_name_label: appNameLabel, buildId: buildId]
}
pro {
buildConfigField "String", "BUILD_ID", '"' + androidApplicationId + '"'
manifestPlaceholders = [app_name_label: appName, buildId: androidApplicationId]
}
Below is an extract from my gradle source code. What I want to achieve is to add suffix to app name when buildType.debug is executed. I tried the following code, but variables are in gradle assigned in sequence as they are written in file and not as task order. So in the example below buildVariant variable will always be equal to Release.
{
def buildVariant = ""
buildTypes {
debug {
manifestPlaceholders = [showDebug: 'true']
buildVariant = " (DEBUG)"
}
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
manifestPlaceholders = [showDebug: 'false']
signingConfig signingConfigs.myConf
buildVariant = " Release"
}
}
productFlavors {
flavour1{
resValue 'string', 'app_name', 'Flavour1'+buildVariant
}
flavour2{
resValue 'string', 'app_name', 'Flavour2'+buildVariant
}
flavour3{
resValue 'string', 'app_name', 'Flavour3'+buildVariant
}
}
It was a really interesting puzzle to solve, so thanks for the question!
Here what you can do:
android {
compileSdkVersion 23
buildToolsVersion "23.0.0"
defaultConfig {
....
}
buildTypes {
debug {
}
release {
}
}
productFlavors {
FlavorA {
}
FlavorB {
}
}
applicationVariants.all { variant ->
variant.resValue "string", "app_name", '"' + variant.productFlavors.get(0).name + '_' + variant.buildType.name + '"'
}
}
dependencies {
}
As a result, it'd print the app name "FlavorA_debug", "FlavorB_release", etc.
(NB! I ran it with gradle classpath 'com.android.tools.build:gradle:1.3.0' - works great, though I didn't try with older versions)
I have a gradle config as setup below. To allow for side by side installs of different builds/flavors
buildTypes {
release {
}
debug {
applicationIdSuffix ".debug"
// Somehow add debug suffix to app ID?
}
}
productFlavors {
ci {
applicationId "com.myapp.ci"
ext.betaDistributionGroupAliases = "mobileworkforce.ci"
resValue "string", "app_name", "AppName.CI"
}
staging {
applicationId "com.myapp.staging"
resValue "string", "app_name", "AppName.Staging"
}
production {
applicationId "com.myapp"
resValue "string", "app_name", "AppName"
}
The issue is that I cannot figure out how to update the app_name string resource to have the suffix "Debug" to the app_name string resource (used as the label for the application)
I was able to create a viable solution using manifestPlaceholders instead of generating string resources. It is not ideal because the result is AppName.Debug.CI instead of AppName.CI.Debug but it works.
buildTypes {
release {
manifestPlaceholders = [ activityLabel:"AppName"]
}
debug {
applicationIdSuffix ".debug"
manifestPlaceholders = [ activityLabel:"AppName.Debug"]
}
}
productFlavors {
def addActivityLabelSuffix = { placeholders, suffix ->
def appName = placeholders.get("activityLabel")
placeholders.put("activityLabel", appName + suffix);
}
ci {
applicationId "com.myapp.ci"
ext.betaDistributionGroupAliases = "mobileworkforce.ci"
addActivityLabelSuffix getManifestPlaceholders(), ".CI"
}
staging {
applicationId "com.myapp.staging"
addActivityLabelSuffix getManifestPlaceholders(), ".Staging"
}
production {
applicationId "com.myapp"
resValue "string", "app_name", "AppName"
}
}
Using getManifestPlaceholders().get("...") I always get null, so I was looking for another solution... and maybe is better because I can get correct order in app name...
// build.gradle
def appNameBase = "My App"
buildTypes {
release {
manifestPlaceholders = [ appNameBase: appNameBase, appNameSuffix: "" ]
}
debug {
manifestPlaceholders = [ appNameBase: appNameBase, appNameSuffix: " Debug" ]
applicationIdSuffix ".debug"
}
}
productFlavors {
one {
manifestPlaceholders = [ appNameFlavor: "One" ]
}
two {
manifestPlaceholders = [ appNameFlavor: "Two" ]
}
}
// AndroidManifest.xml
<application android:label="${appNameBase} ${appNameFlavor}${appNameSuffix}" ...>
In my case I wanted for prod just "My App One" and "My App Two" ad for debug "My App One Debug" and "My App Two Debug" and code above works great.