1

I already know how to change the language of my application (updating the configuration). My code also check if the configuration is changed by the system and "fix it" in the ´onCreate´ method. I even have created a ListPreference to let the user decide the language with one that my app supports (and saves the decision).

Let's say I have 3 activities (A, B and SettingsActivity). Activity A can start activities B and SettingsActivity. Activity B can start SettingsActivity. If the user changes the language inside SettingsActivity, I can update its resources (in this case Strings) without any problem using this code:

//if (Build.VERSION_CODES.HONEYCOMB <= Build.VERSION.SDK_INT) {
// Disabled because it blinks and looks bad
// recreate();
// } else {
    startActivity(getIntent());
    finish();
    overridePendingTransition(0, 0);
// }

However, I'm unable to change the already open activities because I have no reference to them from SettingsActivity.

My question: is there any clean way to update the resources or recreate the already open activities? If I don't find a better solution, my approach will be one of the above:

  1. Start activities using startActivityForResultand return a code to trigger the code I already use to recreate the activity.
  2. Check inside the onResume method if the current language has changed and do the same thing.
gian1200
  • 3,670
  • 2
  • 30
  • 59
  • Possible duplicate of [Changing Locale within the app itself](http://stackoverflow.com/questions/2264874/changing-locale-within-the-app-itself). For recreating the `Activity`, I used the `onResume()` method. – Andrew T. Nov 03 '13 at 06:24
  • I've already read that question and most of the answers and my question is not a duplicate. – gian1200 Nov 03 '13 at 06:30
  • [This answer](http://stackoverflow.com/a/4881721/2821954) is the one I used in my app. Basically, for every `Activity` that can access the setting `Activity`, add a variable to store the current language (as `Locale` or as `String`, etc) in `onCreate()`. Then, overwrite `onResume()` to check if the language is changed or not. If it is, recreate the `Activity`. – Andrew T. Nov 03 '13 at 06:52
  • I understand you, that is my number 2 approach. But since that question is from 2010 and the answer you are pointing is from 2011, I was hoping to find a cleaner way to do it. – gian1200 Nov 03 '13 at 07:04

1 Answers1

0

At the end what I did was this:

@Override
protected void onStart() {
    super.onStart();
    if (!locale.equals(getResources().getConfiguration().locale)) {
        finish();
        startActivity(getIntent());
        overridePendingTransition(0, 0);
        return;
    }
}

Where locale is a variable assigned in my onCreate method:

private Locale locale;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    ((Application) getApplication()).refreshLanguage();
    locale = getResources().getConfiguration().locale;
    setContentView(R.layout.activity_main);
    //moar code
}

Finally, for the sake of posting code, here is my refreshLanguage method(s):

boolean refreshLanguage() {
    return refreshLanguage(PreferenceManager.getDefaultSharedPreferences(this));
}

boolean refreshLanguage(SharedPreferences sharedPreferences) {
    if (sharedPreferences.contains("language")) {
        int languageIndex = Integer.parseInt(sharedPreferences.getString("language", "0"));
        if (!getResources().getConfiguration().locale.equals(languages[languageIndex])) {
            Configuration config = new Configuration();
            config.locale = languages[languageIndex];
            getResources().updateConfiguration(config, null);
            return true;
        }
    }
    return false;
}

Notice that I use onStart rather than onResume because I'm not switching between transparent activities or using dialogs.

gian1200
  • 3,670
  • 2
  • 30
  • 59