Avoid raw resource duplicates, but still keep unique references - android

In an Android project I have several thousand highly dynamic audio files, in multiple languages. Highly dynamic as in they may change from week to week during development.
Some files are duplicates (within a language), and will have to be in order not to break the logic in the code and for maintanability - but it is a waste of space!
Example (just an example, don't worry about semantics):
raw/en/time_rep.mp3 - used as in "one more time"
raw/en/time.mp3 - used as in "it is now time for"
raw/de/time_rep.mp3 - may be translated to "mal"
raw/de/time.mp3 - may be translated to "zeit"
So, the word is same in English, and therefore a duplicate, but not in German, therefore, we need two resources.
Ideally in English both R.raw.time_rep and R.raw.time would refer to the same time.mp3 audio file, but not in German.
For strings and images it is possible to create an AliasResource, but not for raw files.
Any thoughts on how I can create "soft links" to avoid duplicate having raw resources, so that I can still reference R.raw.time_rep and R.raw.time from within the code, with little to no manual changes whenever I get a new batch of updated raw audio files?
NB: Don't worry about identifying the duplicates. I can do this in a batch script while converting and post processing the audio files.

Any thoughts on how I can create "soft links" to avoid duplicate having raw resources, so that I can still reference R.raw.time_rep and R.raw.time from within the code, with little to no manual changes whenever I get a new batch of updated raw audio files?
Just create lookup table (in any form you like: HashMap, database table etc) and then use it to pick right audio file instead of picking it directly like you do now.

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.

Using large text files in different languages in 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.)

Dynamic Android app languages

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.

Where to store sound files in the project and what solution to chose for storing references to them?

I'm making some fancy app which requires lot of short sounds for its use. Got few questions You might be able to answer.
Is there some restriction to the place I store then in the android project? Currently I put those in bin/res/sounds folder.
Is there a restriction to the format of files and is the .wav ok?
I'm gonna need something to store references to those sounds. I came up with a Dictionary which would consist of a sound name (key) and a path to the file so I could use in such method:
mp = MediaPlayer.create(Test.this, R.raw.mysound);
How should I store R.raw.mysound, it's not a string right?
I apologize If i'm not quite clear about everything, I'm trying my best.
Cheers
Usually, you'll store sounds in the raw folder under your res folder (res/raw/mySound.wav). This tells the OS not to mess with it and just copy it over for you. Then you can use the line of code that you posted to load them in.
As for the .wav format that will work fine but it will be really large.
Have a look at what audio formats Android supports:
http://developer.android.com/guide/appendix/media-formats.html
The reference (i.e. the R.raw.mySound) in an int. So you can just map some string to that int if you want but is that really easier than using the R.raw.mySound id?
They don't belong in /bin, because that is an automatically produced build directory. They do belong in /res/something, which may be what you mean.
R.raw.mysound is an int, as are all R.* references.
.wav files are fine, although big. Anything else and you will have to check both what was supported on your target platform, and whether all devices are likely to support it too. For instance, in the early days of Android, the platform specified several types but some were optional and up to the device as to whether they supported it. For a full list see: http://developer.android.com/guide/appendix/media-formats.html

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.

Categories

Resources