Lingua preferita nelle app

Lingue per app nelle impostazioni di sistema

In molti casi, gli utenti multilingue impostano la lingua di sistema su una lingua, ad esempio l'inglese, ma vogliono selezionare altre lingue per app specifiche, ad esempio olandese, cinese o hindi. Per consentire alle app di offrire un'esperienza migliore a questi utenti, Android 13 introduce le seguenti funzionalità per le app che supportano più lingue:

  • Impostazioni di sistema: una posizione centralizzata in cui gli utenti possono selezionare una lingua preferita per ogni app.

    Puoi configurare l'app in modo che generi automaticamente i file necessari per supportare le preferenze di lingua di ciascuna app e che vengano visualizzati nelle impostazioni di sistema. Per scoprire di più, consulta le istruzioni per attivare il supporto automatico delle lingue per app.

  • API aggiuntive: queste API pubbliche, come i metodi setApplicationLocales() e getApplicationLocales() in LocaleManager, consentono alle app di impostare una lingua diversa da quella del sistema al momento del runtime.

    Queste API si sincronizzano automaticamente con le impostazioni di sistema; pertanto, le app che utilizzano queste API per creare selettori di lingua in-app personalizzati garantiranno agli utenti un'esperienza utente coerente, indipendentemente da dove selezionino le preferenze di lingua. Le API pubbliche consentono inoltre di ridurre la quantità di codice boilerplate, supportano APK divisi e supportano la funzionalità Backup automatico per le app per archiviare le impostazioni della lingua dell'utente a livello di app.

    Per garantire la compatibilità con le versioni precedenti di Android, sono disponibili API equivalenti anche in AndroidX. Tuttavia, le API compatibili con le versioni precedenti funzionano con il contesto AppCompatActivity, non con il contesto dell'applicazione, per Android 12 (livello API 32) e versioni precedenti. Accedi alle API compatibili con le versioni precedenti con Appcompat 1.6.0 o versioni successive.

Panoramica dell'implementazione di questa funzionalità

La seguente tabella mostra le implementazioni consigliate in base a diversi casi d'uso.

Caso d'uso Implementazione consigliata
La tua app non ha un selettore lingua in-app
  1. Attiva il supporto automatico delle lingue in base alle app per generare un file LocaleConfig e aggiungere le lingue della tua app alle impostazioni di sistema.
  2. Facoltativamente, se vuoi aggiungere un selettore lingua in-app, utilizza la libreria AndroidX e attiva la nostra implementazione dell'API per supportare la compatibilità con le versioni precedenti tramite autoStoreLocales.
La tua app ha già un selettore lingua in-app
  1. Attiva il supporto automatico delle lingue in base alle app per generare un file LocaleConfig e aggiungere le lingue della tua app alle impostazioni di sistema.
  2. Esegui la migrazione della logica personalizzata della tua app in modo da utilizzare le API pubbliche e assicurarti che gli utenti vedano un'esperienza coerente.
  3. Gestisci i seguenti casi d'angolo:
    1. Chiama AppCompatDelegate.setApplicationLocales() la prima volta che la tua app viene eseguita su un dispositivo con Android 13.
    2. Chiama AppCompatDelegate.setApplicationLocales() per fornire al sistema le impostazioni internazionali richieste dagli utenti preesistenti per i seguenti casi:

Impostazioni di sistema per gli utenti

A partire da Android 13, Android include una posizione centralizzata nelle impostazioni di sistema per impostare le preferenze relative alla lingua per ogni app. Per assicurarti che le lingue dell'app siano configurabili nelle impostazioni di sistema sui dispositivi con Android 13 o versioni successive, attiva il supporto automatico delle lingue per ogni app (opzione consigliata) oppure configura l'assistenza manualmente.

Attiva il supporto automatico delle lingue per app

A partire da Android Studio Giraffe e AGP 8.1, puoi configurare la tua app per supportare automaticamente le preferenze linguistiche per ogni app. In base alle risorse del progetto, AGP genera il file LocaleConfig a cui aggiunge un riferimento nel file manifest finale, quindi non è più necessario farlo manualmente. AGP utilizza le risorse nelle cartelle res dei moduli dell'app e le eventuali dipendenze dei moduli delle librerie per determinare le impostazioni internazionali da includere nel file LocaleConfig. Ciò significa che se aggiungi risorse per una nuova lingua alla tua app, non devi preoccuparti di aggiornare il file LocaleConfig.

