Android Cambia la localizzazione dell'applicazione Android programmaticamente

Esempio

Negli esempi precedenti capisci come localizzare le risorse dell'applicazione. L'esempio seguente spiega come modificare la locale dell'applicazione all'interno dell'applicazione, non dal dispositivo. Per modificare solo le impostazioni locali dell'applicazione, è possibile utilizzare l'utilità di localizzazione sottostante.

import android.app.Application;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.os.Build;
import android.preference.PreferenceManager;
import android.view.ContextThemeWrapper;

import java.util.Locale;

/**
 * Created by Umesh on 10/10/16.
 */
public class LocaleUtils {

    private static Locale mLocale;

    public static void setLocale(Locale locale){
        mLocale = locale;
        if(mLocale != null){
            Locale.setDefault(mLocale);
        }
    }

    public static void updateConfiguration(ContextThemeWrapper wrapper){
        if(mLocale != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1){
            Configuration configuration = new Configuration();
            configuration.setLocale(mLocale);
            wrapper.applyOverrideConfiguration(configuration);
        }
    }

    public static void updateConfiguration(Application application, Configuration configuration){
        if(mLocale != null && Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1){
            Configuration config = new Configuration(configuration);
            config.locale = mLocale;
            Resources res = application.getBaseContext().getResources();
            res.updateConfiguration(configuration, res.getDisplayMetrics());
        }
    }

    public static void updateConfiguration(Context context, String language, String country){
        Locale locale = new Locale(language,country);
        setLocale(locale);
        if(mLocale != null){
            Resources res = context.getResources();
            Configuration configuration = res.getConfiguration();
            configuration.locale = mLocale;
            res.updateConfiguration(configuration,res.getDisplayMetrics());
        }
    }




    public static String getPrefLangCode(Context context) {
        return PreferenceManager.getDefaultSharedPreferences(context).getString("lang_code","en");
    }

    public static void setPrefLangCode(Context context, String mPrefLangCode) {

        SharedPreferences.Editor editor = PreferenceManager.getDefaultSharedPreferences(context).edit();
        editor.putString("lang_code",mPrefLangCode);
        editor.commit();
    }

    public static  String getPrefCountryCode(Context context) {
        return PreferenceManager.getDefaultSharedPreferences(context).getString("country_code","US");
    }

    public static void setPrefCountryCode(Context context,String mPrefCountryCode) {

        SharedPreferences.Editor editor = PreferenceManager.getDefaultSharedPreferences(context).edit();
        editor.putString("country_code",mPrefCountryCode);
        editor.commit();
    }
}

Inizializza le impostazioni locali preferite dall'utente, dalla classe Application.

public class LocaleApp extends Application{

    @Override
    public void onCreate() {
        super.onCreate();

        LocaleUtils.setLocale(new Locale(LocaleUtils.getPrefLangCode(this), LocaleUtils.getPrefCountryCode(this)));
        LocaleUtils.updateConfiguration(this, getResources().getConfiguration());
    }
}

È inoltre necessario creare un'attività di base ed estendere questa attività a tutte le altre attività in modo che sia possibile modificare le impostazioni internazionali dell'applicazione solo in un punto come segue:

public abstract class LocalizationActivity extends AppCompatActivity {

    public LocalizationActivity() {
        LocaleUtils.updateConfiguration(this);
    }

    // We only override onCreate
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

}

Nota: inizializzare sempre la locale nel costruttore.

Ora puoi usare LocalizationActivity come segue.

public class MainActivity extends LocalizationActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

    }
}

Nota: quando si modifica la localizzazione dell'applicazione a livello di programmazione, è necessario riavviare l'attività per ottenere l'effetto della modifica delle impostazioni locali Per poter funzionare correttamente per questa soluzione e utilizzare le android:name=".LocaleApp" locali dalle preferenze condivise all'avvio dell'app, android:name=".LocaleApp" in tu Manifest.xml.

A volte il programma di controllo Lint richiede di creare la build di rilascio. Per risolvere questo problema, segui le seguenti opzioni.

Primo:

Se si desidera disabilitare la conversione solo per alcune stringhe, quindi aggiungere il seguente attributo a default string.xml

<string name="developer" translatable="false">Developer Name</string>

Secondo:

Ignora tutta la traduzione mancante dal file di risorse aggiungi il seguente attributo È l'attributo ignore dello spazio dei nomi degli strumenti nel file delle stringhe, come segue:

<?xml version="1.0" encoding="utf-8"?>
<resources
  xmlns:tools="http://schemas.android.com/tools"
  tools:ignore="MissingTranslation" >
http://stackoverflow.com/documentation/android/3345/localization-with-resources-in-android#
  <!-- your strings here; no need now for the translatable attribute -->

</resources>

Terzo:

Un altro modo per disabilitare la stringa non traducibile

http://tools.android.com/recent/non-translatablestrings

Se si dispone di molte risorse che non devono essere tradotte, è possibile inserirle in un file denominato donottranslate.xml e Lint considererà tutte le risorse non traducibili.

Il quarto:

È inoltre possibile aggiungere impostazioni internazionali nel file di risorse

<resources
xmlns:tools="http://schemas.android.com/tools"
    tools:locale="en" tools:ignore="MissingTranslation">

Puoi anche disabilitare il controllo della traduzione mancante per lint da app / build.gradle

lintOptions {
        
        disable 'MissingTranslation'
    }