Following is my build.gradle file:
...
defaultConfig {
applicationId "app.com.foo.player"
minSdkVersion 18
targetSdkVersion 23
versionCode 1 // increment with every release
versionName "Foo-1.0" // change with every release
setProperty("archivesBaseName", "$versionName")
testInstrumentationRunner 'android.support.test.runner.AndroidJUnitRunner'
}
...
I have few question related to version name of android apk:
When I build the project, the generated apk name is Foo-1.0-debug.apk. Where from is 'debug' coming from, what does it signify, and how do I avoid/change that ?
How do I generate different names for dev and prod version of apps ?
Is there a way I can automatically increment my version number and version name for each build ?
Thanks in advance.
To generate different name for developmen and product, u can use productFlavors,refer the below link.
https://developer.android.com/studio/build/build-variants.html
In gradle ,
productFlavors{
releaseBuild{
buildConfigField "String", "APP_NAME", '"SAMPLE_APP_PRODUCT"'
}
debugBuild{
buildConfigField "String", "APP_NAME", '"SAMPLE_APP_DEBUG"'
}
}
After setting in gradle, change the BuiltVariant and run the program
With question 1 and 2 you can goto Project Structure select tab Flavors and Build Type to setup config for build.
With question 3 you can make a script in build.gradle in project then use in module. Here I use current time in second as a example:
in project:
ext{
minSdk = 14
targetSdk = 23
verCode = getVersion();
verName = "Foo-1.0"
}
def getVersion() {
return new Date().getTime() / 1000;
}
In module
defaultConfig {
minSdkVersion minSdk
targetSdkVersion targetSdk
versionCode verCode
versionName verName + verCode
}
Related
I have an app with two flavors, each with a unique application id, according to the docs this is how to install both versions of the app on the same phone. But I keep getting the package name conflict error while I try to install either of them while the other one is already installed
Flavor settings
defaultConfig {
applicationId "com.kc.mb.vr"
multiDexEnabled true
minSdkVersion 19
targetSdkVersion 26
versionCode 14
setProperty("archivesBaseName", "vr4.25.1")
}
flavorDimensions "default"
productFlavors {
dev {
versionName "4.25.1"
applicationId "com.kc.mb.vr.dev"
dimension "default"
}
prod {
applicationId "com.kc.mb.vr"
versionName "3.1.2"
dimension "default"
}
}
After installing, I checked with the package name viewer that shows the app with the dev flavor has a packagename + ".dev" and the one with prod has a different package name. But both of them can not be installed together.
Is there any step that I might have missed ?
For example,in your dev flavor,delete applicationId "com.kc.mb.vr" and add following code:
applicationIdSuffix ".dev"
then your dev's package name will be "com.kc.mb.vr.dev"
I am using following build.gradle
apply plugin: 'com.android.application'
def final appId = "com.example.app"
android {
compileSdkVersion 23
buildToolsVersion '24.0.1'
defaultConfig {
vectorDrawables.useSupportLibrary = true
applicationId appId
buildConfigField "String", "DBNAME", "\"mydb.db\""
}
testOptions {
unitTests.returnDefaultValues = true
}
buildTypes {
release {
minifyEnabled false
proguardFile 'proguard-rules.pro'
}
}
productFlavors {
rel {
minSdkVersion 14
applicationId = "${appId}"
buildConfigField "String", "DBNAME", "\"mydb.db\""
targetSdkVersion 23
versionCode 33
versionName '1.4'
}
dev {
minSdkVersion 14
applicationId = "${appId}.dev"
buildConfigField "String", "DBNAME", "\"mydb_dev.db\""
targetSdkVersion 3
versionCode 1
versionName '1.4-beta'
}
}
}
...
I have not copied code from main to rel and dev source sets, and I have just created separate files for each flavor: res/values/strings.xml, res/values/colors.xml, google-service.json.
The application builds well, with different applicationId and installs as separate on the same device.
For the rel flavor everything works well, and it has applicationId = 'com.example.app' equal to original package name and to actual source package name.
But I obtain very strange behavior and look for the dev flavor, which becomes applicationId = 'com.example.app.dev'
Firstly, I see that animations are not working properly, because it seems that they become wrong coordinates.
Secondary, I have many fragments with dynamically inflating views and they are showing partly or not showing at all - differently at different run.
I suggest that the issue is that I have the same package name for classes and probably there emerges so ambiguous class identification.
I see that getContext() returns the same class 'com.example.app.MainActivity' for both flavors and I think this is matter.
I wouldn't like to copy all sources under each source set because i don't need to make changes there - code still the same.
What is a solution?
It was a mistyping that kills many hours to resolve...
I had pointed targetSdkVersion 3 rather targetSdkVersion 23
(I am surprised that it was building at all)
The Issue is solved, Android Flavors are magnificent!
I have gradle project, the simplified android part of the build.gradle of which looks like this:
android {
compileSdkVersion 23
buildToolsVersion "23.0.2"
defaultConfig {
minSdkVersion 15
targetSdkVersion 22
versionCode 1
versionName "1.0"
def mapPlacesApiKeys = [dev_1: [api_key: 'key_1', sender_id: 'sender_id_1'], dev_9: [api_key: 'key_2', sender_id: 'sender_id_2'],prod_1: [api_key: 'key_3', sender_id: 'sender_id_3']]
if (project.hasProperty('env')) {
if (mapPlacesApiKeys.get(env) == null) {
def keyset = mapPlacesApiKeys.keySet()
throw new StopExecutionException("Value '$env' is not a valid environment value. Valid environments: $keyset. You can set an environment by passing the -Penv=<env> parameter to your gradle build.")
}
}
buildConfigField "String", "SENDER_ID", "\"${mapPlacesApiKeys.get(env).get('sender_id')}\""
manifestPlaceholders = [maps_places_api_key: mapPlacesApiKeys.get(env).get('api_key')]
}
}
When I run this from the command line I run it with an environment parameter e.g. -Penv=dev_1. This does 2 things as you can see in the script:
a) Replaces in the androidmanifest the value "maps_places_api_key" with the actual key of the specified environment
b) Adds a String with the SENDER_ID in the BuildConfig java class.
This works fine from the command line. My problem is that in intellij (or android studio, should be the same) when I import the gradle project I get the following error:
-Penv is missing. You can set an environment by passing the -Penv=<env> parameter to your gradle build.
Which is the exception that I am declaring. So my question is how can I structure this code so that the IDE doesn't try to run it when it's loading the project.
Note that I don't want to replace the "env" parameter with any kinds of flavors or buildTypes, as there's about 15 different environments and it's gonna be a mess, but if there's another suggestion that comes in to your mind feel free to share it.
android{
defaultConfig {
applicationId 'com.xx'
minSdkVersion 14
}
productFlavors {
def path="./channel.txt"
file(path).eachLine { line->
def words = line.split(':')
def name = words[0]
def sender_id = words[1]
def api_key = words[2]
"$name" {
buildConfigField "String", "SENDER_ID", sender_id
manifestPlaceholders = [maps_places_api_key: api_key]
}
}
}
}
I'd like to have a layout file which references the versionName attribute in my gradle file:
...
defaultConfig {
applicationId "se.test.myapp"
minSdkVersion 14
targetSdkVersion 22
versionCode 1
versionName "1.0"
}
....
Something like
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/versionName"
/>
Is there a neat way to to this, without having to set up the layout in my code?
According to http://tools.android.com/tech-docs/new-build-system you can create resources directly from gradle, so putting
android {
...
defaultConfig {
applicationId "se.test.myapp"
minSdkVersion 14
targetSdkVersion 22
versionCode 1
versionName "1.0"
}
...
applicationVariants.all { variant ->
variant.resValue "string", "versionName", variant.versionName
}
...
}
in your build.gradle will do the trick
It creates resource file generated.xml during compilation in generated/res folder which is included alongside with resources provided by you in values folder. So you can use android:text="#string/versionName" to reference this value. Unfortunately, sometimes IDE can't resolve this reference, so it'll look like an error in your layout resource (while it's a valid statement and will be resolved at runtime).
You can suppress the error by clicking inside the "#string/versionName", then Alt+Enter, in the menu select "Create string value resource 'versionName", then "Suppress for tag".
Edit: You should not use Jack only for this. As per the official announcement Jack is deprecated (for everything except Java 8 features).
I used a string resource:
<resources>
<string name="app_ver" translatable="false">1.0.2</string>
...
</resources>
in the app's build.gradle:
android {
compileSdkVersion 25
buildToolsVersion "25.0.2"
defaultConfig {
...
versionName "#string/app_ver"
jackOptions {
enabled true
}
}
...
}
And like this:
<Preference
android:title="Version"
android:summary="#string/app_ver"/>
This project in GitHub contains a working version of this.
I use variables in my projects for versionName and versionCode
for example, in the app's build.gradle:
final VERSION_NAME = '2.2.3'
final VERSION_CODE = 15
android {
defaultConfig {
resValue "string", "version_code", VERSION_NAME + " (build " + VERSION_CODE + ")"
versionCode VERSION_CODE
versionName VERSION_NAME
...
}
...
}
Android Studio automatically generates an untranslatable string resource:
<string name="version_code" translatable="false">2.2.3 (build 15)</string>
which I can use in xml:
<Preference
android:selectable="false"
android:title="#string/version"
android:summary="#string/version_code" />
hope it will be useful
I believe you can set the VersionName in your android manifest with a string resource, too. Like this:
AndroidManifest.xml
android:versionName="#string/versionName"
Your Layout xml
android:text="#string/versionName"
But I do not know how compatible this is to gradle.
I want to change the app versionName to whatever is defined in the AndroidManifest file for the specific flavor I'm building.
So if I'm only building one of the 4 defined flavors I have, like:
gradle assembleFlavor1Debug
I was expecting Flavor1 to have the same version name as the one defined for its specific manifest (because of the merging of manifest files), but that's not happening.
How can I know, during build time, which specific flavor is being built?
Because if I know what flavor is being run,
I can extract the respective versionName from the manifest and set it on android.defaultConfig.versionName,
which solves my problem.
As of at least Android Studio 3.1.1 you can do this...
defaultConfig {
versionName "1.0.0"
}
flavorDimensions "dimen1", "dimen2"
productFlavors {
'flavor1' {
dimension "dimen1"
versionNameSuffix "-F1"
}
...
'flavorA' {
dimension "dimen2"
versionNameSuffix "-FA"
}
}
Then for variant flavor1FlavorA the versionName would be 1.0.0-F1-FA
https://developer.android.com/studio/build/build-variants#product-flavors
You can do this in this way
productFlavors
{
test
{
applicationId 'com.example.test'
versionName '1.0.0.test'
versionCode 1
}
product
{
applicationId 'com.example.product'
versionName '1.0.0.product'
versionCode 1
}
}