Tieni presente che la funzionalità linguistica automatica per ogni app supporta le app con Android 13 (livello API 33) o versioni successive. Per utilizzare la funzionalità, devi impostare compileSdkVersion su 33 o un valore superiore. Per configurare le preferenze linguistiche per app per le versioni precedenti di Android, devi comunque utilizzare le API e i selettori lingua in-app.

Per attivare il supporto automatico delle lingue in base alle app, procedi nel seguente modo:

  1. Per attivare la funzionalità, utilizza l'impostazione generateLocaleConfig nel blocco androidResources {} del file build.gradle.kts a livello di modulo (file build.gradle se utilizzi Groovy). La funzionalità è disattivata per impostazione predefinita.

    Kotlin

        android {
          androidResources {
            generateLocaleConfig = true
          }
        }
        

    trendy

        android {
          androidResources {
            generateLocaleConfig true
          }
        }
        
  2. Specifica un'impostazione internazionale predefinita:
    1. Nella cartella res del modulo dell'app, crea un nuovo file denominato resources.properties.
    2. Nel file resources.properties, imposta le impostazioni internazionali predefinite con l'etichetta unqualifiedResLocale. Per formattare i nomi delle impostazioni internazionali, vedi Come creare nomi delle impostazioni internazionali.

AGP aggiunge queste impostazioni internazionali predefinite ed eventuali impostazioni internazionali alternative che hai specificato, utilizzando le directory values-* nella cartella res, al file LocaleConfig generato automaticamente.

Come creare nomi di impostazioni internazionali

Per creare nomi di impostazioni internazionali, combina il codice della lingua con lo script facoltativo e i codici regione, separandoli con un trattino:

Ad esempio, se la tua lingua predefinita è Inglese americano:

unqualifiedResLocale=en-US

Usa android:localeConfig per aggiungere lingue supportate alle impostazioni di sistema

Puoi configurare manualmente l'app in modo che le relative lingue siano configurabili nelle impostazioni di sistema sui dispositivi con Android 13 o versioni successive. Per farlo, crea un file XML locales_config e aggiungilo al file manifest della tua app utilizzando l'attributo android:localeConfig. Omissione degli indicatori di voce del file manifest android:localeConfig che indicano che gli utenti non dovrebbero essere in grado di impostare la lingua dell'app indipendentemente da quella di sistema nelle impostazioni di sistema.

Per aggiungere manualmente le lingue supportate dalla tua app alle impostazioni di sistema di un utente:

  1. Crea un file denominato res/xml/locales_config.xml e specifica le lingue dell'app, incluse le impostazioni internazionali di riserva, quelle specificate in res/values/strings.xml.

    Per i requisiti di formato, consulta Come creare nomi di impostazioni internazionali. Vedi anche il file locale_config.xmldi esempio per un elenco delle impostazioni internazionali più utilizzate.

    Ad esempio, formatta il file locales_config.xml in questo modo per un'app che supporta le seguenti lingue:

    • Inglese (Stati Uniti) come lingua di riserva definitiva
    • Inglese (Regno Unito)
    • Francese
    • Giapponese
    • Cinese (semplificato, Macao)
    • Cinese (tradizionale, Macao)
    <?xml version="1.0" encoding="utf-8"?>
    <locale-config xmlns:android="http://schemas.android.com/apk/res/android">
       <locale android:name="en-US"/>
       <locale android:name="en-GB"/>
       <locale android:name="fr"/>
       <locale android:name="ja"/>
       <locale android:name="zh-Hans-MO"/>
       <locale android:name="zh-Hant-MO"/>
    </locale-config>
    
  2. Nel manifest, aggiungi una riga che rimandi a questo nuovo file:

    <manifest>
        ...
        <application
            ...
            android:localeConfig="@xml/locales_config">
        </application>
    </manifest>
    

Puoi aggiornare dinamicamente localeConfig dell'app con LocaleManager.setOverrideLocaleConfig per personalizzare l'insieme di lingue visualizzate nell'elenco delle lingue dell'app nelle Impostazioni di Android. In questo modo, puoi personalizzare l'elenco di lingue per regione, eseguire esperimenti A/B e fornire impostazioni internazionali aggiornate se la tua app utilizza push di localizzazione lato server, come mostrato nell'esempio seguente:

