0

I'm working on android project that has an activity for app settings using "SharedPreferences" allowing user to select locale from list of locales.

When I use "listPreferences.setvalue()" to set the default selected value based on current Locale the SettingsActivity is created two times!!

The following is my code:

private void setLanguagePrefDefaultValues() {
    // Current Locale
    Locale sysLocale = getResources().getConfiguration().locale;
    // Language Preference
    ListPreference languagePref = (ListPreference) findPreference(getString(R.string.pref_language_key));
    // Edit Preference Summary
    languagePref.setSummary(sysLocale.getDisplayName(sysLocale));

    // Set Language Preference to Current Locale
    if (sysLocale.getCountry() != "") {
        languagePref.setValue(sysLocale.getLanguage() + "_" + sysLocale.getCountry());

    } else {
        languagePref.setValue(sysLocale.getLanguage());
    }
}

This methode is called from onCreate() method

I note that when "setSummary(...)" method is called there is no problem but the problem arises when the "setValue()" is called

The Settings Activity Class:

import java.util.Locale;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.res.Configuration;
import android.os.Bundle;
import android.preference.ListPreference;
import android.preference.Preference;
import android.preference.PreferenceActivity;
import android.preference.PreferenceCategory;
import android.view.View;
import android.view.Window;
import android.widget.TextView;
import com.telephoenic.simgateway.R;

/**
* Settings Activity
* 
* @author Abd Alrahman Shoman
* @since September 2013
* @version 1.0.0
* 
*/
public class SettingsActivity extends PreferenceActivity implements
    SharedPreferences.OnSharedPreferenceChangeListener {

public static boolean updatedLocale = false;

@Override
public void onCreate(Bundle savedInstanceState) {
    requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);
    super.onCreate(savedInstanceState);
    addPreferencesFromResource(R.xml.settings_pref_file);
    getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE,
            R.layout.custom_title_bar);

    TextView title = (TextView) findViewById(R.id.textView_titleBar_title);
    title.setText(getResources()
            .getString(R.string.title_activity_settings));

    getPreferenceScreen().getSharedPreferences()
            .registerOnSharedPreferenceChangeListener(this);

    hideFirstLaunchPref();
    setLanguagePrefDefaultValues();
    setProfileEditPrefIntent();

}

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

@Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences,
        String key) {
    if (key.equals(getString(R.string.pref_language_key))) {
        Locale locale = null;
        String languageCode =     sharedPreferences.getString(getString(R.string.pref_language_key), "");
        if (languageCode.length() > 2) {
            char ch3 = languageCode.charAt(2);
            if (ch3 == '_') {
                String language = languageCode.substring(0, 2);
                String country = languageCode.substring(3, 5);
                locale = new Locale(language, country);
            }
        } else {
            locale = new Locale(languageCode);
        }

        Configuration config = new Configuration();
        config.locale = locale;
        getApplicationContext().getResources().updateConfiguration(config,
                getBaseContext().getResources().getDisplayMetrics());
        refresh();
        updatedLocale = true;
    }
}

/**
 * Hide FirstLaunchPref from preference screen
 * 
 */
private void hideFirstLaunchPref() {
    // First Launch Preference
    PreferenceCategory firstlaunchPref = (PreferenceCategory) findPreference(getString(R.string.pref_app_first_launch));
    // Hide First Launch Preference
    getPreferenceScreen().removePreference(firstlaunchPref);
}

/**
 * Set LanguagePref default Values (summary, selected language)
 * 
 */
private void setLanguagePrefDefaultValues() {
    // Current Locale
    Locale sysLocale = getResources().getConfiguration().locale;
    // Language Preference
    ListPreference languagePref = (ListPreference)   findPreference(getString(R.string.pref_language_key));
    // Edit Preference Summary
    languagePref.setSummary(sysLocale.getDisplayName(sysLocale));

    // Set Language Preference to Current Locale
    if (sysLocale.getCountry() != "") {
        languagePref.setValue(sysLocale.getLanguage() + "_" + sysLocale.getCountry());

    } else {
        languagePref.setValue(sysLocale.getLanguage());
    }
}

