access Properties file located in app folder in src file in android - android

I want to access a property file from a module root, but failed to find any suitable example to access the property file as many only tells how to access from asset in android. My app structure is as follows,
├── app
│ ├── key.properties <--It is my property file, which contains app keys,to be used in app
│ └── src <-- Here i want to access the key.properties to access some keys
├── build.gradle
├── gradle
├── gradlew
├── gradlew.bat
├── settings.gradle
└── local.properties

Mike M is correct in that you should use gitignore to hide your file from git so it won't be pushed on your repository.
To expand a bit on this, here's a solution to have gradle load your properties during the build, and make them available to your app via BuildConfig.
1/ app/build.gradle
Before the android { ... } plugin, add:
Properties props = new Properties()
try {
props.load(file('keys.properties').newDataInputStream())
} catch (Exception ex) {
throw new GradleException("Missing keys.properties file.");
}
2/ app/build.gradle
In your buildTypes config, add
buildTypes {
debug {
buildConfigField "String", "KEY_MY_PROP", "\"${props.getProperty("myPropKey")}\""
}
release {
buildConfigField "String", "KEY_MY_PROP", "\"${props.getProperty("myPropKey")}\""
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
3/ Any class in your app
Your key is accessible as BuildConfig.KEY_MY_PROP

Related

Android: whitelabel app with a debug directory per each flavor

I am creating some app with multiple branding variations. One of the requirements is that we deliver 2 environments per client, so I need to have one release build per client for debug and release.
The code in build gradle file is
android {
...
buildTypes {
release {
minifyEnabled false
}
debug {
applicationIdSuffix ".debug"
}
}
flavorDimensions "branding"
productFlavors {
mainCompany {
dimension "branding"
applicationIdSuffix ".mainCompany"
}
client1 {
dimension "branding"
applicationIdSuffix ".client1"
}
client2 {
dimension "branding"
applicationIdSuffix ".client2"
}
client3 {
dimension "branding"
applicationIdSuffix ".client3"
}
}
The directory structure tree is:
.
├── androidTest
│   └── java
├── client1
│   └── res
├── client2
│   └── res
├── client3
│   └── res
├── debug
│   └── res
├── main
│   ├── AndroidManifest.xml
│   ├── java
│   └── res
├── mainCompany
│   └── res
└── test
└── java
And the question is, how do I create a debug folder per client? Such folder should have just the app icon and the strings with only the app title
It seems this was a stupid question. At the end, I found the solution in the android docs. Problem was I didn't know how to search this correctly :(
Here is the piece of doc that answers my question.
And the folders in my case should be called:
client1Debug
client2Debug
client3Debug
mainCompanyDebug
And this works exactly as I expected

I already registered in Dailymotion and create apiKey, then how do I generate sampleapp.properties file?

There is a block code in build.gradle file:
Properties props = new Properties()
props.load(new FileInputStream("sampleapp.properties"))
buildConfigField "String", "apiKey", props.getProperty("apiKey")
buildConfigField "String", "apiSecret", props.getProperty("apiSecret")
buildConfigField "String", "defaultLogin", props.getProperty("defaultLogin")
buildConfigField "String", "defaultPassword", props.getProperty("defaultPassword")
I clone dev version from github, and when I open the sampleapp in Android studio, gradle building failded because of missing sampleapp.properties file.
I already registered in Dailymotion and created a apiKey for my application.
Now my question is how to generate a sampleapp.properties file so that gradle building would be successful?
Thank you.
Use project.rootProject if you are reading the properties file in a sub-project build.gradle:
Properties props = new Properties()
props.load(project.rootProject.file('sampleapp.properties').newDataInputStream())
// your code goes here
Project structure
.
├── app
│ ├── build.gradle <-- You are reading the sampleapp.properties in this gradle build file
│ └── src
├── build.gradle
├── gradle
├── gradlew
├── settings.gradle
└── sampleapp.properties
UPDATE
Your sample.properties file should look like shown below, just with your own values:
apiKey="yourKey"
apiSecret="yourSecret"
defaultLogin="yourLogin"
defaultPassword="yourPassword"

Android Studio 1.0.2 proguard rules

I imported an Eclipse project into Android Studio and now I'm trying to revive the proguard part. I have the following in build.gradle:
buildTypes {
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
}
}
and now the questions are:
where and how do I add the file proguard-android.txt and proguard-rules.txt?
The syntax/format of this file in ADT is the same as it was in Eclipse?
I now noticed that I also have cannot resolve symbol 'getDefaultProguardFile'
Here you can find some more information on what getDefaultProguardFile() does. In essence, Android provides two Proguard files for you to use, one with optimizations, one without.
As for your custom proguard-rules.txt file, put it (if it isn't already there) in the same place where your build.gradle file of your App is located. See the SeriesGuide repository for an example.
Edit
Your directory structure (as can be seen in the SeriesGuide repo linked above) should be something like this (directories like src/ have been omitted):
.
├── app
│   ├── build.gradle # this is probably where you defined android { . . . }
│ │ # and thus `proguardFiles`
│   └── proguard-project.txt
└── build.gradle # setting up buildscript, maven repositories etc

How do I read properties defined in local.properties in build.gradle

I have set sdk.dir and ndk.dir in local.properties.
How do I read the values of sdk.dir and ndk.dir in the build.gradle file?
You can do that in this way:
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.
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);
now it's more simple with the new google plugin
1- add your property
sdk_dir="sdk dir"
2- add the plugin (Groovy)
this in top-level (project level)
buildscript {
dependencies {
classpath "com.google.android.libraries.mapsplatform.secrets-gradle-plugin:secrets-gradle-plugin:1.3.0"
}
}
and in your app Gradle
plugins {
id 'com.google.android.libraries.mapsplatform.secrets-gradle-plugin'
}
3- build your project
4- access it like this
BuildConfig.sdk_dir
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.
Adding the property
The following Gradle technique shows you how to store a property in your local.properties file so that it can be securely referenced by your app.
Open the local.properties in your project level directory, and then add your property like the following example:
sdk.dir=MY_SDK_DIR
In your app-level build.gradle file, add this code in the defaultConfig element. This allows Android Studio to read the sdk.dir property from the local.properties file at build time and then inject the build variable into your res/gradleResVlues.xml.
Properties properties = new Properties()
if (rootProject.file("local.properties").exists()) {
properties.load(rootProject.file("local.properties").newDataInputStream())
}
resValue "string", "sdk_dir", properties.getProperty("sdk.dir", "")
Save the files and sync your project with Gradle.
Retrive your string using the following code
getString(R.string.sdk_dir);
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).
I think it's more elegant way.
println "${android.getSdkDirectory().getAbsolutePath()}"
it works on android gradle 1.5.0 .
This is for Kotlin DSL (build.gradle.kts):
import java.util.*
// ...
val properties = Properties().apply {
load(rootProject.file("local.properties").reader())
}
val myProp = properties["propName"]
In Android projects you can also do this:
import com.android.build.gradle.internal.cxx.configure.gradleLocalProperties
// ...
val properties = gradleLocalProperties(rootDir)
val myProp = properties["propName"]
in kotlin dsl :
build.gradle file
val properties = Properties()
properties.load(project.rootProject.file("local.properties").reader())
...
android{
buildTypes {
debug {
buildConfigField("String", "SOMETHING", properties.getProperty("something"))
}
}
}
build.gradle (:app)
sourceSets {
main {
resources {
srcDirs = ["src/main/resources"]
}
}
}
app/src/main/resources/yourfile.properties
test_feature=test-of-feature
YourClass.kt
fun getProperty(key: String): String? {
val properties = Properties()
val propertiesFile = Thread.currentThread().contextClassLoader.getResourceAsStream("yourfile.properties")
properties.load(propertiesFile)
return properties.getProperty(key)
}
getProperty("test_feature")
GL

Android Studio module that depends on another module's tests

I'm trying to get the Gradle Java plugin to execute jUnit tests that exist in an Android project. My solution was to create a second module that applies the Java plugin, and set the test sourceSet to the app module's src/test directory.
test-module's build.gradle:
apply plugin: 'java'
...
dependencies {
...
testCompile project(':app-module')
}
sourceSets {
test {
java.srcDirs += ["${appDir}/src/test/java"]
}
}
This works fine from the command line, but Android Studio refuses to import a project that has source sets outside the submodule. It throws the error: Can't register given path of type 'TEST' because it's out of content root.
.
├── app-module
│   ├── build.gradle
│   └── src
│   ├── main
│   └── test
├── test-module
│   └── build.gradle
├── build.gradle
└── settings.gradle
I tried configuring this from the parent build.gradle, but that didn't change anything. I can add app-module as a testCompile project dependency in test-module, but that doesn't cause test-module to add app-module's tests.
Any ideas for getting test-module to run app-module's tests without provoking Android Studio's limitation about remote source sets?

Categories

Resources