Many times I've seen Android apps that have a list of languages displayed and I can tap on any of this language and download it for this specific app (GO Weather widget has this functionality).
I'm interested in how is this implemented and what is the best way to load languages dynamically in Android apps? Adding 100 string.xml resources in app project is not a solution and besides if I want to provide some kind of "funny holiday language" pack or add a new language I would need to upload the project to Google Play again and again...
Thanks!
While it's possible to use Expansion Files to add on to your app, they are limited in some ways. The main problem for you would be that you can only have a limited number of expansion files. If you wanted 100 languages, your only option would be to load them all in the expansion file, and download the whole thing. While that might not be a problem, since a list of translated strings probably isn't that large, you may want to go a different route.
The best option I see for downloading separate language add-ons is to forgo using strings.xml altogether. Just use a simple CSV file to hold your strings, mapping names to strings. When your program starts, read it in to a string array/map/whatever, and you have all your strings at the ready. This way, if you want to add a language, it's as easy as downloading a text file and saving it to your data directory.
Also, you can keep a file listing all the available languages on the same server, so you don't have to update the app if you want to add seasonal or limited-time-only languages, like you mentioned. Just read in the file to get the list.
Note, you'll need somewhere to host the files, but that's hardly a barrier in this day and age.
Related
I am very new for developing the multi-language oriented Android APP. This is the first time i am going to support my app in multi-support language app. I need some clarification for developing the multi-language support app. Already i have some ideas before initiate the development.
Single APK with Localization like will make the multiple String.xml and include it in inside of the app and based the member selection of language its automatically invokes and works.
All language strings values will retain in app server (back-end) and will raise the Rest-API request and get those values and change it inside of the entire app (all screens) if member click and change the language inside of the app.
Main concern is if anything needs to change in future then Idea2 is best way. We will just change in back-end side it will be appeared in client side. But if we are going Idea1 and wants to change then we need to put the new build only.
Which one is best approach and recommended way to develop?
You will need to create different String.xml depending the languages you want to target as JDenais says, in my app i have the following
for example the first arab string consist in the same as Strings.xml but with all in arab, now, you only need to call one string in your xml files and it will just select where to grab depending on the phone language. Or in default the language from where the app was downloaded by google play, in fact, they are all the same strings.xml , so you dont need to specify which one you want to pull the translated text from, just replicate your main strings.xml in your other strings.xml and then the phone will decide where to pull the data.
Also please read the official doc on how to accomplish this https://developer.android.com/training/basics/supporting-devices/languages
Also please check the language ISO Codes here
What is the list of supported languages/locales on Android?
All your texts should be packaged in the APK in different String.xml files. Forget about receiving texts from a backend. It would be a lot of extra work for limited gain and with added risks of failure.
The framework takes care of selecting the appropriate string.xml file and offers support for needed use cases like plurals.
right click the values folder and choose new-> values resource file -> locale -> choose the language you want and name it strings.
copy the strings from the original string file to the new file and change them to the new language just the strings
make sure that the view xml files have their text set as "#string/the_name of the string" not hard coded
Why i ask this is because the size of my APK is huge. I wanna make it smaller.
There're lots of strings in strings.xml. Our product manager force us to support all languages on the earth.
I'd like to know, can I just put some languages of strings.xml locally, put others in a server, then when user launches the app, downloads the strings.xml from it dynamically according to the language of the user.
I am not quite clear about the process of how android load the strings.xml file. Any idea about it?
Thanks~~
can I just put some languages of strings.xml locally, put others in a server, then when user launches the app, downloads the strings.xml from it dynamically according to the language of the user.
You cannot modify resources at runtime. You are welcome to download and process XML files at runtime, and those XML files might contain strings that you want to display to the user. However, you cannot use the Android resource system to pull in those strings. You would need to write your own Java code that uses those values, including determining which translation to use for a given device (taking into account the multiple-locale support offered in Android 7.0).
You can easily call some web-service on your application start and fetch the strings of desired/selected language in form of say JsonArray. Then parse that data to some data-model like ArrayList of string to manage in your app
In our multi-platform projects, we have multiple localization files with different notation and file format (iOS .string, Android .xml, etc.).
Now we want to localize them in many languages, but in the different files, there are many equal strings. so anybody knows of a good way to consolidate these strings-files to one big localization file, hand this to the translation agency and then splut them back up into the different files?
Anybody knows a good approach?
I've worked on an iOS/Android project with 20 translations, and we used an Excel spreadsheet to keep track of all the translatable strings. The *.strings files for XCode and the *.xml files for Eclipse are then automagically generated using my custom VBA macro.
I've put an example Excel spreadsheet with VBA macro here:
http://members.home.nl/bas.de.reuver/files/multilanguage.zip
You can convert your existing .strings or .xml files to spreadsheet format (key value pairs, tab separated) with the tool below. Then you can send the spreadsheet to your translators, they fill in a column of translated values, send it back and you can simply generate your new translation files.
http://members.home.nl/bas.de.reuver/files/stringsconvert.html
EDIT in 2021
The homepage is offline now, but I've added the Excel/spreadsheet example on github:
https://github.com/BdR76/Manage-translations
Was in the same situation with my app about a month ago.
If you use SmoothLocalize for your localization (which I would recommend as they are really easy and super cheap), you don't have to pay for repeat strings on the 2nd order. So you would pay the full 4c/word for your iOS localization, then just paste in your order number for the Android localization and you don't have to pay to translate them again.
Also if they are EXACTLY the same, they will convert a .strings to a .xml for you so you would only have to do one order, just email them.
In the app I'm building, I'm using multiple languages. It's easy to add a different language into an app by adding a new folder (for example: values-fr) and adding a new strings.xml file in there. But I have pretty large text files (complete articles) that I need to add. These articles are also written in different languages. What is the best way to add them to my app?
I'd consider using res/raw-<qualifiers> as alternative to the assets. The raw folder can store arbitrary files in their - you guessed it - raw form. For example, a 'Hello World' article written in French and English, would be stored under:
res/raw-fr
res/raw-en
The raw resource can then be opened by calling openRawResource(int id) on a resources object, similar to how it works for other resources like drawables, strings etc. The id's generated by the framework will be in the familiar format of R.raw.filename (without file extension).
The benefit of using this approach is that you can fully leverage Android's localization system, meaning that as a developer you basically don't have to worry about any of that at all. You can also easily add more qualifiers to further filter on device characteristics (e.g. screen size, density, platform version etc etc - see here for a full overview). The downside is that it imposes some limitations in terms of the original file name/extension and doesn't support a proper folder/file hierarchy.
The 'better' approach (/raw vs /assets that is) will probably depend on your project's requirements.
I would probably use assets -- that is, create assets/data/fr/ and store the fr files there. Note that assets require explicit extraction -- which probably is good since you may save memory having only one set of articles installed.
Another possibility is to place everything on an http server, and thus make both keeping and accessing the articles somebody else's problem :) .
BTW, if you files are really big, you will have to install the application without them, and download the articles later. (There are restrictions on the apk size.)
In the case of a windows application(EXE/DLL), we can change or add language resources within the binary without re-compiling it. Can the same be done in case of an Android application? Is there any editor available to make this happen?
My plan is to develop the application in English and then release it to the sales department, where they will be responsible for the localization of the application without compiling and packaging it into a new APK. I just want to split the development part and localization part of the app.
The correct way to localize is to create a string resource for your base language and then have that localized and reimported into your project for every language that you support.
Much more detail can be found in the Localization documentation.
I don't believe there is a safe/supported way to inject localized strings into your app after it's been built.
No. You can not, because once your apk is signed then modifying it after this (you can always do that as apk is just a zip file) will corrupt the signed binary.
When having multiple languages with your application you have to build them into the application itself. Android uses XML files to store strings used within your application. Android allows you to add language localization files containing local specific strings. You can't do this without recompiling your project so you'll want to do it as a future update or right from the start. But you can't have the marketing department do it, that's just not a good idea.
As others have said, the short answer is no. The long(er) answer is sort of. If you pack all your language resources into remote XML that can be updated from the web, then with a little bit of forethought you can do all sorts of live updates to your app's strings, graphics, etc.
So if you want to use the standard R.string method for everything it will be a little difficult. I think it's possible to do something funky with a dynamic classloader for the assets and static dex classes (basically classes of data with just inline byte arrays that can be decoded after). However that would still require compiling. See Custom Class Loading in Dalvik for more info.
Another approach would be more of a standard Java implementation. Java has a class known as ResourceBundle. You could create a ResourceBundle from a property file (key-value plain text, or even property xml). Then these files could be loaded outside the apk, via a network connection or sdcard or other file type resource and deleted as necessary. You will have to write the loader code for it, but that's going to happen with any solution. This solution will be less performant and outside the standard design methods for android but it will solve the problem being asked to solve. Like you won't be able to use R.string or #string/whatever for any of these resources but I think you may be able to write an adapter to such resources (like your own TextView extension and whatever that would allow all of this). It's a matter mostly of how much work you want to invest in solving this actual problem.
Honestly I would opt for trying to distribute whole apks with only the targeted language if you are trying to save space, but then there is no way to change locale for the app at runtime :(