Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android update language in preference activity

In my android app i have a preference activity which let's the user override the app's language. To achieve this I call this function in every activity's onResume() and then reset the content view:

    public static void checkOverrideSystemLanguage(Context context) {
    SharedPreferences prefs = PreferenceManager
            .getDefaultSharedPreferences(context);

    // Check if system's language setting needs to be overridden
    boolean overrideSystemLanguage = prefs.getBoolean(context
            .getString(R.string.pref_key_chkbx_override_system_language),
            false);

    if (overrideSystemLanguage) {

        // Get language selection and possible languages
        String localeString = prefs.getString(
                context.getString(R.string.pref_key_list_languages), "");
        List<String> possibleLanguages = Arrays.asList(context
                .getResources().getStringArray(
                        R.array.pref_values_list_languages));

        if (possibleLanguages.contains(localeString)) {

            // Change language setting in configuration
            Locale locale = new Locale(localeString);
            Locale.setDefault(locale);
            Configuration config = new Configuration();
            config.locale = locale;
            context.getResources().updateConfiguration(config,
                    context.getResources().getDisplayMetrics());
        }
        // Use default language
        else {
            overrideSystemLanguage = false;
        }
    }

    // Use default language
    if (!overrideSystemLanguage) {
        context.getResources().updateConfiguration(
                Resources.getSystem().getConfiguration(),
                context.getResources().getDisplayMetrics());
    }
}

In every activity it works perfectly fine. In the preference activity, however, when the user changes the language it does not get updated right away, because there is no setContentView() method. The user has to go back to the previous activity and start the preferences activity again to see the language change reflected.

I tried the following in a onPreferenceChange() listener:

  1. Updating the configuration, removing and readding the preferences:

    checkOverrideSystemLanguage(this);      
    // Remove all preferences and add them to update the language
    getPreferenceScreen().removeAll();
    addPreferencesFromResource(R.xml.preferences);
    
  2. Updating the configuration and calling onCreate(null)

  3. Finishing and restarting the activity

    finish();
    startActivity(new Intent(this, PreferencesActivity.class));
    

Thanks for your help!

like image 914
Oliver Avatar asked Oct 17 '11 15:10

Oliver


1 Answers

I had a similar problem, I solved in this way (as you said: finishing and restarting activity). It works!

    public class OptionsActivity extends PreferenceActivity implements YesNoDialogPreference.YesNoDialogListener, SharedPreferences.OnSharedPreferenceChangeListener {

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

        //Options Setting
        final SharedPreferences prefs = getSharedPreferences(OptionsUtility.PREFERENCE_NAME, MODE_PRIVATE);
        String language = prefs.getString(OptionsUtility.PREFERENCE_LANGUAGE, OptionsUtility.DEFAULT_LANGUAGE);

        //Update locale
        OptionsUtility.updateLanguage(this, language);
        prefs.registerOnSharedPreferenceChangeListener(this);

        getPreferenceManager().setSharedPreferencesMode(MODE_PRIVATE);
        getPreferenceManager().setSharedPreferencesName(OptionsUtility.PREFERENCE_NAME);

        // Load the preferences from an XML resource
        addPreferencesFromResource(R.xml.preferences);

        Preference eraseGameButton = getPreferenceManager().findPreference(OptionsUtility.PREFERENCE_ERASE_GAME);
        if (eraseGameButton != null) {
            YesNoDialogPreference yesNo = (YesNoDialogPreference)eraseGameButton;
            yesNo.setListener(this);
        }

        Preference configureKeyboardPref = getPreferenceManager().findPreference("keyconfig");
        if (configureKeyboardPref != null) {
            //KeyboardConfigDialogPreference config = (KeyboardConfigDialogPreference)configureKeyboardPref;
            //config.setPrefs(getSharedPreferences(MemodroidCoreActivity.PREFERENCE_NAME, MODE_PRIVATE));
            //config.setContext(this);
        }

    }


    public void onDialogClosed(boolean positiveResult) {
        if (positiveResult) {
            DatabaseScoreManager dbsManager = new DatabaseScoreManager(getApplicationContext());
            dbsManager.resetHighScores();
            Toast.makeText(this, R.string.toast_highScoresReset,Toast.LENGTH_SHORT).show();
        }
    }


    @Override
    public void onSharedPreferenceChanged(SharedPreferences sharedPreferences,String key) {
        restartActivity();
    }

    @Override
    protected void onStop() {
        super.onStop();
        getPreferenceScreen().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(this);
    }

    private void restartActivity() {
        Intent intent = getIntent();
        finish();
        startActivity(intent);
    }

    @Override
    public void onBackPressed() {
        finish();
    }
}
like image 144
Cisco Avatar answered Oct 03 '22 00:10

Cisco