Seventeen languages that actually switch: how we localised Googly Player for Android

Disabled language splits, one process-wide locale call, right-to-left for Arabic and Urdu, and proper plural resources: the engineering behind the 17-language picker in our Android media player.

Binary Buddies · 5 min read · 0 views
Evening over a city of many languagesRooftops and lit windows under a dusk sky, a phone glowing on a balcony rail with music notes rising, and speech shapes in different scripts drifting overhead.

You add translations to an Android app, put a language picker in settings, and test it on your own phone, where it works. Then someone installs from Google Play, picks Hindi, and the app stays in English. Nothing crashes. Nothing shows up in the logs. The picker did its job; the strings it needed were simply never delivered to the device.

That is the quietest of several ways in-app language support breaks. The screen changes language but the playback notification does not. A count reads correctly in English and lands on the wrong side of its label in Arabic. A quantity that needs one of six grammatical forms gets the single form a format string can give it. Each of these looks fine in a demo and fails for exactly the people the translation was meant for.

We ran into all of them building Googly Player, our Android app for videos, music and photos. It ships with 17 languages, chosen from inside the app and independent of the system language. This is what it took to make that choice hold everywhere in the app, and what we would check first in any app that claims to be multilingual.

Key takeaways

  • With App Bundle language splits on, an in-app picker silently renders English; we disable them so all 17 translations ship in the base APK.
  • Applying the locale through AppCompatDelegate.setApplicationLocales reaches services, notifications and dialogs, not just activities.
  • On Android 13 and later the choice is handed to the platform and also appears in the system's per-app language setting.
  • Concatenated counts put the number on the wrong side in Arabic and Urdu; formatted strings let each translation place it.
  • Arabic needs six plural forms and Russian four, so quantities go through plural resources, not format strings.

The failure with no error: App Bundle language splits

Android App Bundles let Google Play split an app's resources by language and deliver only the ones that match the device. For an app that simply follows the system language, that saves space and costs nothing. For an app with its own language picker, it removes the very translations the picker is about to ask for. A phone set to English receives English resources; when the user then selects Bengali inside the app, Android looks for Bengali strings, finds none installed, and falls back to the default.

The result is the worst kind of bug: the picker renders everything in English, with no crash and nothing in the logs. A developer testing a locally built APK will never see it, because a local build carries every resource. Only the delivered app is missing them.

We disable language splits in Googly Player's App Bundle deliberately, so every translation ships in the base APK. Whatever a user picks, the strings are already on the device. It is a single build decision, and it is the difference between a picker that works and one that only appears to.

Language splits on versus disabledWith language splits on, the device receives only system-language resources and the picker shows English. With splits disabled, all 17 translations ship in the base APK and the picker shows the chosen language.Where the translations goLanguage splits onSplits disabledApp BundleSystem language onlyPicker shows EnglishNo crash, no logApp BundleAll 17 in base APKPicker shows choiceEvery translation on device
The left path is the silent failure; the right is the one build setting that prevents it.

A picker people can read before they have chosen

The language list is the one screen a user may have to navigate in a language they do not read. So each entry in Googly Player leads with its endonym, the language's own name in its own script, with the English name underneath. Someone looking for Japanese finds 日本語; someone looking for Gujarati finds ગુજરાતી, without needing to know how either is spelled in English.

The list is searchable, and a Suggested section is built from the device locale, so the most likely choice is usually the first thing on screen. The choice itself is entirely separate from the system language: a phone can run in English while Googly Player runs in Urdu, or the other way round. These are the 17 languages and how each appears:

LanguageListed in the picker as
EnglishEnglish
Hindiहिन्दी
SpanishEspañol
Arabicالعربية
FrenchFrançais
Bengaliবাংলা
PortuguesePortuguês
RussianРусский
Urduاردو
IndonesianBahasa Indonesia
GermanDeutsch
Japanese日本語
TurkishTürkçe
VietnameseTiếng Việt
Korean한국어
ItalianItaliano
Gujaratiગુજરાતી

One call that reaches services, notifications and dialogs

Changing the language activity by activity is the common shortcut, and in a media player it shows quickly. Playback carries on in a foreground service, the media notification is drawn outside any activity, and dialogs can appear over anything. If the locale only reaches activities, those surfaces keep speaking whatever language they started in, and the app ends up half translated in exactly the places a user glances at most.

Googly Player applies the choice process-wide through AppCompatDelegate.setApplicationLocales, so services, notifications and dialogs follow it along with every activity. There is one source of truth for the app's language, and every part of the process reads from it.

On Android 13 and later, the choice is handed to the platform rather than kept privately by the app. That means it also appears under Settings › Apps › Googly Player › Language, alongside every other app's per-app language. A user who manages languages from system settings finds Googly Player where they expect it, and a user who prefers the in-app picker never needs to leave the app.

How a language choice reaches the whole appThe in-app picker calls setApplicationLocales, which applies the language to activities, services, notifications and dialogs, and on Android 13 and later also registers it in system Settings.One locale for the whole appIn-app language pickersetApplicationLocalesSystem Settings, Android 13+ActivitiesServicesNotificationsDialogs
A single process-wide call fans out to every surface, and on newer Android it is mirrored in system Settings.
Morning rooftops strung with pennantsRooftops at sunrise with lines of coloured pennants swaying in the breeze, birds crossing and chimney smoke rising.

