How Googly Player switches between 17 languages without silently falling back to English

Translated strings are the easy part. Getting them onto the device, into every notification and dialog, and onto the correct side of a number is where in-app language pickers quietly fail.

Binary Buddies · 5 min read · 0 views
An evening city and a glowing phoneA city at dusk with lit windows. On a table in the foreground a phone glows, and ribbons of handwriting-like strokes flow out of it in both directions, some leftward and some rightward.

Your Android app has a language picker. A user whose phone is set to English would rather read your app in Hindi, so they pick Hindi, and the app stays in English. Nothing crashes. Nothing appears in the logs. Or the screens switch correctly but the playback notification and the confirmation dialogs carry on in the system language. Or a count that reads fine in English sits on the wrong side of its label in Arabic.

None of these are translation problems. The strings can be translated perfectly and still never reach the device, reach only part of the app, or be stitched together in an order the language does not use. They are engineering problems: how the app is packaged, how the chosen locale is applied, and how strings with numbers in them are built.

Googly Player is our Android app for videos, music and photos, and it runs in 17 languages chosen from its own in-app picker, independent of the system language. This is how we built that language support, the specific failures we closed off, and what it needs to run.

Key takeaways

  • The language choice is applied process-wide through AppCompatDelegate.setApplicationLocales, so services, notifications and dialogs follow it, not just activities.
  • Language splits are disabled in the App Bundle; with them on, Play ships only system-language resources and the picker silently renders English.
  • Counts are formatted rather than concatenated, so numbers sit on the correct side of their labels in Arabic and Urdu.
  • Plural resources carry Arabic's six grammatical forms and Russian's four, which a single format string cannot.
  • On Android 13 and later the choice is handed to the platform and also appears in system Settings.

Seventeen languages, chosen inside the app

The picker offers these languages, each shown by its own name in its own script, with the English name alongside. The choice is entirely separate from the system language, so a phone can stay in one language while Googly Player runs in another.

Shown asLanguage
EnglishEnglish
हिन्दीHindi
EspañolSpanish
العربيةArabic
FrançaisFrench
বাংলাBengali
PortuguêsPortuguese
РусскийRussian
اردوUrdu
Bahasa IndonesiaIndonesian
DeutschGerman
日本語Japanese
TürkçeTurkish
Tiếng ViệtVietnamese
한국어Korean
ItalianoItalian
ગુજરાતીGujarati

That independence matters to real people in an ordinary way. Shared phones, work phones set up in English, and households that read one script more comfortably than another all produce someone who wants the app in a language their system is not set to. A picker that only works when it agrees with the system language is not doing a job.

A picker that reads in your own script

Each language is listed by its endonym, the name a language uses for itself, as the primary label, with the English name underneath. Someone looking for Bengali scans for বাংলা, the word they recognise at a glance, rather than hunting for an English word they may not expect to need. The English line underneath helps anyone choosing on someone else's behalf.

The list is searchable, and it opens with a Suggested section built from the device locale, so the most likely choices are at the top before anyone types. For Arabic and Urdu the picker has full right-to-left support, down to the language names themselves being correctly anchored in the list rather than pushed against the wrong edge, which is the first thing an Arabic or Urdu reader would notice.

17languages in the in-app picker
2right-to-left languages: Arabic and Urdu
6plural forms Arabic needs
4plural forms Russian needs

One choice, applied everywhere the app speaks

A media player does not only talk through its screens. Background playback runs in a service, the media notification is drawn outside any activity, and confirmations arrive as dialogs. If the locale is set per activity, those other surfaces fall back to the system language and the app ends up speaking two languages at once.

We apply the choice process-wide through AppCompatDelegate.setApplicationLocales. Because the locale belongs to the whole process, services, notifications and dialogs pick it up along with every activity. A user who chose Turkish gets Turkish in the player, in the notification that controls it, and in any prompt that appears along the way.

How a language choice spreads through the appThe in-app language picker calls setApplicationLocales, which applies the language to activities, services, notifications and dialogs. On Android 13 and later the choice is also handed to system Settings.In-app language pickersetApplicationLocalesAndroid 13+ system SettingsActivitiesServicesNotificationsDialogs
A single call sets the language for the whole process, so every surface below it follows, and newer Android versions also record it in system Settings.

Handing the choice to Android on 13 and later

From Android 13, the platform has its own notion of a per-app language, and we hand Googly Player's choice to it. The practical effect is that the language a user picked inside the app also shows up under Settings › Apps › Googly Player › Language, and can be read or changed from there.

This keeps the two places in agreement. A user who changes the language from system Settings sees the app follow, and a user who changed it inside the app finds the same answer when they look in Settings. On those versions there is one setting with two doors, rather than two settings that can disagree.

Ribbons of script crossing a dusk landscapeRolling hills at dusk under a low sun, with two ribbons of handwriting-like strokes drifting across the sky in opposite directions and small lights scattered on the hills.

