Change app language programmatically in Android

前端 未结 30 2968
面向向阳花
面向向阳花 2020-11-21 04:34

Is it possible to change the language of an app programmatically while still using Android resources?

If not, is it possible to request a resource in an specific lan

相关标签:
30条回答
  • 2020-11-21 05:25

    Create a class Extends Application and create a static method. Then you can call this method in all activities before setContentView().

    public class MyApp extends Application {
    
    @Override
    public void onCreate() {
        super.onCreate();
    }
    
    public static void setLocaleFa (Context context){
        Locale locale = new Locale("fa"); 
        Locale.setDefault(locale);
        Configuration config = new Configuration();
        config.locale = locale;
        context.getApplicationContext().getResources().updateConfiguration(config, null);
    }
    
    public static void setLocaleEn (Context context){
        Locale locale = new Locale("en_US"); 
        Locale.setDefault(locale);
        Configuration config = new Configuration();
        config.locale = locale;
        context.getApplicationContext().getResources().updateConfiguration(config, null);
    }
    
    }
    

    Usage in activities:

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        MyApp.setLocaleFa(MainActivity.this);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        setContentView(R.layout.activity_main);
    }
    
    0 讨论(0)
  • 2020-11-21 05:25
    /*change language at Run-time*/
    //use method like that:
    //setLocale("en");
     public void setLocale(String lang) { 
      myLocale = new Locale(lang);         
      Resources res = getResources();         
      DisplayMetrics dm = res.getDisplayMetrics();         
      Configuration conf = res.getConfiguration();         
      conf.locale = myLocale;         
      res.updateConfiguration(conf, dm);         
      Intent refresh = new Intent(this, AndroidLocalize.class);         
      startActivity(refresh); 
     }
    
    0 讨论(0)
  • 2020-11-21 05:25

    If someone looking for disable language at compile time, here is the solution:

    android {
        defaultConfig {
            resConfigs "en"
        }
    }
    

    This isn't just for disabling localisation—resConfigs simply tells the build system which resources to keep.

    You can check original answer here

    0 讨论(0)
  • 2020-11-21 05:26

    None of the solutions listed here helped me.

    The language did not switch on android >= 7.0 if AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES)

    This LocaleUtils works just fine: https://gist.github.com/GigigoGreenLabs/7d555c762ba2d3a810fe

    LocaleUtils

    public class LocaleUtils {
    
    public static final String LAN_SPANISH      = "es";
    public static final String LAN_PORTUGUESE   = "pt";
    public static final String LAN_ENGLISH      = "en";
    
    private static Locale sLocale;
    
    public static void setLocale(Locale locale) {
        sLocale = locale;
        if(sLocale != null) {
            Locale.setDefault(sLocale);
        }
    }
    
    public static void updateConfig(ContextThemeWrapper wrapper) {
        if(sLocale != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
            Configuration configuration = new Configuration();
            configuration.setLocale(sLocale);
            wrapper.applyOverrideConfiguration(configuration);
        }
    }
    
    public static void updateConfig(Application app, Configuration configuration) {
        if(sLocale != null && Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1) {
            //Wrapping the configuration to avoid Activity endless loop
            Configuration config = new Configuration(configuration);
            config.locale = sLocale;
            Resources res = app.getBaseContext().getResources();
            res.updateConfiguration(config, res.getDisplayMetrics());
        }
    }
    }
    

    Added this code to Application

    public class App extends Application {
    public void onCreate(){
        super.onCreate();
    
        LocaleUtils.setLocale(new Locale("iw"));
        LocaleUtils.updateConfig(this, getBaseContext().getResources().getConfiguration());
    }
    
    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        LocaleUtils.updateConfig(this, newConfig);
    }
    }
    

    Code in Activity

    public class BaseActivity extends AppCompatActivity {
        public BaseActivity() {
            LocaleUtils.updateConfig(this);
        }
    }
    
    0 讨论(0)
  • 2020-11-21 05:29

    I was looking for a way to change the system language programmatically. While I fully understand that a normal application should never do that and instead either:

    • the user should be pointed(through an intent) to the system settings to change it manually
    • the application should handle its localization on its own just like described in the answer of Alex

    there was a need to really change the language of the system programmtically.

    This is undocumented API and thus should not be used for market/end-user applications!

    Anyway heres the solution i found:

      Locale locale = new Locale(targetLocaleAsString);
    
      Class amnClass = Class.forName("android.app.ActivityManagerNative");
      Object amn = null;
      Configuration config = null;
    
      // amn = ActivityManagerNative.getDefault();
      Method methodGetDefault = amnClass.getMethod("getDefault");
      methodGetDefault.setAccessible(true);
      amn = methodGetDefault.invoke(amnClass);
    
      // config = amn.getConfiguration();
      Method methodGetConfiguration = amnClass.getMethod("getConfiguration");
      methodGetConfiguration.setAccessible(true);
      config = (Configuration) methodGetConfiguration.invoke(amn);
    
      // config.userSetLocale = true;
      Class configClass = config.getClass();
      Field f = configClass.getField("userSetLocale");
      f.setBoolean(config, true);
    
      // set the locale to the new value
      config.locale = locale;
    
      // amn.updateConfiguration(config);
      Method methodUpdateConfiguration = amnClass.getMethod("updateConfiguration", Configuration.class);
      methodUpdateConfiguration.setAccessible(true);
      methodUpdateConfiguration.invoke(amn, config);
    
    0 讨论(0)
  • 2020-11-21 05:31

    Locale configuration should be set in each activity before setting the content - this.setContentView(R.layout.main);

    0 讨论(0)
提交回复
热议问题