Right-to-left in Arabic and Urdu

Two of the 17 languages, Arabic and Urdu, read right to left, and Googly Player supports both fully. Mirroring the layout is the part everyone expects to do. The part that is easy to miss is the language picker itself, which is the one place where right-to-left names sit in the same list as left-to-right ones, often on a device whose system language is neither.

In the picker, العربية and اردو are anchored correctly, so the names sit where a reader of those scripts expects them rather than drifting to the wrong edge of the row. It is a small detail, and it appears on the screen where a reader of Arabic or Urdu decides whether the app was built with them in mind or translated as an afterthought.

Counts are formatted, never concatenated

Code like “Total Videos: ” + n is natural to write and wrong to ship. It hard-codes the number at the end of the label in every language. In Arabic and Urdu, that puts the number on the wrong side of the label, and no amount of translation can fix it, because the translator only ever sees the words, never the number's position.

Every count in Googly Player goes through a format string instead: “Total Videos: %d”. Each translation carries its own placeholder and puts it where its grammar needs the number. The code supplies the value; the translation decides where the value goes. It costs nothing extra to write this way from the start, and it is one of the first things we look for when we review another team's localisation.

Concatenated versus formatted countsA concatenated string fixes the number at the end of the translated label; a formatted string with a placeholder lets the translation position the number.Where the number landsConcatenated stringTranslated labelnNumber fixed at the endFormatted with %dnTranslated labelTranslation positions the number
Concatenation decides the number's position in code; a placeholder hands that decision to each translation.

Plurals: six forms in Arabic, four in Russian

A format string fixes position, not grammar. Arabic uses six grammatical forms for a number and Russian uses four, and a single string with a placeholder can express only one of them. The result is text that is technically translated and visibly wrong to every native reader who sees a count.

Googly Player uses proper plural resources for these strings. Each language supplies as many forms as its grammar has, and the right one is selected for each value at runtime. The code asks for a quantity string and a number; it never has to know how many forms a language needs, and adding a language never means touching the code that displays counts.

17languages in the in-app picker
2right-to-left languages, fully supported
6plural forms Arabic needs
4plural forms Russian needs
Grammatical forms needed for a numberA single format string gives one form; Russian needs four and Arabic needs six, which plural resources can supply.Forms needed for a numberFormat string1Russian4Arabic6Plural resources supply every form
The gap between one template and six grammatical forms is why quantities need plural resources.

What to check in any app that claims to be multilingual

None of this is specific to a media player. If you are building an Android app with an in-app language choice, or assessing one somebody has built for you, these are the checks we would run, roughly in order of how quietly each one fails:

  • Are language splits disabled in the App Bundle, so a language the device does not use is still installed?
  • Is the locale applied process-wide, so services, notifications and dialogs change along with the screens?
  • On Android 13 and later, does the choice show up in the system's per-app language setting?
  • Is every count a format string, with the placeholder inside the translation rather than glued on in code?
  • Do quantities use plural resources, so Arabic gets its six forms and Russian its four?
  • Does the picker list endonyms first and anchor right-to-left names correctly?

Each of these is cheap to get right at the start and tedious to retrofit across a finished app. The first one in particular cannot be found by testing a local build, which is why it so often reaches users before anyone notices.

Getting Googly Player into your language

Googly Player is an Android app for videos, music and photos. All 17 languages are available from the in-app picker, independent of the system language, and on Android 13 and later the same choice lives in system settings too. Media access uses granular permissions on Android 13+ (READ_MEDIA_AUDIO, READ_MEDIA_IMAGES and READ_MEDIA_VIDEO) and READ_EXTERNAL_STORAGE on earlier versions, and every prompt says in plain language that nothing is uploaded and everything stays on the device.

  1. Pick your language in the app

    Open the language picker, then search or choose from the Suggested section, which is based on your device locale. Each language is listed in its own script, with the English name underneath.

  2. Or set it from Android

    On Android 13 and later, go to Settings › Apps › Googly Player › Language. It is the same setting the in-app picker uses.

  3. Allow access to your media

    Grant access to videos, music and photos. On Android 14, if you share only some items, the grant persists between launches and the app tells you “You've shared only some items”, with an option to allow all.

Questions

Does Googly Player follow my phone's system language?

Not necessarily. The language is chosen inside the app and is independent of the system language. The picker's Suggested section uses your device locale to put the likely choice first.

Can I change Googly Player's language from Android settings?

On Android 13 and later, yes. The choice is handed to the platform, so it appears under Settings › Apps › Googly Player › Language.

Which languages read right to left?

Arabic and Urdu. Both have full right-to-left support, including correctly anchored names in the language picker.

Why ship every translation in the base APK?

With App Bundle language splits, Play delivers only the system-language resources, so choosing a different language in the app would show English with no error. Disabling splits keeps all 17 translations on the device.

  • #Android localization
  • #Android plural resources
  • #Googly Player
  • #RTL Arabic Urdu
  • #binary buddies
  • #in-app language picker

Comments

Add a comment
Sign in with Google to join the conversation