Kotlin

//For setOverrideLocaleConfig
val localeManager = applicationContext
    .getSystemService(LocaleManager::class.java)
localeManager.overrideLocaleConfig = LocaleConfig(
LocaleList.forLanguageTags("en-US,ja-JP,zh-Hans-SG")
)

//For getOverrideLocaleConfig
// The app calls the API to get the override LocaleConfig
val overrideLocaleConfig = localeManager.overrideLocaleConfig
// If the returned overrideLocaleConfig isn't equal to NULL, then the app calls the API to get the supported Locales
val supportedLocales = overrideLocaleConfig.supportedLocales()

Java

//For setOverrideLocaleConfig
mContext.getSystemService(LocaleManager.class).setOverrideLocaleConfig(new LocaleConfig(LocaleList.forLanguageTags("en-US,ja-JP,zh-Hans-SG")));

//For getOverrideLocaleConfig
// The app calls the API to get the override LocaleConfig
LocaleConfig overrideLocaleConfig = mContext.getSystemService(LocaleManager.class).getOverrideLocaleConfig();
// If the returned overrideLocaleConfig isn't equal to NULL, then the app calls the API to get the supported Locales
LocaleList supportedLocales = overrideLocaleConfig.getSupportedLocales();

Inoltre, gli IME ora possono usare LocaleManager.getApplicationLocales per conoscere la lingua dell'interfaccia utente dell'app corrente e aggiornarla come mostrato:

Kotlin

val currentAppLocales: LocaleList = applicationContext.getSystemService(LocaleManager::class.java).getApplicationLocales(appPackageName)

Java

LocaleList currentAppLocales =
    mContext.getSystemService(LocaleManager.class).getApplicationLocales(appPackageName);

Specifica le lingue supportate in Gradle

Se non è già presente, specifica le stesse lingue utilizzando la proprietà resourceConfigurations nel file build.gradle a livello di modulo dell'app:

android {
  ...
  defaultConfig {
    resourceConfigurations += ["en", "en-rGB", "fr", "ja", "b+zh+Hans+MO", "b+zh+Hant+MO"]
  }
}

Quando la proprietà resourceConfigurations è presente, il sistema di compilazione include solo una risorsa di lingua nell'APK per questi linguaggi specificati, impedendo l'inclusione di stringhe tradotte da altre librerie che potrebbero supportare lingue non supportate dalla tua app. Per maggiori informazioni, consulta Specificare le lingue supportate dall'app.

In che modo gli utenti selezionano una lingua dell'app nelle impostazioni di sistema

