Localizely logo
  • Home
  • Getting started
  • How it works
  • Pricing
  • FAQ
Sign up

I18n questions · Android

How do I get the current app or device language on Android? 

For most code, Locale.getDefault() is the answer. Android sets the process default locale when the app starts and again on every configuration change, from the first locale of the app's resource configuration, so it reflects a per-app language on Android 13+ as well as one applied by AppCompat on older versions.

import java.util.Locale

val locale = Locale.getDefault()
locale.language          // "pt"
locale.toLanguageTag()   // "pt-BR", a BCP 47 tag
locale.displayName       // the locale's name in the current language

The locale your resources were resolved for sits in the configuration. Configuration.locales holds the user's preferred languages, and the system moves the best match among your app's translations to the front, so index 0 is the language your strings come from:

val resourceLocale = resources.configuration.locales[0]   // API 24+
// Below API 24: ConfigurationCompat.getLocales(resources.configuration)[0]

LocaleList.getDefault() returns the full preference list in order; Locale.getDefault() is guaranteed to be in it but not necessarily first, which is how you can tell that the user's first choice is a language you do not ship.

Whether the user picked a language for your app specifically:

import androidx.appcompat.app.AppCompatDelegate

val appLocales = AppCompatDelegate.getApplicationLocales()
val appLanguage = appLocales[0]?.toLanguageTag()
// null: no per-app language, the app follows the system

The device language, as opposed to the app language, when a per-app language is active:

import android.app.LocaleManager
import android.content.res.Resources
import android.os.Build

val systemLocale = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
    context.getSystemService(LocaleManager::class.java).systemLocales[0]
} else {
    Resources.getSystem().configuration.locales[0]
}

LocaleManager.getSystemLocales() returns the system locales ignoring app-specific overrides. Below Android 13 the override exists only inside AppCompat, which applies it to AppCompatActivity contexts, so the system Resources object still carries the device configuration.

Pitfalls:

  • On Android 12 and lower, read resources through an AppCompatActivity context. The application context does not see the AppCompat per-app locale.
  • Use toLanguageTag() (zh-Hant-TW) rather than toString() (zh_TW_#Hant) when sending the language to a server or comparing it with a list of supported tags.
  • Locale.getDefault() can be changed by any code in the process through Locale.setDefault(); the configuration value cannot.

References: LocaleManager, Locale and Per-app language preferences.

Published Oct 9, 2026 · Markdown version

Related Android localization questions:

Android localization files:

Learn about Android XML string resources
Localizely logo
About
Free tools
Boring stuff
  • Privacy Policy
  • Terms of Service
  • Cookie Policy
  • Compare
Newsletter
Copyrights 2026 © Localizely