I have inherited an old android app, and the first thing I did, was change the build from Ant to gradle.
The app builds fine, but when I try to run the release target, gradle fails complaining about missing translations.
The folder structure of the resource folder is: (the default language, in the values folder is en-GB)
res/
values/
/file1.xml
/file2.xml
/file3.xml
/values-us/
/file2.xml (containing just the few lines that differ from /value/file2.xml
/values-dk/
file1.xml
file2.xml
file3.xml
So, basically the linter is correct, most of the files are missing in the values-us folder.
However, a single locale contains about 20 files, with around 100+ lines each, and the difference between the default and US is probably 5 lines total, it seems impractical to have to maintain all values for both locales.
To be clear, I absolutely want the release target to fail, when values-dk/ or values-de/ are missing translations, I's just like some way to mark the US locale as an extension of the default. Is this possible?
I think Lint found some strings that are not in res/values but in res/values-{language}. In this case, if the code tries to use one of those strings and the string selection falls to default one (phone is set to a language where you don't provide translations), the application will crash.
The error should tell you which string is not translated. I'd start by checking the languages defining it and make sure it's also in the default ones.
So it turns out this is actually pretty simple. All I had to do was rename the values-us/ folder to values-en-rUS/ and it works.
Related
I've been looking on Internet for this but didn't find any article/blog (probably I have been looking poorly) so I'd decided to ask question here: is it possible to use same strings.xml (translations) from one language folder for another language, which is very similar? To be more specific, I'd like to use translations from values-sk also for values-cz language.
I was thinking about writing a Gradle script which would make a copy of strings.xml file in values-sk folder and copy it into values-cz folder on build, but I'd like to know if there's an easier/out of the box solution.
Well, I solved it using Gradle script before build. In case someone's interested, I added new task in app.gradle (at the end of the file, but that shouldn't matter):
gradle.projectsEvaluated {
preBuild.dependsOn(copySkStringsFileToCsFolder)
}
task copySkStringsFileToCsFolder(type: Copy) {
description = 'Copies strings.xml from values-sk to values-cs'
from 'src/main/res/values-sk/strings.xml'
into 'src/main/res/values-cs'
}
From what I overview, it copies the file on every Sync/Build operation - works pretty neatly for me, but I am still interested in other possibilities (if there are any).
Also I would like to apologize to Czech people that I misinterpreted the code for values folder (using -cz instead of -cs) - sorry 'bout that, I didn't know I was supposed to use the other one. :)
Create both values-sk & values-cz folder in your /res directory of your project and then copy-paste the strings.xml to each. As you can see, those will be different directories but with the same strings.xml so, it probably should work.
After that, Android will detect that you have two different directory-strings for two different localization then, you can change, modify each one of them (If needed).
I have a big and messy string.xml file with 3000 records, which most of the values are useless and never used inside code. I want to find and omit those useless records automatically. Is there a way to find useless records inside string.xml file?
Right click on strings.xml file:
Click on Refractor and then on Remove Unused Resources.
Click on Refractor in the confirm Dialog Box.
Menu -> Analyze -> Run Inspection by Name -> Unused resources
Actual resource Is there any simple way to find out unused strings in Android project?
use (Remove Unused Resources) in Android Studio
link
I found the that using the lint check and the translations editor works like a charm.
Go Analyse -> Run inspection by name -> Unused resources.
Here i add a file mask to only show me the strings
After the check has ran go to the Translations Editor, find the key(s) right click and safe delete.
This checks of the resource can safely be deleted and deletes the key in all your locales.
I would suggest the best way would be to load the XML into objects such as Python ElementTree.
import xml.etree.ElementTree
You can then easily Prune all the branches down easily before exporting as an XML file. To deal with XML on a string level is a nuisance.
I have a value for a String in String.xml
<string name="id">4</string>
and I have a class which contains a variable
public static int Id=1;
Now what I need is I want to get either of these two values in the gradle, which will check a condition and based on the condition it will rename my app. Below given is the part of the gradle code
def identifier //here i need to get value from the java or xml
switch(identifier)
{
case 1:
temp="ApplicationNewName";break;
}
newName=newName.replace("-release",temp);
output.output.File=new File(output.outputFile.parent,newName);
My question is that, Can i access the variables initialised in the java file or string xml in gradle file ?
You're approaching this problem backwards, Gradle gives you the ability to set those variables within the script itself and then you can further access those variables throughout your Android code. Here's a relevant answer for how you can set build configuration variables: https://stackoverflow.com/a/17201265/2168085
It also sounds like you are trying to build different apps from a single code base, or build variations of those apps. If that's the case then you should really look into build flavors to solve this problem. Essentially a build flavor allows you build different apps from a single main code base and apply variations or new functionality to the different flavors. This can be as basic as having a free and paid version of an app or a full white label code base where you can build very different apps from the same master code base. In Android these are more commonly known as build variants and the developer documentation gives plenty of good information on how to get started: https://developer.android.com/studio/build/build-variants.html
I am currently working on an Android project with multiple source sets.
My question is concerned with string resources.
The majority of the string resources are in the main/res/values directory.
There is an alternative source set called foo which overrides some of the string resources in main/res/values. This works just fine, however there is an additional source set we can call foobar that is a slightly different version of foo.
Is there a way foobar can be configured to use the resources defined in foo/res/values instead of defaulting back to main/res/values? Despite the source sets both being slightly different, the resources between foo and foobar are to be identical so I'd only like to write them once.
Essentially in foobar if I try to get the string resource cat I want it to look in foo/res/values/string.xml as if I was making the resource reqeust in foo; and just like in foo; fallback to main/res/values if that resource isn't defined.
Is there a way that I can structure my project to have this behavior? I am limited in how much I can restructure the source sets within the project, so I understand that the problem I am presenting might go against some conventional practices.
The solution to my problem was to add the following to my application's build.gradle
android.sourceSets {
foobar.res.srcDirs = ['src/foo/res']
}
my app has a styles.xml file with various visual constants defined.
I'd like my users to be able to switch the entire app to an alternative visual theme. I'd like to provide an alternative styles2.xml file and switch at runtime (via the Settings).
Is this possible, and how? I suspect the style names' appearance in the generated R class does not bode well.
If it's not possible, what's my next best option?
Not sure if anyone is still interested but I have found a possible solution. A bit hackish but gets the desired result.
Basically I set up my 2 style files in separate country code directories:
res/values-mcc199/style.xml
res/values-mcc198/style.xml
Then in my activity I use the following to change which is referenced:
Configuration config = new Configuration();
config.mcc = 199;
getBaseContext().getResources().updateConfiguration(config,null);
I've only done some basic testing so far but it appears to work. Obviously if you are already using country code to decide your layouts then this will interfere. I think there may be problems as well if the phone gets an event about a country change.
Actually, after some reading of the doc, it seems that this can be done. Look here.
As it is mentionned :
To create a set of styles, save an XML
file in the res/values/ directory of
your project. The name of the XML file
is arbitrary, but it must use the .xml
extension and be saved in the
res/values/ folder.
Now, if this is logical and I didn't read the doc wrongly, you can create as many styles as you want, reference them in themes.xml with #style/... (if you want to apply it to a whole activity or application) and then, just call
setTheme(R.id.yourtheme)
I think this should work. Have a go at it and tell us?
It's not an exact answer; in my blog post here:
http://blog.blundell-apps.com/switching-android-configurations-using-constants-and-ant/
I switch out a java class at build time using Ant, there is nothing to stop you switching out an XML file, as it compiles after the switch. To amend the tutorial you'd just have to change the path's of the file your templating.
Also mirrored on GitHub: https://github.com/blundell/BuildChoiceTut