¿Cómo leo las propiedades definidas en local.properties en build.gradle?

89

Me he puesto sdk.diry ndk.direntrado local.properties.

¿Cómo leo los valores definidos en sdk.diry ndk.diren el build.gradlearchivo?

Vikram
fuente
15
la verdadera pregunta es: ¿por qué no está integrado en el complemento gradle de Android?!?!?!?!
Armand
@Armand: tal vez porque local.propertiesestá en uso para la propia configuración local de Android Studio, y tener otro archivo con el mismo nombre podría crear un poco de confusión. Consulte stackoverflow.com/a/49306091/1587329 a continuación
serv-inc
1
@Armand es una lástima que esto no se construyó hace 5 años, pero luego se agregó esto: android.getSdkDirectory()simplemente funciona.
Alex Cohn

Respuestas:

139

Puedes hacerlo de esta manera:

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

Úselo project.rootProjectsi está leyendo el archivo de propiedades en un subproyecto 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

En caso de que el archivo de propiedades esté en el mismo directorio de subproyecto, puede usar solo project.

rciovati
fuente
3
¿Qué es "project.rootProject"?
AlexBalo
1
Se agregó una breve explicación
rciovati
¿A qué te refieres con proyecto? Mi ide me está dando un error. ¿Cómo obtengo la ruta del proyecto?
AlexBalo
Dentro de un build.gradlearchivo projecthay una variable que se refiere al proyecto actual. Si tiene errores extraños, haga una nueva pregunta.
rciovati
Si copio su código dentro de una clase de utilidad en app / src / main / java / my_package_name / Utils.java, no se puede resolver. ¿Cómo puedo leer local.properties de una clase de utilidad?
AlexBalo
26

propiedades.locales

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", "")
}

y en el código lo obtienes como otra cadena de Resources -

resources.getString(R.string.default_account_iccid);
Dmitrijs
fuente
2
Esta es la respuesta correcta. ¿Cómo no se selecciona? ¿La respuesta elegida ni siquiera ofrece una solución?
Joshua Pinter
10

Aunque la respuesta de @ rciovati es ciertamente correcta, también hay una forma alternativa de leer los valores de sdk.diry ndk.dir.

Como se señaló en esta entrada de blog de Gaku Ueda (Obtener directorio ndk), la BasePluginclase ofrece métodos para getNdkFolder()y getSdkFolder():

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

Nota: es posible que deba cambiar com.android.applicationa com.android.librarysi está construyendo una biblioteca

Esta es quizás una forma más elegante de leer los valores de la carpeta. Aunque hay que decir que la respuesta proporcionada por @rciovati es más flexible, ya que se puede leer cualquier valor en el archivo de propiedades.

super-qua
fuente
1
Para Gradle 1.1.0, debe usarlo plugins.getPlugin('com.android.library').sdkHandler.getNdkFolder()como se puede ver aquí: stackoverflow.com/questions/28615439/…
Stephan
1
Se rompió de nuevo con el cambio al complemento "experimental" :(
Alex Cohn
8

La respuesta que carga local.properties manualmente arriba obviamente funciona, y la siguiente que requiere que sepa qué complemento se aplicó debería funcionar también.

Estos enfoques pueden ser un poco mejores para algunos, ya que son más genéricos porque funcionan independientemente de si está utilizando el complemento Aplicación, Prueba o Biblioteca. Estos fragmentos también le brindan acceso programático completo a todas las configuraciones de complementos de Android (tipos de productos, versión de herramientas de compilación y mucho más):

Si necesita acceso en un archivo build.gradle que usa el complemento Gradle de Android, simplemente acceda al DSL de Android directamente, ya que ahora está disponible directamente:

project.android.sdkDirectory

La forma más larga (a continuación) de esto es útil si está creando clases o complementos personalizados de Gradle Tasks o simplemente desea ver qué propiedades están disponibles.

// 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}");

En el momento de esta publicación también hay una adbExepropiedad útil que definitivamente vale la pena señalar.

Este código debe ejecutarse DESPUÉS de que el complemento Gradle de Android esté configurado según el ciclo de vida de Gradle. Por lo general, esto significa que lo coloca en el executemétodo de a Tasko lo coloca DESPUÉS de la androiddeclaración DSL en un build.gradlearchivo de aplicación / biblioteca de Android ).

Estos fragmentos también vienen con la advertencia de que a medida que actualiza las versiones del complemento de Gradle de Android, estas propiedades pueden cambiar a medida que se desarrolla el complemento, así que simplemente pruebe cuando se mueva entre las versiones de Gradle y el complemento de Gradle de Android, así como Android Studio (a veces una nueva versión de Android Studio requiere una nueva versión del complemento Gradle de Android).

PaulR
fuente
3

Creo que es una forma más elegante.

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

Funciona en Android Gradle 1.5.0.

Víctor Choy
fuente
1

Me he puesto sdk.diry ndk.direntrado local.properties.

Puede reconsiderar si desea establecer valores manualmente, local.propertiesya que Android Studio ya lo usa (para el proyecto raíz), y

no debe modificar este archivo manualmente ni registrarlo en su sistema de control de versiones.

pero vea la exención específica sobre cmake listada en los comentarios.

serv-inc
fuente
Muy al contrario: el archivo lo mantiene Android Studio y, a veces, es agradable leer su contenido. Afortunadamente, esto ahora es compatible:android.getSdkDirectory()
Alex Cohn
@AlexCohn: claro, leer suena bien. La respuesta solo se trata de configurar manualmente los valores. Ojalá sea más claro ahora.
serv-inc
La manipulación manual de también local.propertieses legítima. Consulte developer.android.com/studio/projects/… : Google recomienda agregar cmake.dir="path-to-cmake"para anular el comportamiento de búsqueda predeterminado.
Alex Cohn
@AlexCohn: como una opción. Con la salvedad If you set this property, Gradle no longer uses PATH to find CMake.. Entonces, ¿cuál es tu opinión al respecto? ¿Recomiendas usarlo o simplemente mencionas que se puede alterar en algunos casos? Es decir: esto NO DEBE ser como en RFC2119 : intente hacerlo de esa manera a menos que haya buenas razones.
serv-inc
1
Interpreto esta frase de manera diferente. "Gradle ya no usa PATH para encontrar CMake" es el propósito documentado de agregar cmake.dira local.properties , no una advertencia o efecto secundario de hacer algo peligroso. No soy yo, es Google quien recomienda usarlo, cuando hay una buena razón (es decir, si no desea que Gradle use PATH para encontrar CMake).
Alex Cohn