31

Every time i release my app i change all my url strings and some keys from testing to production. The way I do it is just comment out the testing strings before i release. Is there a better way to handle strings based on the build type ?

spaceMonkey
  • 4,475
  • 4
  • 26
  • 34
  • 4
    http://stackoverflow.com/questions/17197636/is-it-possible-to-declare-a-variable-in-gradle-usable-in-java – CommonsWare Mar 16 '16 at 15:19
  • was searching for this one.. great question and answer.. – DJphy Mar 16 '16 at 15:21
  • 3
    Do not do that. Chances of having incorrect strings in production code with your approach are pretty high. Do it this way: http://developer.android.com/tools/building/configuring-gradle.html – Rusheel Jain Mar 16 '16 at 17:10
  • @RusheelJain is there a solution for just android resource values ? – spaceMonkey Mar 16 '16 at 17:17
  • @spaceMonkey Yes the link I gave you. I know this because I tried it myself today only :P I wrote the steps in the answer below. Let me know if something is unclear :) – Rusheel Jain Mar 16 '16 at 17:28

3 Answers3

57

Assuming you use Android Studio, by default the system creates a basic release and debug flavor. So if you add a debug and release folder in the app/src folder of your project you can declare separate values there.

So your structure should be like this:

project
  -app
    -src
      -debug
        -java
          ...
        -res
          -values
            -strings.xml
      -release
        -java
          ...
        -res
          -values
            -strings.xml
      -main
        -java
          ...
        -res
          -values
            -strings.xml

I should also add that if you have a string which isn't defined in either of the debug or the release folder that it will fallback to your main folder.

  • 1
    so every time i work on something should i update all 3 folders ? – spaceMonkey Mar 16 '16 at 17:11
  • what about seperating the url specific strings into a seperate "url-strings.xml" and then having `project/app/src/main/res/values/strings.xml` `project/app/src/debug/res/values/url-strings.xml` `project/app/src/release/res/values/url-strings.xml` – k3b Mar 16 '16 at 17:28
  • 5
    nope, you just have your app in your default `main` folder. Any resource that needs to be different in `debug` or `release` builds you just add to the strings.xml (or as @k3b mentioned a different file). Android Studio will always fallback on the `main` folder so you can have 1 url string in the `debug`/`release` folders and it will only take those. – Jasper van de Klundert Mar 16 '16 at 20:16
  • 1
    I had to use this for **admob ad units** which I created in 3 new resource files (for main, debug and release). In my case, having a release version wasn't necessary, although I still created it anyway. But I made the release and main versions of `admob.xml` same (copy and paste) cos I was porting to other OSes which only recognised the files in the main folder. – aphoe Aug 02 '16 at 12:59
  • Also make sure to change build variant in Android Studio to manage everything integrated – Juan Saravia Jun 10 '17 at 13:36
8

Well, you can use Gradle if needs to use for a few strings

buildTypes {
    release {
        resValue 'string', 'adUnitIdMain', '"production-id-value-should-be-here"'
        resValue 'string', 'adUnitIdList', '"production-id-value-should-be-here"'
        resValue 'string', 'adUnitIdDetail', '"production-id-value-should-be-here"'
        minifyEnabled false
        proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
    }
    debug {
        resValue 'string', 'adUnitIdMain', '"test-id-value-should-be-here"'
        resValue 'string', 'adUnitIdList', '"test-id-value-should-be-here"'
        resValue 'string', 'adUnitIdDetail', '"test-id-value-should-be-here"'
    }
}
Kishan Vaghela
  • 7,678
  • 5
  • 42
  • 67
  • 1
    For those which want to know more about `resValue` you can read up in the DSL document here: https://google.github.io/android-gradle-dsl/current/com.android.build.gradle.internal.dsl.BuildType.html as linked by Google Documentation here: https://developer.android.com/studio/build/build-variants#build-types – Bruno Bieri Oct 06 '20 at 09:41
  • 2
    I was looking for a place to put my adMob unit ids, and this is the perfect place instead of strings.xml. Thank you! – GiveEmTheBoot Jan 31 '21 at 11:19
1

Just make two flavors in build.gradle. Then two directories, again as given in the link (developer.android.com/tools/building/configuring-gradle.html ). Since you need only strings to be altered, just copy your strings.xml files into the new directories (i.e. dev and production) Delete your original strings.xml

And thats it. :)

No need to move your java files or other layout files.

In short, leave everything in your 'main' directory that should be consistent across all build flavors. Override the values dependent upon build flavor into their respective directory.

trevren11
  • 192
  • 1
  • 4
  • 10
Rusheel Jain
  • 843
  • 6
  • 20