Seventeen languages that actually ship: how Googly Player makes an in-app language choice stick

Choosing Hindi and still seeing English is a build problem, not a translation problem. Here is how we made the language choice in Googly Player hold everywhere the app shows text.

Binary Buddies · 5 min read · 1 view
A rooftop above a city at duskA city at dusk seen from a rooftop, windows lit across many buildings, lanterns strung overhead and music drifting up from a small speaker on the ledge.

Shipping an Android app in more than one language is mostly not a translation problem. The strings are the easy part. The hard part is everything that sits around them: the media notification that stays in English after the user switched to Hindi, the item count that reads backwards in Arabic, the plural that is only correct in English, and the release build that passes every test on your desk and still shows English to the person who chose Bengali, because the store never delivered the Bengali strings to their phone.

Almost all of these fail quietly. Nothing crashes and nothing appears in the logs. The user simply sees an app that half-speaks their language and concludes that nobody tried.

Googly Player, our Android app for videos, music and photos, has a full in-app language picker with seventeen languages. This is how we built it so that choosing a language changes the language everywhere the app shows text, and keeps working once the app has gone through the Play Store.

Key takeaways

  • The language in Googly Player is chosen inside the app, independently of the system language, and applied process-wide so services, notifications and dialogs follow it too.
  • On Android 13 and later the choice is handed to the platform, so it also shows up under Settings › Apps › Googly Player › Language.
  • Language splits are disabled in the App Bundle; with them on, Play ships only the system-language resources and the picker silently renders English.
  • Arabic and Urdu get full right-to-left support, counts are format strings rather than concatenation, and plurals use proper plural resources.

Seventeen languages, chosen inside the app

The picker is entirely independent of the system language. Someone can keep their phone in one language and run Googly Player in another, and the app does not need the system setting to agree with them. That matters for a media app in particular, because it is often the app people spend the most time in, and the language they want for browsing their own videos and music is not always the one their phone was set up in.

These are the languages the picker offers, each shown here by its own name:

  • 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 covers several scripts and two right-to-left languages, which is exactly why the details further down are not optional.

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 language

Each language is listed by its endonym, its own name in its own script, as the primary label, with the English name underneath. Someone looking for Gujarati recognises ગુજરાતી before they would find the word Gujarati in a Latin-alphabet list, and they may not read English at all. The English name underneath helps the other case: someone setting the app up for a relative, or a tester checking that each entry is where it should be.

The list is searchable, and it opens with a Suggested section based on the device locale, so most people find their language at the top without scrolling. For Arabic and Urdu, the language names in the picker are correctly anchored for right-to-left text, so the picker itself does not look broken in the two languages most likely to break it.

How the language picker is organisedThe device locale feeds a Suggested section and a search field filters the full list of 17 languages; every entry shows the endonym in its own script with the English name underneath.Two ways to find a languageDevice localeSearch fieldSuggested sectionFull list of 17Endonym, in its own scriptEnglish name underneath
Whether a language is found through the Suggested section or by search, every entry leads with its own name in its own script.

One setting for the whole process

A common shortcut is to change the locale for the activity on screen. That works until the app shows text from somewhere that is not an activity. Googly Player applies the chosen language process-wide through AppCompatDelegate.setApplicationLocales, so it covers services, notifications and dialogs as well as activities.

For a media player this is the difference between working and not. Background playback on modern Android runs in a foreground service with a media notification; the app declares FOREGROUND_SERVICE, FOREGROUND_SERVICE_MEDIA_PLAYBACK and WAKE_LOCK for exactly that, and POST_NOTIFICATIONS for the media notification on Android 13 and later. With an activity-only approach, the screen would be in Urdu and the notification controlling the music would still be in whatever language the system uses. Applying the locale to the process means the user sees one language whether they are looking at the app, a dialog, or the notification shade.

Where the chosen language reachessetApplicationLocales applies the language to activities, services, notifications and dialogs, and on Android 13 and later hands the choice to the system per-app language setting.Where the chosen language reachessetApplicationLocalesActivitiesServicesNotificationsDialogsOn Android 13 and laterSettings › Apps › Googly Player › Language
One call sets the language for every part of the app that shows text, and on newer Android the system setting reflects the same choice.

Handed to Android on 13 and later

Android 13 introduced a per-app language setting in the system, and on Android 13 and later Googly Player hands its choice to the platform. The language picked inside the app therefore also appears under Settings › Apps › Googly Player › Language, and the two places show the same choice rather than competing with each other.

This is a small thing that prevents a confusing one. A user who changes the language from system settings, or who goes looking there because that is where they expect it, finds the app behaving the way the platform says it should. An app that keeps its own private language setting and ignores the platform one leaves people with two switches that disagree.

