Search code examples
androidbooleanandroid-resourcestranslatexliff

How do I get Android to translate booleans?


In Android Studio, I'm attempting to localize to Spanish, using xliff, a string that receives a boolean.

In English, my string resource looks like:

<string name="true_false_test">True/False?      <xliff:g example="true" id="true_false">%b</xliff:g></string>

In Spanish, like this:

<string name="true_false_test">Verdadero/Falso? <xliff:g id="true_false" example="true">%b</xliff:g></string>

When the app runs in English, this gives one of:

  • True/False? true
  • True/False? false

But in Spanish, the actual boolean doesn't seem to get translated:

  • Verdadero/Falso? true
  • Verdadero/Falso? false

How do I get Android to translate booleans?


Solution

  • I found no "simple" solution, but could get around this task like this. Tested within Android Studio and on 6.0.1 Android.

    First, in res/strings.xml: within 'resources' tag, specify your localized true / false values like this:

    <string name="TRUE">Ja</string>
    <string name="FALSE">Nein</string>
    

    Define your string with xliff tag use %s (NOT %b!) like this:

    <string name="does_mary_have_a_little_lamb">Does Mary have a little lamb? <xliff:g name="trueFalse" example="true">%s</xliff:g>
    

    **The below example is within mainActivity.java class. Your application may differ. Please mind the namespace. **

    In your java code create a function to convert boolean values to localized string representation:

    /**
     * function to convert boolean values to localized true / false strings
     * @param b boolean to be translated
     * @return String containing localized true / false message
     */
    private String translateBoolean(boolean b) {
        String trueFalse = Boolean.toString(b).toUpperCase(); // true / false is a reserved keyword, so convert to TRUE / FALSE
        String packageName = getPackageName();
        int resId = getResources().getIdentifier(trueFalse, "string", packageName);
    
        // this is to make sure that we got a valid resId else getString() will force close
        if (resId > 0) {
            return getString(resId);
        }
        else
        {
            return trueFalse; // provide a fallback 'true/false' if translation is not available
        }
    }
    

    Then use it in your string functions like this:

    String output = getString(R.string.does_mary_have_a_little_lamb,translateBoolean(hasLittleLamb)) + "\n";
    

    You could easily extend the above example to account for yes/no, up/down etc. translations. As this method is pretty expensive you could consider caching the results if you heavily use it.