Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android - Forced locale reset on orientation changes

I try to force the locale in my app to one the user specified. As this may be used to demonstrations, I want to change the language/locale in the app and not anytime for the whole device.

I looked around SO and tried to use every hint I found here. The result: I can restart my test activity with the new language, but if I change the orientation, the locale will always be reseted to the device one.

I uploaded a minimalistic project so you can reproduce my issue. Please ignore the shrinking of the UI, it's not important :)

like image 435
WarrenFaith Avatar asked Feb 24 '10 07:02

WarrenFaith


3 Answers

This code snippet does what you need, I've tested it. Suppose for the example you want the user to be able to switch language through a menu from your main activity. You can do it through saving a language flag as a user preference and check it on "onCreate()" and on "onConfigurationChanged()" as follows:

    public class MainActivity extends Activity {

SharedPreferences mPrefs1;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    mPrefs1 = PreferenceManager.getDefaultSharedPreferences(this);
    String languageToLoad = mPrefs1.getString("languagePref", Locale.getDefault().getLanguage());
    Locale locale = new Locale(languageToLoad); 
    Locale.setDefault(locale);
    Configuration config = new Configuration();
    config.locale = locale;
    getBaseContext().getResources().updateConfiguration(config,getBaseContext().getResources().getDisplayMetrics());

    setContentView(R.layout.activity_main);
}

@Override
public void onConfigurationChanged(Configuration newConfig) {
  super.onConfigurationChanged(newConfig);
    mPrefs1 = PreferenceManager.getDefaultSharedPreferences(this);
    String languageToLoad = mPrefs1.getString("languagePref", Locale.getDefault().getLanguage());
    Locale locale = new Locale(languageToLoad); 
    Locale.setDefault(locale);
    Configuration config = new Configuration();
    config.locale = locale;
    getBaseContext().getResources().updateConfiguration(config,getBaseContext().getResources().getDisplayMetrics());
    setContentView(R.layout.activity_main);
}

// Declaring the Menu options
@Override
public boolean onCreateOptionsMenu(Menu menu)
{       
    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.main_menu, menu);
    return true;
}

//handle menu item selection
public boolean onOptionsItemSelected(MenuItem item)
{
  switch (item.getItemId()) {
    case R.id.menu_switch_language:
        String languageToLoad  = getResources().getString(R.string.switch_language);

        mPrefs1 = PreferenceManager.getDefaultSharedPreferences(this);
        SharedPreferences.Editor editor = mPrefs1.edit();
        editor.putString("languagePref", languageToLoad);
        editor.commit(); // Very important to save the preference                      
        finish();
        startActivity(getIntent());
        return true;
    default:
        return super.onOptionsItemSelected(item);
  }
}   

}

like image 177
Ronen Rabinovici Avatar answered Nov 11 '22 14:11

Ronen Rabinovici


I just saw your code.

Check that the Locale you are using is from java.util and not from android. Your code will not change the locale of the cellphone.

To test it:

  • I set my phone to Spanish.
  • Open your app
  • click the button
  • go to home
  • Icons were in spanish instead of english.

If what you are trying to do is just setting the Locale to a default and being able to see the same value after a screen rotation:

Instead of:

android:configChanges="locale"

use:

android:configChanges="locale|orientation"
like image 3
Macarse Avatar answered Nov 11 '22 14:11

Macarse


What worked for me is setting the locale right before you inflate your layouts :

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    String userLocale = "Wolof"; // adapt to your need
    Locale locale = new Locale(userLocale);
    Locale.setDefault(locale);
    Configuration config = new Configuration();
    config.locale = locale;
    getBaseContext().getResources().updateConfiguration(config, getBaseContext().getResources().getDisplayMetrics());

    setContentView(R.layout.my_activity);

    ...

}
like image 3
Mbengue Assane Avatar answered Nov 11 '22 15:11

Mbengue Assane