Gli utenti possono selezionare la lingua che preferiscono per ogni app tramite le impostazioni di sistema. Possono accedere a queste impostazioni in due modi diversi:

  • Accesso tramite le impostazioni di sistema

    Impostazioni > Sistema > Lingue e immissione > Lingue delle app > (seleziona un'app)

  • Accesso tramite le impostazioni delle App

    Impostazioni > App > (seleziona un'app) > Lingua

Gestire i selettori della lingua in-app

Per le app che hanno già un selettore lingua in-app o che vuoi utilizzarne uno, usa le API pubbliche anziché una logica dell'app personalizzata per gestire le impostazioni e ottenere la lingua preferita dall'utente per la tua app. Se utilizzi le API pubbliche per il selettore di lingua in-app, le impostazioni di sistema del dispositivo vengono aggiornate automaticamente in modo che corrispondano alla lingua selezionata dall'utente tramite l'esperienza in-app.

Per la compatibilità con le versioni precedenti di Android, consigliamo vivamente di utilizzare la libreria di supporto AndroidX quando implementi un selettore lingua in-app. Tuttavia, se necessario, puoi anche implementare direttamente le API framework.

Implementazione utilizzando la libreria di supporto AndroidX

Utilizza i metodi setApplicationLocales() e getApplicationLocales() in Appcompat 1.6.0 o versioni successive. Tieni presente che le API compatibili con le versioni precedenti funzionano con il contesto AppCompatActivity, non con il contesto dell'applicazione, per Android 12 (livello API 32) e versioni precedenti.

Ad esempio, per impostare la lingua preferita di un utente, chiedi all'utente di selezionare un'impostazione internazionale nel selettore lingua e di impostare quel valore nel sistema:

Kotlin

val appLocale: LocaleListCompat = LocaleListCompat.forLanguageTags("xx-YY")
// Call this on the main thread as it may require Activity.restart()
AppCompatDelegate.setApplicationLocales(appLocale)

Java

LocaleListCompat appLocale = LocaleListCompat.forLanguageTags("xx-YY");
// Call this on the main thread as it may require Activity.restart()
AppCompatDelegate.setApplicationLocales(appLocale);

Tieni presente che la chiamata a setApplicationLocales() ricrea il tuo Activity, a meno che l'app non gestisca le modifiche alla configurazione delle impostazioni internazionali da sola.

Utilizza AppCompatDelegate.getApplicationLocales() per recuperare le impostazioni internazionali preferite dall'utente. L'utente potrebbe aver selezionato le impostazioni internazionali dell'app dalle impostazioni di sistema o dal selettore lingua in-app.

Supporta Android 12 e versioni precedenti

Per supportare i dispositivi con Android 12 (livello API 32) e versioni precedenti, chiedi ad AndroidX di gestire l'archiviazione locale impostando un valore autoStoreLocales su true e android:enabled su false nella voce del manifest per il servizio AppLocalesMetadataHolderService della tua app, come mostrato nel seguente snippet di codice:

<application
  ...
  <service
    android:name="androidx.appcompat.app.AppLocalesMetadataHolderService"
    android:enabled="false"
    android:exported="false">
    <meta-data
      android:name="autoStoreLocales"
      android:value="true" />
  </service>
  ...
</application>

Tieni presente che l'impostazione di un valore autoStoreLocales su true causa una lettura di blocco sul thread principale e potrebbe causare una violazione di StrictMode diskRead e diskWrite se registri violazioni dei thread. Per saperne di più, visita la pagina AppCompatDelegate.setApplicationLocales().

Gestione personalizzata dello spazio di archiviazione

Se la voce del file manifest o l'impostazione di autoStoreLocales su false viene omessa, significa che stai gestendo il tuo spazio di archiviazione in autonomia. In questo caso, devi fornire le impostazioni internazionali archiviate prima del giorno onCreate nel ciclo di vita dell'attività e limitare le chiamate a AppCompatDelegate.setApplicationLocales() in Android 12 (livello API 32) o versioni precedenti.

Se la tua app ha una posizione di archiviazione delle impostazioni internazionali personalizzata, ti consigliamo di effettuare un trasferimento una tantum tra la tua soluzione di archiviazione delle impostazioni internazionali personalizzata e autoStoreLocales, in modo che gli utenti possano continuare a usufruire dell'app nella lingua che preferiscono. Questo vale in particolare nei casi in cui la tua app viene eseguita per la prima volta dopo l'upgrade di un dispositivo ad Android 13. In questo caso, puoi fornire le impostazioni internazionali richieste dagli utenti preesistenti recuperandole dallo spazio di archiviazione personalizzato e passandole a AppCompatDelegate.setApplicationLocales().

Esegui l'implementazione utilizzando le API del framework Android

Anche se consigliamo vivamente di utilizzare la libreria di supporto AndroidX per implementare i selettori della lingua in-app, puoi anche usare i metodi setApplicationLocales() e getApplicationLocales() nel framework Android per i dispositivi con Android 13.

Ad esempio, per impostare la lingua preferita di un utente, chiedi all'utente di selezionare un'impostazione internazionale nel selettore lingua e di impostare quel valore nel sistema:

// 1. Inside an activity, in-app language picker gets an input locale "xx-YY"
// 2. App calls the API to set its locale
mContext.getSystemService(LocaleManager.class
    ).setApplicationLocales(new LocaleList(Locale.forLanguageTag("xx-YY")));
// 3. The system updates the locale and restarts the app, including any configuration updates
// 4. The app is now displayed in "xx-YY" language

Per fare in modo che la lingua preferita di un utente venga visualizzata nel selettore lingua, la tua app può recuperare il valore dal sistema:

// 1. App calls the API to get the preferred locale
LocaleList currentAppLocales =
    mContext.getSystemService(LocaleManager.class).getApplicationLocales();
// 2. App uses the returned LocaleList to display languages to the user

Best practice aggiuntive

Prendi nota delle seguenti best practice.

Considera il linguaggio quando richiami un intent in un'altra app

Gli intent incentrati sul linguaggio potrebbero consentirti di specificare la lingua in cui vuoi che venga utilizzata l'app richiamata. Un esempio è la funzionalità EXTRA_LANGUAGE dell'API Speech Recognition.

Prendi in considerazione l'intestazione Accept-Language per la scheda personalizzata di Chrome

Potresti aggiungere l'intestazione in lingua accettazione tramite Browser.EXTRA_HEADERS per aprire una pagina web nella lingua della tua app quando richiami una scheda personalizzata di Chrome.

Se rimuovi le preferenze relative alla lingua per ciascuna app nelle impostazioni di sistema, reimposta le impostazioni internazionali dell'app con quelle di sistema.

Se rimuovi le preferenze relative alla lingua dell'app dalle impostazioni di sistema (rimuovendo android:localeConfig da AndroidManifest.xml dell'app), gli utenti non potranno facilmente reimpostare la lingua dell'app sul valore predefinito di sistema.

Per questo motivo, se rimuovi android:localeConfig, valuta la possibilità di reimpostare le impostazioni internazionali dell'app sul sistema utilizzando LocaleListCompat.getEmptyLocaleList() o LocaleList.getEmptyLocaleList() come mostrato nel seguente snippet di codice:

Kotlin

// Use the AndroidX APIs to reset to the system locale for backward and forward compatibility
AppCompatDelegate.setApplicationLocales(
  LocaleListCompat.getEmptyLocaleList()
)

// Or use the Framework APIs for Android 13 and above to reset to the system locale
val context = LocalContext.current
context.getSystemService(LocaleManager::class.java)
  .applicationLocales = LocaleList.getEmptyLocaleList()

Java

// Use the AndroidX APIs to reset to the system locale for backward and forward compatibility
AppCompatDelegate.setApplicationLocales(
  LocaleListCompat.getEmptyLocaleList()
);

// Or use the Framework APIs for Android 13 and above to reset to the system locale
mContext.getSystemService(LocaleManager.class)
  .setApplicationLocales(LocaleList.getEmptyLocaleList());

Risorse aggiuntive

Consulta i nostri esempi di codice, gli articoli del blog e i video per ulteriori informazioni.

File locale_config.xml di esempio

Per impostazione predefinita, Android include traduzioni a livello di sistema nell'Android Open Source Project (AOSP) per un insieme standard delle impostazioni internazionali di uso più comune. Il file locale_config.xml di esempio incluso in questa sezione mostra il formato suggerito per ciascuna di queste impostazioni internazionali. Fai riferimento a questo file di esempio per creare il tuo file locale_config.xml per l'insieme di lingue supportate dalla tua app.

<?xml version="1.0" encoding="utf-8"?>
<locale-config xmlns:android="http://schemas.android.com/apk/res/android">
   <locale android:name="af"/> <!-- Afrikaans -->
   <locale android:name="am"/> <!-- Amharic -->
   <locale android:name="ar"/> <!-- Arabic -->
   <locale android:name="as"/> <!-- Assamese -->
   <locale android:name="az"/> <!-- Azerbaijani -->
   <locale android:name="be"/> <!-- Belarusian -->
   <locale android:name="bg"/> <!-- Bulgarian -->
   <locale android:name="bn"/> <!-- Bengali -->
   <locale android:name="bs"/> <!-- Bosnian -->
   <locale android:name="ca"/> <!-- Catalan -->
   <locale android:name="cs"/> <!-- Czech -->
   <locale android:name="da"/> <!-- Danish -->
   <locale android:name="de"/> <!-- German -->
   <locale android:name="el"/> <!-- Greek -->
   <locale android:name="en-AU"/> <!-- English (Australia) -->
   <locale android:name="en-CA"/> <!-- English (Canada) -->
   <locale android:name="en-GB"/> <!-- English (United Kingdom) -->
   <locale android:name="en-IN"/> <!-- English (India) -->
   <locale android:name="en-US"/> <!-- English (United States) -->
   <locale android:name="en-XA"/> <!-- English (Pseudo-Accents) -->
   <locale android:name="es"/> <!-- Spanish (Spain) -->
   <locale android:name="es-US"/> <!-- Spanish (United States) -->
   <locale android:name="et"/> <!-- Estonian -->
   <locale android:name="eu"/> <!-- Basque -->
   <locale android:name="fa"/> <!-- Farsi -->
   <locale android:name="fi"/> <!-- Finnish -->
   <locale android:name="fr"/> <!-- French (France) -->
   <locale android:name="fr-CA"/> <!-- French (Canada) -->
   <locale android:name="gl"/> <!-- Galician -->
   <locale android:name="gu"/> <!-- Gujarati -->
   <locale android:name="hi"/> <!-- Hindi -->
   <locale android:name="hr"/> <!-- Croatian -->
   <locale android:name="hu"/> <!-- Hungarian -->
   <locale android:name="hy"/> <!-- Armenian -->
   <locale android:name="in"/> <!-- Indonesian -->
   <locale android:name="is"/> <!-- Icelandic -->
   <locale android:name="it"/> <!-- Italian -->
   <locale android:name="iw"/> <!-- Hebrew -->
   <locale android:name="ja"/> <!-- Japanese -->
   <locale android:name="ka"/> <!-- Georgian -->
   <locale android:name="kk"/> <!-- Kazakh -->
   <locale android:name="km"/> <!-- Khmer -->
   <locale android:name="kn"/> <!-- Kannada -->
   <locale android:name="ko"/> <!-- Korean -->
   <locale android:name="ky"/> <!-- Kyrgyz -->
   <locale android:name="lo"/> <!-- Lao -->
   <locale android:name="lt"/> <!-- Lithuanian -->
   <locale android:name="lv"/> <!-- Latvian -->
   <locale android:name="mk"/> <!-- Macedonian -->
   <locale android:name="ml"/> <!-- Malayalam -->
   <locale android:name="mn"/> <!-- Mongolian -->
   <locale android:name="mr"/> <!-- Marathi -->
   <locale android:name="ms"/> <!-- Malay -->
   <locale android:name="my"/> <!-- Burmese -->
   <locale android:name="my-MM"/> <!-- Burmese (Myanmar) -->
   <locale android:name="nb"/> <!-- Norwegian -->
   <locale android:name="ne"/> <!-- Nepali -->
   <locale android:name="nl"/> <!-- Dutch -->
   <locale android:name="or"/> <!-- Odia -->
   <locale android:name="pa"/> <!-- Punjabi -->
   <locale android:name="pl"/> <!-- Polish -->
   <locale android:name="pt-BR"/> <!-- Portuguese (Brazil) -->
   <locale android:name="pt-PT"/> <!-- Portuguese (Portugal) -->
   <locale android:name="ro"/> <!-- Romanian -->
   <locale android:name="ru"/> <!-- Russian -->
   <locale android:name="si"/> <!-- Sinhala -->
   <locale android:name="sk"/> <!-- Slovak -->
   <locale android:name="sl"/> <!-- Slovenian -->
   <locale android:name="sq"/> <!-- Albanian -->
   <locale android:name="sr"/> <!-- Serbian (Cyrillic) -->
   <locale android:name="sr-Latn"/> <!-- Serbian (Latin) -->
   <locale android:name="sv"/> <!-- Swedish -->
   <locale android:name="sw"/> <!-- Swahili -->
   <locale android:name="ta"/> <!-- Tamil -->
   <locale android:name="te"/> <!-- Telugu -->
   <locale android:name="th"/> <!-- Thai -->
   <locale android:name="tl"/> <!-- Filipino -->
   <locale android:name="tr"/> <!-- Turkish -->
   <locale android:name="uk"/> <!-- Ukrainian -->
   <locale android:name="ur"/> <!-- Urdu -->
   <locale android:name="uz"/> <!-- Uzbek -->
   <locale android:name="vi"/> <!-- Vietnamese -->
   <locale android:name="zh-CN"/> <!-- Chinese (Simplified) -->
   <locale android:name="zh-HK"/> <!-- Chinese (Hong Kong) -->
   <locale android:name="zh-TW"/> <!-- Chinese (Traditional) -->
   <locale android:name="zu"/> <!-- Zulu -->
</locale-config>