如何读取build.gradle中local.properties中定义的属性


88

我已sdk.dirndk.dirlocal.properties

如何阅读中定义的值sdk.dirndk.dirbuild.gradle文件?


15
真正的问题是:为什么这不是内置于android gradle插件中?!?!?!?!
阿曼德

@Armand:也许是因为local.properties用于Android Studio自己的本地配置,并且拥有另一个同名文件可能会造成一些混乱。请参阅以下stackoverflow.com/a/49306091/1587329
serv-inc,

1
@Armand遗憾的是它不是5年前建造的,但后来又添加了:android.getSdkDirectory()简单有效。
亚历克斯·科恩

Answers:


137

您可以通过以下方式进行操作:

Properties properties = new Properties()
properties.load(project.rootProject.file('local.properties').newDataInputStream())
def sdkDir = properties.getProperty('sdk.dir')
def ndkDir = properties.getProperty('ndk.dir')

Use project.rootProject if you are reading the properties file in a sub-project build.gradle:

.
├── app
│   ├── build.gradle <-- You are reading the local.properties in this gradle build file
│   └── src
├── build.gradle
├── gradle
├── gradlew
├── gradlew.bat
├── settings.gradle
└── local.properties

In case the properties file is in the same sub-project directory you can use just project.


3
What it is "project.rootProject"?
AlexBalo

1
Added a brief explanation
rciovati

What do you mean with project? My ide is giving me an error. How do I get project path.
AlexBalo

Inside a build.gradle file project is a variabile which refers to the current project. If you have strange errors ask a new question.
rciovati

If I copy your code inside a utility class in app/src/main/java/my_package_name/Utils.java it cannot be resolved. How can I read local.properties from a Utility class?
AlexBalo

26

local.properties

default.account.iccid=123

build.gradle -

def Properties properties = new Properties()
properties.load(project.rootProject.file("local.properties").newDataInputStream())

defaultConfig {

    resValue "string", "default_account_iccid", properties.getProperty("default.account.iccid", "")
}

and in code you get it as other string from Resources -

resources.getString(R.string.default_account_iccid);

2
This is the correct answer. How is it not selected? The chosen answer doesn't even provide a solution??
Joshua Pinter

10

Although @rciovati's answer is certainly correct, there is also an alternative way of reading the values for sdk.dir and ndk.dir.

As pointed out in this blog entry by Gaku Ueda (Getting ndk directory) the BasePlugin class offers methods for getNdkFolder() and getSdkFolder():

def ndkDir = project.plugins.findPlugin('com.android.application').getNdkFolder()
def sdkDir = project.plugins.findPlugin('com.android.application').getSdkFolder()

Note: You may have to change com.android.applicationto com.android.libraryif you are building a library

This is maybe a more elegant way of reading the folder values. Although it has to be said that the answer provided by @rciovati is more flexible, as one could read any value in the properties file.


1
For Gradle 1.1.0 you nee to use plugins.getPlugin('com.android.library').sdkHandler.getNdkFolder() as can be seen here: stackoverflow.com/questions/28615439/…
Stephan

1
Broken again with the shift to "experimental" plugin :(
Alex Cohn

8

The answer that loads local.properties manually above obviously works, and the next one that requires you to know which plugin was applied should work as well.

These approaches might be a little better for some since they are more generic because they work regardless of whether you're using the Application, Test, or Library plugin. These snippets also give you full programmatic access to all of the Android plugin config (Product Flavors, Build Tools version, and much more):

If you need access in a build.gradle file that is using the Android Gradle Plugin simply access the Android DSL directly as it's now available directly:

project.android.sdkDirectory

The longer form (below) of this is handy if you're creating custom Gradle Tasks classes or Plugins or simply want to view which properties are available.

// def is preferred to prevent having to add a build dependency.
def androidPluginExtension = project.getExtensions().getByName("android");

// List available properties.
androidPluginExtension.properties.each { Object key, Object value ->
    logger.info("Extension prop: ${key} ${value}")
}
String sdkDir = androidPluginExtension.getProperties().get("sdkDirectory");
System.out.println("Using sdk dir: ${sdkDir}");

At the time of this posting there is also a handy adbExe property that is definitely worth noting.

This code has to execute AFTER the Android Gradle Plugin is configured per the Gradle livecycle. Typically this means you put it in the execute method of a Task or place it AFTER the android DSL declaration in an Android app/libraries' build.gradle file).

These snippets also come with the caveat that as you upgrade Android Gradle Plugin versions these properties can change as the plugin is developed so simply test when moving between versions of the Gradle and Android Gradle plugin as well as Android Studio (sometimes a new version of Android Studio requires a new version of the Android Gradle Plugin).


3

I think it's more elegant way.

println "${android.getSdkDirectory().getAbsolutePath()}"

it works on android gradle 1.5.0 .


1

I have set sdk.dir and ndk.dir in local.properties.

You might reconsider if you want to manually set values in local.properties as that is already in use by Android Studio (for the root project), and

you should not modify this file manually or check it into your version control system.

but see the specific exemption about cmake listed in the comments.


Quite contrary: the file is maintained by Android Studio, and sometimes it's nice to read its contents. Luckily, this is now supported: android.getSdkDirectory()
Alex Cohn

@AlexCohn: sure, reading sounds good. The answer just deals with manually setting the values. Hopefully clearer now.
serv-inc

Manual manipulation of local.properties is legitimate, too. See developer.android.com/studio/projects/…: Google recommends to add cmake.dir="path-to-cmake" to override the default lookup behaviour.
Alex Cohn

@AlexCohn: as one choice. With the caveat If you set this property, Gradle no longer uses PATH to find CMake.. So what's your take on it? Do you recommend using it, or do you simply mention that it can be altered in some cases? That is: this SHOULD NOT is as in RFC2119: try to do it that way unless there are good reasons?
serv-inc

1
I interpret this phrase differently. "Gradle no longer uses PATH to find CMake" is the documented purpose of adding cmake.dir to local.properties, not some caveat or side-effect of doing something dangerous. It's not me, it's Google who recommend using it, when there is a good reason (i.e., if you don't want Gradle to use PATH to find CMake).
Alex Cohn
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.