Seventeen languages in Googly Player, and the Android traps we built around

A language picker that quietly shows English is worse than no picker at all. Here is how we built one for Googly Player that holds up across scripts, plurals, notifications and Play delivery.

Binary Buddies · 5 min read · 0 views
An evening rooftop above a cityA rooftop at dusk with string lights, a hanging lantern, a potted plant and a phone glowing on a small table beside headphones, with lit windows across the city and stars over a rising moon.

Adding translated strings to an Android app takes an afternoon. Getting them to show up for every user, on every screen, with the words in the right order, is a different job, and most of the ways it goes wrong are silent. A user picks Hindi from a language menu and the app keeps talking to them in English. Nothing crashes, nothing appears in the logs, and the eventual bug report says only that the language setting does not work.

The other failures are quieter still. A count glued onto the end of a label lands on the wrong side of the line in Arabic. A plural written with English in mind reads as broken grammar in Russian. A notification arrives in the system language while the screen behind it is in Urdu, because the language was switched for the screens and nowhere else.

Googly Player, our Android app for the videos, music and photos already on your phone, runs in 17 languages chosen from its own in-app picker. This is how we built that so the choice a person makes actually holds: useful if you are localising an Android app of your own, or deciding whether to have us do it.

Key takeaways

  • The app language is chosen inside Googly Player and is independent of the phone's system language; on Android 13 and later the same choice also appears in system settings.
  • Every translation ships in the base APK. We disabled App Bundle language splits, because with them on, Play delivers only the system language and the picker silently falls back to English.
  • The locale is applied process-wide through AppCompatDelegate.setApplicationLocales, so services, notifications and dialogs follow it, not just activities.
  • Counts use format strings and plurals use plural resources, because Arabic needs six grammatical forms for a number and Russian needs four.

Seventeen languages, chosen inside the app

Googly Player offers a full in-app language picker that is entirely independent of the system language. Someone whose phone is set to English can run the app in Bengali; someone sharing a family phone set to Turkish can run it in German. The languages are:

  • English
  • Hindi (हिन्दी)
  • Spanish (Español)
  • Arabic (العربية)
  • French (Français)
  • Bengali (বাংলা)
  • Portuguese (Português)
  • Russian (Русский)
  • Urdu (اردو)
  • Indonesian (Bahasa Indonesia)
  • German (Deutsch)
  • Japanese (日本語)
  • Turkish (Türkçe)
  • Vietnamese (Tiếng Việt)
  • Korean (한국어)
  • Italian (Italiano)
  • Gujarati (ગુજરાતી)

That list spans Latin, Arabic, Devanagari, Bengali, Gujarati, Cyrillic, Japanese and Korean scripts, two right-to-left languages, and languages with very different rules for how numbers combine with nouns. Each of those differences breaks a common Android shortcut somewhere, which is why the sections below are mostly about the places translations usually fail rather than the translations themselves.

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

A picker people can read in their own script

A language picker has one job that most get wrong: it has to be usable by the person who cannot read the language the app is currently in. If the list says "Bengali" in English, a Bengali reader stuck in an English interface has to recognise a foreign word for their own language. So every entry in our picker leads with its endonym, the language's own name in its own script, as the primary label, with the English name underneath for everyone else.

The list is searchable, and above the full list sits a "Suggested" section built from the device locale, so the most likely choice is usually the first thing on screen. Seventeen entries is short enough to scroll, but search and a sensible first suggestion mean nobody has to hunt through scripts they do not read to find their own.

How the language picker is arrangedA search field filters the full list, a Suggested section is picked from the device locale, and each language row shows its endonym as the main label with the English name below it.Inside the language pickerSearch languagesFilters the full listSuggestedPicked from device localeEndonym, own scriptEnglish name belowPrimary labelSecondary label
Each row leads with the name a speaker of that language would recognise, and the Suggested section puts the device locale's language first.

Right to left for Arabic and Urdu

Arabic and Urdu read right to left, and Googly Player supports that fully rather than translating the words and leaving the layout pointing the wrong way. When either language is chosen, the interface mirrors so that reading order, alignment and the flow of each screen match the direction of the text.

The picker itself is a small test of this. It mixes left-to-right and right-to-left names in a single list, and a name in Arabic script anchored to the wrong edge looks misplaced even to someone who cannot read it. We anchor each language name correctly for its own script, so العربية and اردو sit where a reader of those languages expects them, alongside English, Japanese and Gujarati entries that sit where theirs expect.

A market street of hanging signsA morning market street with striped awnings and wordless signboards of many shapes swaying beneath a line of bunting.

One language for the whole app, not just its screens

The common way to switch an Android app's language is to override the locale for each activity. It works for the screens and misses everything else. A media player has a lot of everything else: Googly Player keeps music playing in the background through a foreground service, posts a media notification, and asks its questions in bottom-sheet dialogs. Override only the activities and those pieces keep speaking the system language.

We apply the chosen language process-wide through AppCompatDelegate.setApplicationLocales. That covers services, notifications and dialogs along with activities, so a user who chooses Korean gets Korean in the playback notification on the lock screen as well as in the library they are browsing.

