In Android Studio I created two configurations:
How can I determine in code which configuration I selected?
I know that there is buildConfigField in /app/build.gradle but the names of the buildTypes do not correspond to the configuration names, so I wonder how does that all fit together.
android {
...
defaultConfig {
...
}
buildTypes {
debug {
...
buildConfigField 'boolean', 'DEBUG', 'true'
}
release {
...
}
}
}
I assume that in Android Studio a configuration corresponds to a schema in Xcode and a buildConfigField corresponds to the Environment Variable in Xcode (me coming from iOS world).
How can I determine in code which configuration I selected?
You don't, insofar as a run configuration is an IDE thing, not an Android thing.
what I want is to define environment variable values that I can use in code, e.g. in a debug build variant I want to connect to the development database, in a release build variant I want to connect to the production database
None of that has anything to do with run configurations. Run configurations are for configuring what is to be run:
the main app
tests for the main app
tests for the something library
etc.
debug versus release are build types, one dimension of the build variant. You choose which build variant the run configurations use via the Build Variants tool, docked by default on the lower-left side of the Android Studio IDE window.
To have different code behavior based upon debug versus release, you can:
Examine BuildConfig.BUILD_TYPE, which will be either debug or release
Use buildConfigField to inject values into BuildConfig from Gradle, based upon build type and/or product flavor
Use resConfig to inject values into resources, such as string resources
Use custom source sets per build type (e.g., src/main/ for your common code, src/debug/ for debug-specific code, src/release/ for release-specific code)
You can configure different resource sets. By default main and debug already exist. To determine at runtime which set was used to build the apk create a new resource file in each resource set, e.g.
app/src/main/res/values/resourceset.xml
and
app/src/debug/res/values/resourceset.xml
and place a single string or integer value inside like this:
<resources>
<string name="resource_set">debug</string>
</resources>
and
<resources>
<string name="resource_set">main</string>
</resources>
You may then use getString() to get the value for R.string.resource_set and you can detect which resource set was used.
I am using this technique to include different Google API client IDs depending on the resource set that was used (to enable debugging with Google APIs and release with another fingerprint then debug).
Related
I have 3 jar files in my Android project's app/libs folder:
api-dev.jar
api-qa.jar
api-prod.jar
I want to use api-dev.jar when I work on the app in the studio (default), build a version of the app using api-qa.jar which will be tested by the QA team, then release the production app with api-prod.jar.
How should I do?
So far I read that I should add a
configurations {
qaCompile
...
}
element to app/build.gradle and use
android {
buildTypes {
...
qa {
...
}
}
}
to define the builds.
I don't know how to point to the appropriate libs/dependencies, I don't know how to make one the default one either, especially in my case where the default one is not the one for the production release...
Also if the API requires a specific key for dev, qa and prod, how do I set it up?
By the way the features are exactly the same between the different builds, the user experience is exactly the same, it's why I want to use builds, not flavors.
Check this out - Add dependency to specific productFlavor and buildType in gradle
Add you jars to the libs directory
Create a build type and product flavor
Use the name to create a specific compile command
Use that to specify your jar file in the libs directory
I have an app with more than a few buildFlavors and three different buildTypes.
I generate the signed apks from Build -> Generate Signed APK.... (Unless there is no other go I'd like to continue using the wizard and not create a script, because i have a constantly increasing set of apps and do not want to modify the script every time.)
The generated apks are named in the following pattern:
app-flavorName-buildType.apk
How can i change the naming pattern to something like this:
app_flavorName_buildType_versionCode.apk
Changes I want to make:
Suffix file name with versionCode
Replace hyphens with underscores
I used to do it in ant using task, but not sure how to do it with gradle.
Trying to figure a solution to create the name straight away in the new pattern rather than trying to rename it once it is generated. Is that possible?
I tried looking under Settings -> Gradle but did not find anything. Any other place i should be looking?
It is not exactly what you are looking for.
You can use your build.gradle to set this attribute:
android {
//...
defaultConfig {
//...
project.ext.set("archivesBaseName", "app_"+ defaultConfig.versionCode);
}
}
Assigning the archivesBaseName you will obtain something like:
app_0.9.6-flavorName-buildType.apk
This attribute requires the gradle-plugin 1.3.1 or higher.
Otherwise you have to use a task to rename the apk after building.
I have two apps that shares same functionality except images,icons,colors,app name and package change and the URL that gets called in the event of network activity.
In iOS we can create two different apps easily from one source code by using the power of targets.
Here is the link on How to do it in iOS
But how to go about it in android
You should leverage product flavors for this.
In your build.gradle, you will define the flavors like so:
android {
productFlavors {
brand1 {
// ...
}
brand2 {
// ...
}
}
}
You can then create flavor specific resources. If you are creating an icon called ic_launcher.png for example, you would typically put it at a location such as main/res/drawable-xhdpi/ic_launcher.png. Instead, you could put the brand1 version at brand1/res/drawable-xhdpi/ic_launcher.png and the brand2 version at brand2/res/drawable-xhdpi/ic_launcher.png.
When you run gradlew build, it will build all variants. You can also build specific variants such by specifying the variant name like so: gradlew assembleBrand1Debug. In Android Studio you can select the variant you want to see using the "build variants" pane.
I have a project in Android Studio with two Product Flavours. They're effectively identical except for a few hard-coded values in them, e.g. URLs, ids and whether to activate some additional functionality.
I'd like to be able to just have one flavour and move these hard-coded values out to some kind of config/properties file which the now generic code could read or pre-load on startup as needed. I'd then like to have some kind of gradle command that creates the different APKs using the different config/properties file.
That way, if I wish to create another configuration for the app (a combination of the properties I mentioned above), I don't have to go copying (and maintaining) another Product Flavour to do this.
It'd be great if this could all be done in Android Studio and not the command line also. Can someone tell me of a way to do this please?
A command-line solution may also be acceptable, but it would ideally have to be Operating System independent as some of our developers work on MACs while others work on PCs.
I and other Android developers around me looked into this ourselves. But we couldn't find anything within the gradle framework that allowed the kind of flexibility I've outlined.
Outside of pre-configured android parameters that can be set in build.gradle, we couldn't find anything where we could configure properties of our own that would affect the build.
The only solution we could see it to have duplicate Product Flavours with the hard-coded values changed to the new configuration we want. We'd like to avoid this at all costs.
Looks like I asked too soon :D .
Someone else in our company managed to solve the problem using build types.
For example, say we wanted a boolean variable saying whether the app should operate in "Test-mode". We can define a "TEST_MODE_ENABLED" variable using the buildConfigField parameter. You could define a "testing" build type in the gradle file as follows (see the last build type):
buildTypes {
debug {
debuggable true
buildConfigField "boolean", "TEST_MODE_ENABLED", "false"
}
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
buildConfigField "boolean", "TEST_MODE_ENABLED", "false"
}
testing {
debuggable true
buildConfigField "boolean", "TEST_MODE_ENABLED", "true"
}
}
This parameter and others can then be accessed in the java code by referencing:
BuildConfig.TEST_MODE_ENABLED
With this concept, we can create as many configurations we like and then define additional Build Variants using these additional build types.
We can also use this with gradlew, e.g.:
gradlew assemble[ProductFlavour][BuildType]
Hope I explained that properly and that it might help someone else.
I have several options - both in code and in the manifest file - that I would like to easily toggle on and off based on whether it's a debug build or release build.
What's the best way to handle things like this in an Android application?
You could use properties files, e.g. one for prod and one for dev. Then you could create an Ant script with two targets, a prod build and a dev build, where the appropriate properties file is copied prior to the APK being built. Make sure that the properties files are copied using the same name, then you can access the deployed one, irrespective of the environment you built for.
In addition to what Tyler mentioned, if you are looking at including optional code in case it is a Debug and not having that code if its a release, then you could look at using the BuildConfig file that is generated by the ADT.
As per the docs: " Added a feature that allows you to run some code only in debug mode. Builds now generate a class called BuildConfig containing a DEBUG constant that is automatically set according to your build type. You can check the (BuildConfig.DEBUG) constant in your code to run debug-only functions such as outputting debug logs."
You will find this file in the Project/gen folder, the same place where the R.java is generated.
Now with Android Studio and Gradle it is easy to do this using the auto generated flag BuildConfig.DEBUG. Like:
if (BuildConfig.DEBUG) {
// Debug code
} else {
// Resease code
}