Towns along a road at nightRolling hills at night with small towns lit along a winding road under a moon.

The build setting that decides whether any of this works

Everything above can be implemented correctly and still fail in production. Android App Bundles split resources by language by default, and Play then delivers only the resources matching the device's system language. The translations for every other language never reach the phone.

The result is one of the nastier bugs in Android localisation. The user opens the picker, chooses Hindi on a phone set to English, and the app renders everything in English. There is no crash and nothing in the logs. On a developer's machine, where the app is installed with every resource, it works perfectly, so the bug only exists for real users.

We disable language splits in Googly Player's App Bundle deliberately, so every translation ships in the base APK. Whatever language the system is set to, all seventeen are on the device when the user opens the picker.

Language splits on versus disabledWith splits on, Play ships only the system language and the picker renders English with no crash and nothing logged; with splits disabled, every translation is in the base APK and the chosen language renders.Language splits onSplits disabledPlay ships system language onlyUser picks another languagePicker renders EnglishNo crash, nothing loggedEvery translation in base APKUser picks another languageChosen language renders
The two builds behave identically until a user picks a language other than the system one; only the left one then fails, and it fails silently.

Right-to-left, including the numbers

Arabic and Urdu get full right-to-left support in Googly Player, down to the language names in the picker being anchored correctly. The less obvious part is how numbers meet text.

Every count in the app is a formatted string, never a concatenation. The code uses a resource like “Total Videos: %d” rather than gluing “Total Videos: ” to a number at runtime. Concatenation fixes the order of label and number in the code, which puts the number on the wrong side of the label in Arabic and Urdu. A format string lets each translation place the number where its own grammar and direction put it.

Counts appear all over a media app. Global Search, for example, scans videos, music and photos in a single pass and shows sectioned results with a count on each heading, such as “Videos · 12”, “Music · 4” and “Photos · 87”. Each of those has to read correctly in every one of the seventeen languages.

Concatenated versus formatted countsA label concatenated with a number puts the number on the wrong side in Arabic and Urdu; a format string such as Total Videos %d is correct in both.Building a count labelLabel + number, concatenatedArabic, Urdu: number misplacedWord order fixed in codeTotal Videos: %dCorrect in Arabic and UrduTranslation decides position
The difference is invisible in English and only shows up once the text runs right to left.

Plurals a format string cannot express

Formatting the number is only half of a count. The word next to it changes with the number too, and English trains developers to think there are two cases: one, and everything else. Arabic needs six grammatical forms for a number and Russian needs four. A single format string, or an if statement that checks for one, cannot express that.

Googly Player uses proper Android plural resources for these strings, so each language supplies as many forms as its grammar has and the platform chooses the right one for the number being shown. It is the same principle as the format strings: the code says what it means, a count of videos, and leaves the language-specific shape of that phrase to the translation, where it belongs.

What it runs on and how to set the language

Googly Player is an Android app built with Material Design 3 throughout. It picks up the wallpaper palette through Material You dynamic colour on Android 12 and later, handles edge-to-edge insets correctly on Android 15 and later, and uses granular media permissions on Android 13 and later: READ_MEDIA_AUDIO, READ_MEDIA_IMAGES and READ_MEDIA_VIDEO, with READ_EXTERNAL_STORAGE capped at API 32 for older devices. Its permission prompts are written in plain language and state that nothing is uploaded and everything stays on the device.

Setting the language takes a few taps:

  1. Open the language picker

    The picker lives inside the app and does not depend on the phone's system language.

  2. Choose from Suggested or search

    Languages matching the device locale appear in the Suggested section; any of the seventeen can be found by searching, under its own name or its English one.

  3. Or set it from system settings

    On Android 13 and later, the same choice is available under Settings › Apps › Googly Player › Language, and it stays in step with the in-app picker.

If you are building your own Android app for users across these languages, the same decisions apply: one process-wide locale, the platform setting on Android 13 and later, language splits disabled, format strings for counts and plural resources for words. They are the decisions we made for Googly Player, and they are the ones we would bring to your project.

Questions

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

No. Googly Player's language picker is entirely independent of the system language, and the choice is applied across the whole app, including notifications and dialogs.

Why would an in-app language picker show English after I chose another language?

Usually because the app was published with language splits enabled, so Play only delivered the system-language resources. Googly Player disables language splits so every translation ships in the base APK.

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

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

Which right-to-left languages does Googly Player support?

Arabic and Urdu, with full right-to-left layout, correctly anchored language names in the picker, and counts built from format strings so numbers land on the correct side.

  • #Android localisation
  • #Android plural resources
  • #Googly Player
  • #RTL Arabic Urdu
  • #in-app language picker

Comments

Add a comment
Sign in with Google to join the conversation