The App Bundle setting that silently breaks every translation

This is the failure from the opening paragraph, and it is the hardest one to see. When an app is published as an App Bundle, Play can split resources by language and deliver only the ones matching the device's system language. For most apps that is a saving. For an app with an in-app picker it is a trap: the user picks Hindi, the Hindi strings were never installed, and Android falls back to the defaults.

The result is a picker that silently renders everything in English. There is no crash and nothing in the logs, so it does not show up in crash reporting or in testing on a device whose system language already matches. We deliberately disable language splits in the App Bundle so every translation ships in the base APK, and every language in the picker is actually on the device when it is chosen.

Language splits on versus offWith language splits on, Play delivers only the system language, the picker shows English only, and nothing crashes or logs. With splits off, every translation is in the base APK and the picker shows the chosen language.Language splits onPlay delivers system languagePicker shows English onlyNo crash, nothing loggedLanguage splits offEvery translation in base APKPicker shows chosen language
The left path fails without any signal, which is why it survives testing; the right path is the one Googly Player ships.

Numbers belong where the language puts them

The quickest way to put a count on screen is to glue it to a label: "Total Videos: " plus the number. In English that reads correctly. In Arabic and Urdu, which run right to left, concatenation puts the number on the wrong side of the label, and the sentence reads backwards to the person it was translated for.

So in Googly Player counts are formatted, never concatenated. The string is written as "Total Videos: %d", one resource with a placeholder, and each translation carries the whole phrase with the placeholder wherever that language puts it. The code supplies the number; the translation decides where it goes.

Concatenated versus formatted counts in right-to-left textTwo panels. In the concatenated panel, the number lands on the right of the label in right-to-left text, the wrong side. In the formatted panel, using Total Videos %d, the number lands on the left, the correct side.ConcatenatedFormatted stringlabel + nTotal Videos: %dReading directionReading directionlabelnnlabelWrong side in RTLCorrect side in RTL
Read each row from the right: only the formatted string lets the translation put the number where Arabic and Urdu expect it.

Plurals that a format string cannot express

A placeholder fixes position but not grammar. English gets by with a singular and a plural, which tempts teams into a single format string and an "(s)". Other languages change the noun depending on the number in ways one string cannot carry: Arabic needs six grammatical forms for a number, and Russian needs four.

Googly Player uses proper plural resources for these. Each language supplies as many forms as its grammar has, and Android selects the right one for the count at runtime. A Russian reader sees the form Russian uses for that particular number, and an Arabic reader sees one of six, not a single phrase bent to fit every quantity.

Plural forms per languageArabic needs six plural forms and Russian needs four, while a single format string offers only one.Plural forms per languageArabic6Russian4Format string1
Each block is one grammatical form a count can take; a single format string has room for only one of them.

What it takes to run, and how to switch

Googly Player is an Android app, and the language picker is part of it on every device it runs on, independent of whatever language the system uses. The one version-dependent piece is system integration: on Android 13 and later the choice is handed to the platform and appears in Settings, as described above. Arabic and Urdu run right to left throughout, including in the picker. No separate download is needed per language, because every translation ships in the base APK.

  1. Open the language picker

    It lives inside the app, so it works the same whatever the phone's own language is.

  2. Find your language

    Check the Suggested section first, which is based on the device locale, or search the list. Languages appear in their own script with the English name underneath.

  3. Pick it once

    The choice applies across the whole app, including background playback, the media notification and dialogs.

  4. Change it from Settings, if you prefer

    On Android 13 and later the same choice is available under Settings › Apps › Googly Player › Language.

For teams weighing us for their own Android work, this is the kind of detail we treat as part of shipping a feature rather than polish after it: the packaging flag that decides whether translations exist on the device, the API that decides how far a locale reaches, and the string rules that decide whether a translated sentence reads correctly.

Questions

Does Googly Player's language have to match my phone's system language?

No. The in-app picker is entirely independent of the system language, so the phone can stay in one language while the app runs in any of its 17.

Will notifications and dialogs also change language?

Yes. The choice is applied process-wide through AppCompatDelegate.setApplicationLocales, which covers services, notifications and dialogs as well as the app's screens.

Why would an in-app language picker show only English?

Usually because the App Bundle uses language splits, so Play installs only the system-language resources. Nothing crashes and nothing is logged. We disable language splits so every translation ships in the base APK.

Are Arabic and Urdu fully right-to-left?

Yes, including the language names in the picker, and counts are formatted rather than concatenated so numbers sit on the correct side of their labels.

Can I change the app language from Android's Settings?

On Android 13 and later, yes: under Settings › Apps › Googly Player › Language, which stays in step with the choice made inside the app.

  • #Android localization
  • #Arabic and Urdu
  • #Googly Player
  • #RTL support
  • #in-app language picker
  • #setApplicationLocales

Comments

Add a comment
Sign in with Google to join the conversation