/**
 * Set ProfileEditPref Intent
 * 
 */
private void setProfileEditPrefIntent() {
    // Start PoS Profile Activity onClick
    Preference profile = (Preference) findPreference(getString(R.string.pref_profile_edit_key));
    profile.setIntent(new Intent(SettingsActivity.this,
            PosProfileActivity.class));
}

/**
 * Restart activity to reflect locale change
 * 
 */
private void refresh() {
    Intent intent = getIntent();
    overridePendingTransition(0, 0);
    intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
    finish();

    overridePendingTransition(0, 0);
    startActivity(intent);
}

/**
 * Back to previous activity
 * 
 * @param View
 *            v
 */
public void back(View v) {
    finish();
}

}

  • I am not sure what you mean by SettingsActivity is called twice. Btw for string comparison always use equals: sysLocale.getCountry().equals("") or sysLocale.getCountry().isEmpty() – cYrixmorten Sep 29 '13 at 09:56
  • as far as I can tell your code never calls SettingsActivity, so I think you mean something else than you wrote in the title of your question. – cYrixmorten Sep 29 '13 at 09:59
  • Thanks cYrixmorten for your advice about string comparison. "SettingsActivity" is the activity that responsible for creating preferences screen and "setLanguagePrefDefaultValues()" is called from its "onCreate()" method. I think "SettingsActivity" implicitly duplicated when I call "languagePref.setValue(...)" method such that I have to press back button twice if I want to get back to previous activity!! – Abd Alrahman Shoman Sep 29 '13 at 13:10
  • That is weird. Cannot spot any reason why setLanguagePrefDefaultValues() should be responsible for this. Is SettingsActivity too big to add here to get the complete picture? – cYrixmorten Sep 29 '13 at 13:14
  • ok I'll add the whole Setting Activity class – Abd Alrahman Shoman Sep 29 '13 at 13:17

1 Answers1

0

Try comment away your refresh() method.

onSharedPreferenceChanged will get called when you enter the SettingsActivity.

Also I do not see the need for this refresh() method.

If this does not work I will look more into it.

This must be the reason.. looked it over again:

@Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences,
    String key) {
    if (key.equals(getString(R.string.pref_language_key))) {
       ... // this is called when setLanguagePrefDefaultValues() sets value
       refresh()
    }
}

private void refresh() {
    // start a new SettingsActivity, why you do this in the first place, I do not know 

    Intent intent = getIntent();
    overridePendingTransition(0, 0);
    intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
    finish();

    overridePendingTransition(0, 0);
    startActivity(intent);
}

Try rewriting your refresh method to:

private void refresh() {
    // ok it is to reflect the language update, i see :)

    Intent intent = getIntent();
    overridePendingTransition(0, 0);
    intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION | Intent.FLAG_ACTIVITY_NO_HISTORY);
    startActivity(intent);
    finish();

}

Otherwise see: [Removing an activity from the history stack

[1]: Removing an activity from the history stack for more options to remove current Activity from backstack.

Community
  • 1
  • 1
cYrixmorten
  • 7,110
  • 3
  • 25
  • 33
  • actually the "refresh" method is for reflecting the locale change on the preferences screen once it's changed (redisplay the view with new locale). And I did comment it and yes you're right the problem didn't appear, but it disappear when you comment the "setValue(...)" and keep the "refresh" method. I'm sorry that I didn't mentioned that the problem appears just when the application runs for the first time(at first app launch) !!!. Thank you cYrixmorten I appreciate your concern – Abd Alrahman Shoman Sep 29 '13 at 17:21
  • Ok now I better understand the reasoning behind it. Updated the answer. – cYrixmorten Sep 29 '13 at 17:34