user924
user924

Reputation: 12283

Per-app language preferences - get list of app's available language programmatically?

So based on https://developer.android.com/guide/topics/resources/app-languages#kotlin

we can use

android {
  androidResources {
    generateLocaleConfig = true
  }
}

which automatically generates language list available for for users to change for a specific app:

enter image description here

(all languages list)

This list available for Android 13+ and only in app's system settings.

I want to implement a picker inside the app.

How can I get the same languages list without manually implementing it?

How to access the list which android.androidResources.generateLocaleConfig feature generated?

Update

I tried

val localeManager = context
    .getSystemService(LocaleManager::class.java)
localeManager.overrideLocaleConfig?.supportedLocales?.let { localeList ->
    Timber.d("localeList ${localeList.size()}")
}

but it's empty and works only for Android 13+

LocaleManagerCompat doesn't have such method

Upvotes: 2

Views: 160

Answers (1)

Kieron
Kieron

Reputation: 2028

I was able to do this by parsing the raw generated XML. It's not pretty and it's not perfectly safe (eg. if the format were to change - though I think it should remain stable), but it does work without any need to duplicate your supported languages manually.

@SuppressLint("DiscouragedApi")
fun Context.getSupportedLocales(): List<Locale> {
    val id = resources.getIdentifier(
        "_generated_res_locale_config",
        "xml",
        packageName
    )
    val localeXml = resources.getXml(id)
    val locales = ArrayList<String>()
    var event = localeXml.next()
    while(event != XmlResourceParser.END_DOCUMENT) {
        if(event == XmlResourceParser.START_TAG && localeXml.name == "locale") {
            locales.add(localeXml.getAttributeValue(0))
        }
        event = localeXml.next()
    }
    return locales.map {
        Locale.forLanguageTag(it)
    }
}

The lint suppression is required because getIdentifier is discouraged, but since the resource is generated during compile time we don't have access to its ID, so it has to be retrieved this way.

Upvotes: 0

Related Questions