Googly Player's 17-language picker, and the Android pitfalls we engineered around
An independent language choice only works if it reaches services, notifications and dialogs, and survives Google Play's delivery. Here is what that took.
Plenty of Android apps offer a language setting and get exactly one screen right. Switch to Hindi or Turkish and the activity in front of you redraws; then the playback notification arrives in English, a dialog opens in the system language, and in Arabic the count in a header sits on the wrong side of its label.
The worse failures make no noise at all. An in-app picker can ship through Google Play and render every language in English for the people who installed it, with no crash and nothing in the logs. Plural strings that read correctly in English come out grammatically broken in Russian. Nobody files a bug about any of this. People simply conclude the app was not made for them.
Googly Player is our Android app for videos, music and photos, and it has a full in-app language picker covering 17 languages. This is how we built it so the chosen language reaches every part of the app, including the services, notifications and dialogs that a screen-level switch leaves behind.
Key takeaways
- The language choice is independent of the system language and is applied process-wide through
AppCompatDelegate.setApplicationLocales, so services, notifications and dialogs follow it. - Language splits are disabled in the App Bundle. With them on, Play delivers only system-language resources and the picker silently falls back to English.
- Arabic and Urdu get full right-to-left support, and counts use format strings rather than concatenation so numbers land on the correct side.
- Plurals come from plural resources, because Arabic needs six grammatical forms for a number and Russian four.
- On Android 13 and later the choice is handed to the platform and also appears in the system's per-app language setting.
Seventeen languages, chosen inside the app
The picker offers English, Hindi, Spanish, Arabic, French, Bengali, Portuguese, Russian, Urdu, Indonesian, German, Japanese, Turkish, Vietnamese, Korean, Italian and Gujarati. The choice is entirely independent of the language the phone itself runs in: someone can keep their device in English and use Googly Player in Bengali, or keep the device in Spanish and read the app in Portuguese.
That independence is the reason to have a picker at all, since an app that only followed the system locale would have nothing to offer. It also raises the bar. Once a person has made an explicit choice, every string the app shows anywhere has to honour it, and anything still appearing in the system language is not a cosmetic slip. It is the feature failing.
Every language listed under its own name
Each entry in the picker leads with the language's endonym, its name in its own script: हिन्दी, العربية, বাংলা, 日本語, ગુજરાતી. The English name sits underneath as a secondary label. A person looking for their language finds it written the way they write it, and anyone helping them set up the phone can still read the list.
The list is searchable, and a Suggested section is drawn from the device locale, so the most likely choice is usually the first thing on screen rather than somewhere down a list of seventeen. For Arabic and Urdu the language names are anchored correctly for right-to-left text inside the picker itself, which matters because the picker is the first screen where a broken RTL layout would show, and it is shown to exactly the people who would notice.
One call that reaches the whole process
The selected language is applied through AppCompatDelegate.setApplicationLocales, which sets it for the application process rather than for one activity at a time. In a media app that distinction is everything, because much of what a person sees never comes from an activity: playback runs in a foreground service, the media notification is built outside any screen, and dialogs open over whatever happens to be current.
Applied process-wide, the language covers services, notifications and dialogs as well as activities. Someone who picks Vietnamese gets Vietnamese in the player, in the notification controlling playback, and in the dialog that asks them to confirm something, without each component having to look up and re-apply the choice on its own. One decision, made once, reaches every surface the app draws.
Handed to Android on 13 and later
On Android 13 and later we hand the choice to the platform. The language picked inside Googly Player then also appears under Settings › Apps › Googly Player › Language, which is the system's own per-app language setting, sitting alongside the same setting for every other app on the device.
That gives people two ways in to one setting. Someone who never opens our picker can set the language from system settings, and someone who manages their apps from there finds Googly Player behaving like an app that knows the platform it runs on rather than one hiding a private option in its own menus. Because the choice is handed to the platform rather than kept beside it, both places show the same answer.
The App Bundle setting that empties a picker without a sound
Android App Bundles let Google Play split an app into pieces and deliver only what a given device needs. For language resources, that means Play delivers the strings for the device's system language and leaves the others out. For an app that only ever follows the system language, that is a reasonable saving. For an app with an independent language picker it is fatal, and it fails quietly.
With language splits on, a person on an English-language phone who chooses Japanese has no Japanese resources installed at all. The picker would silently render everything in English: no crash, nothing in the logs, nothing for crash reporting to catch. Because nothing fails, nothing reports it, and the first sign of the problem is a user who gives up.
We deliberately disable language splits in the bundle, so every translation ships in the base APK. Every language in the picker is present on every device that installs Googly Player, whatever the phone itself is set to.
Right-to-left, end to end
Arabic and Urdu read right to left, and Googly Player has full RTL support for both. Mirroring the layout is the visible part of that work, and the part most teams remember. The details that give a half-finished RTL implementation away are smaller: a language name pinned to the wrong edge of its row, or a number stranded at the far end of a label it is supposed to introduce.
We handle the first of those inside the picker, where the names are anchored correctly for right-to-left text, so an Arabic or Urdu speaker's first impression of the app is not a misaligned list. The second, where numbers land, is not a layout problem at all. It comes down to how each string is assembled in code, which is why we treat it as a rule for every count in the app rather than a fix applied screen by screen.
Counts are formatted, and plurals are real plurals
Wherever the app shows a count, the string is a format with a placeholder, such as Total Videos: %d, and never a label with a number glued on in code. Concatenation fixes the number to the end of the string in code order, and in Arabic and Urdu that puts it on the wrong side of the label. A format string lets each translation decide where the number belongs.
Plurals use Android's plural resources rather than a single format string. Arabic has six grammatical forms for a number and Russian has four, and one string with a placeholder cannot express either of them. With plural resources each language supplies every form it needs, and the correct one is selected for the count being shown, so a library of one video, a few videos or many videos reads naturally in each language.
What it runs on, and what to take from it
The language work in Googly Player rests on a short list of concrete pieces:
- An Android app using AppCompat, with the language applied through
AppCompatDelegate.setApplicationLocalesso it is process-wide. - Android 13 or later for the choice to appear under Settings › Apps › Googly Player › Language.
- An App Bundle with language splits disabled, so all 17 translations ship in the base APK.
- String resources that use format placeholders for every count and plural resources for every quantity.
- RTL layouts for Arabic and Urdu, including the picker's own list of names.
For a team weighing whether to work with us, this is the standard we hold localisation to: the choice a person makes is honoured on every surface, including the ones without a screen, and it survives the trip through Play. If you already have a picker of your own, the two checks with the highest payoff are whether language splits are on in your bundle and whether any string in your code appends a number to a label. Both fail silently, and both are quick to find once you know to look.
Questions
Does Googly Player's language have to match the phone's language?
No. The in-app picker is entirely independent of the system language, so the phone can run in one language and Googly Player in another.
Where can I change the app language on Android 13 or later?
Either in the app's own picker or under Settings › Apps › Googly Player › Language. The choice is handed to the platform, so both show the same setting.
Do notifications and dialogs follow the chosen language?
Yes. The language is applied process-wide, so it covers services, notifications and dialogs as well as the app's screens.
Which languages read right to left?
Arabic and Urdu. Both have full RTL support, including correctly anchored language names in the picker and counts formatted so the number sits on the correct side of its label.
Why would an in-app language picker show only English after installing from Google Play?
Usually because App Bundle language splits are enabled, so Play delivers only the device's system-language resources. We disable language splits so every translation ships in the base APK.
- #Android localization
- #Googly Player
- #RTL support
- #in-app language picker
- #per-app language
- #setApplicationLocales



Comments