Using large text files in different languages in Android - android

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.)

Related

Loading resources from external files

I am working on a localization strategy for our Android product. Once the core product is installed, I would like the user to be able to download additional language packs. Our resources are mainly strings. Essentially, I would like to keep the external file in xml format, similar to how it is done for embedded resources. This way, the translators can also test their translations right away and there won't be any need for sending them back-n-forth.
I am wondering if anyone has done something similar? The biggest challenge I see is that for embedded resources, the key gets converted to a numeric value. For example, getString(R.string.hello) may not work.
On second thought, it would be nice if I can compile the external resource file, similar to what Android framework does when building the .apk file.

Android use of resources from an external file

I have a non-standard Android application that has a requirement to load resources from an external file that is not part of the application apk. These resources will be packaged separately and delivered as its own package.
There are a few different types of items that will be part of this external resource bundle. One of those items includes the localized strings.xml file. This philosophy allows the change of a string / translation that does not affect the deployment of the application (in other words, application.apk stays in tact, but the only difference is a new strings.xml).
I've been searching around, and this doesn't seem possible. Is there any way? Or does this philosophy mean completely abandoning the resources all together and writing a custom layer to pull these strings and other external resources from a file?
The application is for Honeycomb platform.
Thanks in advance for any advise.
The best way to do this, I think, is to package your resources as a ContentProvider. See the guide topic Content Providers for how to get started doing this.

Is it possible to make use of the Android resource resolver on a self-created folder in the file system?

I'd like the ability to "overwrite" the Android resources packaged within my apk by having the app periodically download a zipped file containing overrides that follow the same naming convention as the source does. For example, the zip might consist of the following paths:
res/values/strings.json
res/values-land/strings.json
My code would parse those files and produce a Map> that would map the string resource id to a folder->value pair (or something along these lines). At this point I'm really only concerned with strings and images (maybe arrays), but not layouts, etc.
To the point: Is there any method available, that, given a list of folder names, would tell me which one the Android resolver would choose based on current state? I'm assuming this is difficult because the compiler breaks everything down to ids, but figured it was worth a shot. Any ideas?
Is there any method available, that, given a list of folder names, would tell me which one the Android resolver would choose based on current state?
No. You are welcome to roll this yourself based on Configuration, DeviceMetrics, and kin. You will also need to create your own parsers for your own files, as Android's resource system only works with resources, not arbitrary files retrieved from arbitrary locations.
The expectation in Android is that if you want to update resources, you update the app, probably because there were also code changes as well. Admittedly, this approach has its limitations.

Is there a way to add or change Android apps language after packaging it into an APK?

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 :(

Adding new String resource to multiple (localized) strings.xml files in Android app

I have an app with support for several different languages.
Now lets say I want to add a new feature, which will usually will require new string resources to be added.
What is the (Or is there) way to add new string resources that will be added automatically to all the localization strings files? (Means i'll just need to translate the content of the string and not to create new one with the same key for each localization file)
Because it dosen't make any sense to copy-paste it manually when you have a lot of localization files...
If you follow Android localization rules, there isin't any other way other than manually adding to each language strings.xml file. You can script this but then you will have to write the script. So, my suggestion is to bite the bullet and do it.
As you said if there are a lot of files, then scripting it is best way, even then you may have to manually add the localized string values to each file.
What you refer to is common Localization problem. It is not just strings.xml and Android platform related.
As you might be guessing, people actually found ways to resolve it. Typically, you will send just the English file to translators (translation vendors) and they will update it using Translation Memory software.
Or if you are independent Software Developer, you may want to use some crowd-sourcing platform for your translations, like Launchpad, BabelZilla or Crowdin. These platforms also act as Translation Memory, so you won't have to manually synchronize individual language files.

Categories

Resources