12

I was wondering what the best way of storing an api key is in android studio. I would want to exclude this file from github using gitignore.

I have seen some people use the gradle.properties in the HOME directory but the api is specific to my application.

I also notice there is a gradle.properties in a new android studio project but this can contain other things that I may not want to exclude.

Anyone know the best way to do this ?

So the file would be available locally and my project would read it at runtime but I would "maybe" gitignore this file so I wouldn't commit it so I would not expose my api key.

Martin
  • 23,844
  • 55
  • 201
  • 327
  • I also noticed a local.properties file but unsure how this works and it specifically says "Do not modify this file", so i don't think that is a good candidate – Martin Jul 31 '15 at 10:14
  • What about shared preferences? – Hans1984 Jul 31 '15 at 10:16
  • Shared preferences ? No, what i mean is that an api key i use to contact a service that needs to be present in code but I must not commit this file to github otherwise others can see the file and hence see my api. Shared preferences is to store user settings at runtime.. – Martin Jul 31 '15 at 10:18
  • Ok my bad. I gues I missunderstood what you were talking about. – Hans1984 Jul 31 '15 at 10:20

4 Answers4

3

I have seen some people use the gradle.properties in the HOME directory but the api is specific to my application.

I see no problem with API being specific to your app. We have similar situations sometimes, so we just use some unique name for gradle.properties entries. Something like

(MY_APP_NAME)_(MY_API_NAME)_API_KEY

Also we're storing passwords to our internal Maven repositories in the same way, so they're not pushed to GitHub as part of build.gradle file. I can say we're pretty happy with that approach.

Some alternatives which I can think about:

  • Explicitly pass parameters to gradle while executing task. So, you can store those parameters in Android Studio configuration.
  • You can apply another .gradle file to your buildscript (which will contain your variables) using apply from: 'path-to-my-local-script.gradle'. Just don't forget to add it to .gitignore.
Dmitry Zaytsev
  • 23,650
  • 14
  • 92
  • 146
  • Thanks, yes it seems a solution but the file could grow. I saw the android studio project itself has an gradle.properties also but it appears it maybe used for things that need to be checked into source control so its not an ideal candidate for excluding ? – Martin Jul 31 '15 at 10:22
  • @Martin it is just one way to do it. You can also explicitly pass parameters to gradle while building. You can use `apply` command in your `build.gradle` and include some `.gradle` file with variables defined. – Dmitry Zaytsev Jul 31 '15 at 10:22
  • Hey now that sounds pretty cool, using apply to include some "other" .gradle file. – Martin Jul 31 '15 at 10:23
  • Thanks thats great, just out of interest do you have an example of how i would access those variables from code in my "new" gradle file ? – Martin Jul 31 '15 at 10:47
  • @Martin you can declare project's global variables. http://stackoverflow.com/a/25600733/926907 – Dmitry Zaytsev Jul 31 '15 at 11:55
  • Ermm, really confused. I added the following to the gradle.properties file TestProperty='ttt' and now I get an error Gradle sync failed: No such property: TestProperty for class: org.gradle.api.internal.project.DefaultProject_Decorated Consult IDE log for more details (Help | Show Log) – Martin Jul 31 '15 at 19:10
3

You can store api keys with help of gradle and the system path variable Add new system PATH variable THE_MOVIE_DB_API_TOKEN="XXXXX":

For Windows OS:

  • Open System
  • Advanced system settings
  • Environment variables
  • Add new variables to the user variables

Add the following code to the build.gradle file

apply plugin: 'com.android.application'

  android {
   ...

    defaultConfig {
        ...
    }
    buildTypes {
        release {
            ...
        }
        buildTypes.each {
            it.buildConfigField 'String', 'THE_MOVIE_DB_API_TOKEN', "$System.env.THE_MOVIE_DB_API_TOKEN"
        }
    }
}

Use the API keys in Java code like this

BuildConfig.THE_MOVIE_DB_API_TOKEN)

Anirudh
  • 453
  • 2
  • 5
  • 18
Denis
  • 2,622
  • 3
  • 22
  • 24
3

on MacOS Put this into ~/.gradle/gradle.properties

THE_MOVIE_DATABASE_API_KEY=***********

Android Studio Gradle int build.gradle

    defaultConfig {
    applicationId "com.sample"
    minSdkVersion 16
    targetSdkVersion 27
    versionCode 1
    versionName "1.0"
    testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    buildConfigField "String" , "API_KEY" ,  "\"$THE_MOVIE_DATABASE_API_KEY\""
}

Then in Java Code you can Access BuildConfig.API_KEY

  • My `gradle.properties` is under source control so that does not help. Posted a solution below which reads it from `local.properties` instead. See: https://stackoverflow.com/a/76351043/3969362 – Slion May 28 '23 at 10:39
0

You could define it in local.properties which is not usually under source control:

apikey="sdkjhqsffoief"

Your build.gradle should then look like:

android {
    //…
    // Load properties file containing our API key
    Properties properties = new Properties()
    properties.load(project.rootProject.file('local.properties').newDataInputStream())
    def apikey = properties.getProperty('apikey')

    defaultConfig {
        //…
        buildConfigField "String" , "API_KEY" ,  apikey

    }

    buildFeatures {
        //…
        buildConfig true
    }
}

In code you can access it like that:

val apiKey = BuildConfig.API_KEY
Slion
  • 2,558
  • 2
  • 23
  • 27
  • See: https://stackoverflow.com/a/22012018/3969362 and https://stackoverflow.com/a/48273566/3969362 – Slion May 28 '23 at 14:09