One language choice applied across the appThe in-app picker and, on Android 13 and later, the system settings page hold the same choice, which goes through AppCompatDelegate.setApplicationLocales to activities, services, notifications and dialogs.In-app language pickerAndroid 13+ system settingsAppCompatDelegate.setApplicationLocalesActivitiesServicesNotificationsDialogs
Both entry points set the same application locale, and that one setting reaches every part of the app that shows text.

Handing the choice to Android 13 and later

Android 13 introduced per-app language settings at the system level, and on those devices we hand the choice to the platform rather than keeping it to ourselves. The language picked inside Googly Player also appears under Settings › Apps › Googly Player › Language, and the two stay in step because they are the same setting, not two copies of it that can drift apart.

This matters for support as much as for users. Someone who has set the app to a language they cannot read, or who borrowed a phone that someone else configured, has a way back that does not depend on navigating the app's own menus in an unfamiliar script. And on devices older than Android 13, the in-app picker still does the whole job on its own.

The App Bundle setting that silently breaks a picker

This is the failure we opened with, and it is the one most likely to catch a team that has done everything else right. When an app is published as an App Bundle, Google Play by default splits language resources out and delivers only those matching the device's system language. For most apps that is a sensible saving. For an app with its own language picker, it means the translations the user is choosing between were never installed.

The result is not an error. The picker lists Hindi, the user taps it, and the app renders English, because English is what is on the device. No crash, nothing in the logs. We disabled language splits in the App Bundle deliberately, so every translation ships in the base APK and every entry in the picker has its resources present.

Language splits on versus offWith language splits enabled, Play installs the base APK plus only the system-language split and the picker shows English with no crash and nothing logged. With splits disabled, the base APK holds all 17 languages, the chosen language loads and the picker renders it.Language splits enabledBase APKPlus system-language splitPicker shows EnglishNo crash, nothing loggedLanguage splits disabledBase APK, all 17Chosen language loadsPicker renders it
The top row is the default App Bundle behaviour and its silent English fallback; the bottom row is how Googly Player is built.

Numbers and plurals that read correctly

Counts appear all over a media library: how many videos, how many tracks, how many photos, and the sectioned results of the app's global search, which scans videos, music and photos in one pass and labels each group with its count. The quick way to build those labels is to concatenate a string and a number. We never do. Every count goes through a format string, so a translator decides where the number sits.

Concatenated

"Total Videos: " + n

  • The number is always appended after the label
  • In Arabic and Urdu that puts it on the wrong side

Formatted

"Total Videos: %d"

  • The number's position is part of the translated string
  • Each language places it where it belongs

Plurals are a separate problem that a format string cannot solve. English gets by with a singular and a plural, but Arabic needs six grammatical forms for a number and Russian needs four, and which form applies depends on the number itself. We use Android's plural resources for these, so each language supplies every form it needs and the right one is picked at run time.

Plural forms in Arabic and RussianArabic needs six grammatical forms for a number and Russian needs four, shown as six and four separate cells.Grammatical forms for a numberArabic6 formsRussian4 forms
Each cell is a distinct form a translator must supply, which is why counts go through plural resources rather than a single format string.

What it runs on and what it asks for

Googly Player is an Android app for the media already on the device: local videos, music and photos. It ships as an Android App Bundle through Google Play, with language splits disabled as described above, so whichever language a person picks is already installed. The in-app picker works independently of the system language; on Android 13 and later the same choice is also available in system settings. Material Design 3 runs throughout, with dynamic colour from the wallpaper on Android 12 and later and correct edge-to-edge insets on Android 15 and later.

Permissions are granular on Android 13 and later: READ_MEDIA_AUDIO, READ_MEDIA_IMAGES and READ_MEDIA_VIDEO, plus READ_MEDIA_VISUAL_USER_SELECTED for partial access on Android 14 and later, which keeps a partial grant from being revoked when the app goes to the background. Older devices use READ_EXTERNAL_STORAGE, capped at API 32. Background playback uses FOREGROUND_SERVICE, FOREGROUND_SERVICE_MEDIA_PLAYBACK and WAKE_LOCK, the media notification needs POST_NOTIFICATIONS on Android 13 and later, and MODIFY_AUDIO_SETTINGS lets the equalizer and booster work. Every prompt is in plain language and says that nothing is uploaded and everything stays on the device.

Questions

Does the app language have to match my phone's language?

No. The in-app picker is entirely independent of the system language, and it lists a Suggested choice based on the device locale to make the common case quick.

Where else can I change Googly Player's language?

On Android 13 and later, the same setting appears under Settings › Apps › Googly Player › Language. Changing it in either place changes the one setting.

Do notifications and dialogs follow the language I choose?

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

Is Arabic and Urdu laid out right to left?

Yes. Both have full right-to-left support, including correctly anchored language names inside the picker.

Why are all the translations installed, not just mine?

We disabled App Bundle language splits on purpose. With splits on, Play would install only the system language, and choosing any other language in the picker would silently show English.

  • #Android localisation
  • #Android media player
  • #Android plural resources
  • #Googly Player
  • #in-app language picker
  • #right-to-left support

Comments

Add a comment
Sign in with Google to join the conversation