I would like to create my strings.xml file dynamically every time I build my project from Android Studio. Right now I'm using Loco to share strings across Android and IOS. This tool exposes an API which response is my strings.xml or .strings file (IOS). I would like to know if there is any way to call the API from gradle in order to update the strings files each time the project is build.
Maybe Fastlane can help me with that issue?
Finally, I found a solution. Basically, with a groovy script in your gradle you can call an http endpoint via URL class from java.net, get the response of the GET call as string and write the response into your string.xml file.
In my build.gradle (Project level) I defined the "syncStrings" task as below:
task syncStrings {
def strings = new URL( 'https://localise.biz/api/export/locale/it-IT.xml?format=android&key=<api_key>' ).text
File file = new File("app/src/main/res/values/strings.xml")
file.write(strings)
}
Hope it helps somebody else ;)
Related
I working an Android application. Some activities, I used webview and load html from Android asesst folder. On apk if rename package to name.apk.zip then anyone can easily access my asesst folder content.
Now I want to protect my assect content mainly html files.
Please help to give some suggest about html encryption or Android studio plugins about protection.
Most efficient way to do this, it's include that files in your Server, and getting files by authorization.
To do it locally. I suggest to create custom task in gradle for mapping your html/css files in some incode storage, with Base64 (encoding just for ex.). It's looks like:
task mapAssets(dependsOn: build) {
SOURCE_FILE = 'Path to Source File'
doFirst {
println "I'm Gradle"
}
String source = new File(SOURCE_FILE).text
ENCODED_FILE = 'Path to Encoded File'
new File(ENCODED_FILE).withWriter { out ->
out.println source.bytes.encodeBase64().toString()
}
}
Later in your Java code, just find ENCODED_FILE and make call with reading file and mapping again in HTML, from Base64 (or any other encoding).
I am using Google Speech API in My Android application and I am taking reference with the sample application provided by Google in docs.
In this sample, there are several lines for the authentication process in App level gradle file.
task copySecretKey(type: Copy) {
def File secretKey = file "$System.env.GOOGLE_APPLICATION_CREDENTIALS"
from secretKey.getParent()
include secretKey.getName()
into 'src/main/res/raw'
rename secretKey.getName(), "credential.json"}
preBuild.dependsOn(copySecretKey)
In this code, I am not getting what is GOOGLE_APPLICATION_CREDENTIALS and where I should paste my JSON.
Thanks in Advance.
file is the location of your json file. they are just showing you how to use the system variable assuming you have that set to the location of said fule
I created Sample data directory for my Android app using the process described in this article. I would like to share this set of sample data between my projects, so I created a library that only has sample data inside. But as far as I can see sampledata folder is not being compiled into the library. Is there a way to share sample data between multiple Android projects?
As already said, you can't do that with a library because sampledata simply can't be part of an Android library.
One thing you could though, host your names file somewhere and then fetch it with a gradle task, you could just add to an app's build.gradle
clean.doFirst {
println "cleanSamples"
def samplesDir = new File(projectDir.absolutePath, "sampledata")
if (samplesDir.exists()) {
samplesDir.deleteDir()
}
}
task fetchSamples {
println "fetchSamples"
def samplesDir = new File(projectDir.absolutePath, "sampledata")
if (samplesDir.exists()) {
println "samples dir already exists"
return
}
samplesDir.mkdir()
def names = new File(samplesDir, "names")
new URL('http://path/to/names').withInputStream { i ->
names.withOutputStream {
it << i
}
}
}
You can see 2 functions there, the first one is run before a clean task and it will just delete your sampledata folder. The second one is a task run on every build, it won't download the file every time but only if the directory is not there.
I understand you might as well copy paste names file, but, with this method you need to copy paste the tasks only once and you would be able to change names in any project just by uploading a new file and doing a clean build.
The short answer is no, you can't do that with sampledata folder. Basically, the format of the Android Libraries is AAR. If you reference the official documentation, it says that:
The file itself is a zip file containing the following mandatory entries:
/AndroidManifest.xml
/classes.jar
/res/
/R.txt
/public.txt
Additionally, an AAR file may include one or more of the following optional entries:
/assets/
/libs/name.jar
/jni/abi_name/name.so (where abi_name is one of the Android supported ABIs)
/proguard.txt
/lint.jar
So, sampledata can't be a part of AAR library.
UPDATE
Instead of your own data samples, you can use predefined sample resources. For example #tools:sample/first_names will randomly select from some common first names, eg., Sophia, Jacob, Ivan.
Example of usage:
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:text="#tools:sample/first_names" />
android project with files in assets, these file need encrypt before generator apk
every times i changed some file in assets,
i need copy out these file , encrypt ,then copy into assets
what i want is:
keep file in assets not encypt (can edit it conveniently) ,
but file in .apk encrypted
encrypt work do automatically by gradle.build
my basic idea is thad add some task before mergeDebugAssets (or mergeReleaseAssets)
before mergeDebugAssets, i replace all file in file://$MODULE_DIR$/build/assets
code like below
task processAssetFile {
// code : replace file in build/assets
}
mergeDebugAssets.dependsOn processAssetFile
the problem is
mergeDebugAssets is not available in gradle.build
error log below:
Could not find property 'mergeDebugAssets' on project ':gradle'.
so is there some idea can achieve my goals ?
android studio ver :0.52
You can always find the task by its name.
I would also suggest that you want to perform encryption for other build variants (makes sense for release even more than for debug).
This requires a little bit of coding since you need to create a task for each variant, too.
It is best to create those tasks dynamically so you don't forget a variant.
Say you're encrypting with some command-line tool, the code you need to add could look like this:
android.applicationVariants.all { variant ->
String suffix = variant.variantData.name.capitalize()
Task mergeAssetsTask = tasks.findByName("merge${suffix}Assets")
Task processAssetFileTask = tasks.create(name: "process${suffix}AssetFile", type: Exec)
processAssetFileTask.commandLine "path/to/your/encryption/tool",
"--input-file=${inputFilePath}",
"--output-file=${outputFilePath}"
mergeAssetsTask.dependsOn processAssetFileTask
}
I have a Parse account that I'm using to store user data for my Android application. Because I'm using source control, I don't want to leave my secret key embedded in the code. Is there a way to have a "config" file that I would keep out of source control, that can then host the key? If that's not feasible, what are the best practices of handling such a situation?
Yes, you can create a folder outside of source control, put a file called app.properties in there, put your key in that properties file and add the folder to your build path. Then use a properties loader to load it from the classpath.
If you have many developers or more than one dev machine, you can set the local properties location as a variable in your build path so that each developer can configure their own.
One option is to put the key in an environment variable and then read it during your build.
in your pom.xml declare a property (secret.key)
<properties>
<secretKey>${env.SECRET_KEY}</secretKey>
<properties>
further down enable "filtering" on your resources
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
In resources maintain a "config.properties" to read with the variable ready for substitution:
secret_key=${secretKey}
Filtering in maven will replace ${secret.key} with the value from your environment variable.
If you are using gradle for your build with Android studio see section 16.6.6.2 on filtering files.
Within build.gradle add the following
import org.apache.tools.ant.filters.FixCrLfFilter
import org.apache.tools.ant.filters.ReplaceTokens
task copyProductionConfig(type: Copy) {
from 'source'
include 'config.properties'
into 'build/targetpath/config'
expand([
secretKey: System.getenv("SECRET_KEY")
])
}
In gradle you can also request input when you run gradlew using
Console console = System.console()
def password = console.readPassword("Enter Secret Key: ")
And then apply it to the appropriate config or source files.