3

EDIT I forgot a hunk of code. Inserted at right here.

  @Override
  public boolean onOptionsItemSelected(MenuItem item) {
    Log.w("Before switch", (String) item.getTitle());
    switch (item.getItemId()) {
      case R.id.menu_settings:
        Log.w("Before intent","\n");
        Intent intent = new Intent(this, SettingsActivity.class);
        startActivity(intent);
        Log.w("back from intent", "\n");
        preferences = getSharedPreferences(SETTINGS, MODE_PRIVATE);
        focusAtClue = preferences.getBoolean("focus",true);
        screenSaver = preferences.getBoolean("screen",true);
        Log.w("after intent", focusAtClue + " " + screenSaver);
        return true;

      default:
        Log.w("onOptItemSel","default");
        return super.onOptionsItemSelected(item);
    }
  }
}

The onCreate code here works to create the preferences, as shown in the pic. The xml in preferences.xml is inserted as a comment. It's also included below, intact.

The preferences are stored under the keys focus and screen. Right?

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    preferences = getSharedPreferences(SETTINGS, MODE_PRIVATE);
    boolean firstUse = preferences.getBoolean(FIRST_USE, true);
    if (firstUse){
      Toast helloMessage = Toast.makeText(getApplicationContext(), "Hello First Time User",Toast.LENGTH_LONG);
      helloMessage.show();
      editor = preferences.edit();
      editor.putBoolean(FIRST_USE, false);
      editor.putBoolean  ("focus", false);
/*NOTE THE MATCHED STRING  vvvvv
      <CheckBoxPreference
              android:key="focus"   android:title="@string/focusAfterShow" android:summary="Always place the cursor" android:defaultValue="false"/> */
      editor.putBoolean  ("screen", false);
/*NOTE THE MATCHED STRING  vvvvvv
      <CheckBoxPreference
              android:key="screen"  android:title="@string/screenSaver" android:summary="Keep screen on" android:defaultValue="false" /> */
          editor.commit();
    }
    else {
    ///////////////////// problems here *******************
      SharedPreferences preferences = getSharedPreferences(SETTINGS, MODE_PRIVATE);
      focusAtClue = preferences.getBoolean("focus",focusAtClue);
      screenSaver = preferences.getBoolean("screen",screenSaver);
      Log.w("oncreate:", focusAtClue + " " + screenSaver);
    ///////////////////// problems 
    }
  }

preferences.xml:

<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
    <PreferenceCategory
        android:title="Screen options">
        >
        <CheckBoxPreference
            android:key="focus"
            android:title="@string/focusAfterShow"
            android:summary="Always place the cursor at the 'clue' (sum) after tapping 'Show'."
            android:defaultValue="false"
            />
        <CheckBoxPreference
            android:key="screen"
            android:title="@string/screenSaver"
            android:summary="Keep screen on at all times while running this app."
            android:defaultValue="false"
            />
    </PreferenceCategory>
</PreferenceScreen>

After leaving the app for the home screen and then returning to it, there has been no change in prefs, as shown in the logcat.

Then I change the first pref by checking its box. The logcat shows that correctly. The code involved is in SettingsFragment.java:

package com.bffmedia.hour11app;

import android.content.SharedPreferences;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.os.Bundle;
import android.preference.PreferenceFragment;
import android.util.Log;

public class SettingsFragment extends PreferenceFragment implements OnSharedPreferenceChangeListener {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        addPreferencesFromResource(R.xml.preferences);
    }
  @Override
    public void onResume() {
        super.onResume();
        getPreferenceScreen().getSharedPreferences().registerOnSharedPreferenceChangeListener(this);
    }
  @Override
    public void onPause() {
        super.onPause();
        getPreferenceScreen().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(this);
    }
    @Override
    public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {    
       //SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(getActivity());
       Log.w("onSharedPrefChgd", sharedPreferences.getBoolean("focus",false) + " " + sharedPreferences.getBoolean("screen",false));
       }
    }

Then I remove the app from the list of apps in memory and then run it from the apps icon.

onCreate says both values are FALSE, but only the first is.

Here's the logcat with only the lines that I wrote via Log.w. There are 3 groups to look at: creation of prefs and changing the first pref, which worked fine. And then the 2nd onCreate, where both values are said to be false, which is wrong--first is true--but the settings screen shows that I did check the first box.

I am clueless as to what I've done wrong.

05-16 13:25:20.290  18778-18778/com.bffmedia.hour11app W/Before switch? Settings
05-16 13:25:20.291  18778-18778/com.bffmedia.hour11app W/Before intent? [ 
05-16 13:25:20.292   438:0x1a07 I/ActivityManager ]
    START u0 {cmp=com.bffmedia.hour11app/.SettingsActivity} from pid 18778
05-16 13:25:20.449  18778-18778/com.bffmedia.hour11app W/back from intent? 
05-16 13:25:20.450 18778:0x495a W/after intent ]
    false false ***************************** CORRECT ************************



05-16 13:35:16.717  18778-18778/com.bffmedia.hour11app W/onSharedPrefChgd? 
     true false *********************************** CORRECT



05-16 13:37:21.185  20014-20014/com.bffmedia.hour11app W/Before switch? Settings
05-16 13:37:21.186  20014-20014/com.bffmedia.hour11app W/Before intent? [ 
05-16 13:37:21.188   438:0x2ef I/ActivityManager ]
    START u0 {cmp=com.bffmedia.hour11app/.SettingsActivity} from pid 20014
05-16 13:37:21.245  20014-20014/com.bffmedia.hour11app W/back from intent? [ 
05-16 13:37:21.245 20014:0x4e2e W/after intent ]
    false false *************************************** WHY? *******************************************

enter image description here enter image description here

DSlomer64
  • 4,234
  • 4
  • 53
  • 88

1 Answers1

2

The problem here is that you're not looking in the correct preferences xml file. The preferences from your PreferenceFragment is being saved to the default preferences xml file, and in your MainActivity, since you are using getSharedPreferences(SETTINGS, MODE_PRIVATE), that creates a new file in addition to the default preference xml file.

In order to fix it, just change that code to PreferenceManager.getDefaultSharedPreferences(this), and then you will be looking in the same preference xml file that the PreferenceFragment uses.

More info here.... and also here.....

Here is all you need to do to fix it, I just tested it and it works!

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //preferences = getSharedPreferences(SETTINGS, MODE_PRIVATE);
        //use this instead:
        preferences = PreferenceManager.getDefaultSharedPreferences(this);

        boolean firstUse = preferences.getBoolean(FIRST_USE, true);
        if (firstUse){
            Toast helloMessage = Toast.makeText(getApplicationContext(), "Hello First Time User",Toast.LENGTH_LONG);
            helloMessage.show();
            editor = preferences.edit();
            editor.putBoolean(FIRST_USE, false);
            editor.putBoolean  ("focus", false);
/*NOTE THE MATCHED STRING  vvvvv
      <CheckBoxPreference
              android:key="focus"   android:title="@string/focusAfterShow" android:summary="Always place the cursor" android:defaultValue="false"/> */
            editor.putBoolean  ("screen", false);
/*NOTE THE MATCHED STRING  vvvvvv
      <CheckBoxPreference
              android:key="screen"  android:title="@string/screenSaver" android:summary="Keep screen on" android:defaultValue="false" /> */
            editor.commit();
        }
        else {
            ///////////////////// problems here *******************
            //no need to create another preferences, it's already defined above
            //SharedPreferences preferences = getSharedPreferences(SETTINGS, MODE_PRIVATE);

            //This should work now!!!!!!
            focusAtClue = preferences.getBoolean("focus",focusAtClue);
            screenSaver = preferences.getBoolean("screen",screenSaver);
            Log.w("oncreate:", focusAtClue + " " + screenSaver);
            Toast helloMessage = Toast.makeText(getApplicationContext(), "Hello Returning User " + focusAtClue + " " + screenSaver,Toast.LENGTH_LONG);
            helloMessage.show();
            ///////////////////// problems
        }
    }

One more thing to note, it looks like this code below is not going to behave as you think it will. The execution of this code is not going to pause at the call to startActivity(), it will just continue on. So, your logs here will reflect the state of the SharedPreference before the Settings Activity opens, not after.

Also, you should use the default shared preference here as well.

Intent intent = new Intent(this, SettingsActivity.class);
startActivity(intent);
Log.w("back from intent", "\n");
//preferences = getSharedPreferences(SETTINGS, MODE_PRIVATE);
preferences = PreferenceManager.getDefaultSharedPreferences(this);
focusAtClue = preferences.getBoolean("focus",true);
screenSaver = preferences.getBoolean("screen",true);
Log.w("after intent", focusAtClue + " " + screenSaver);
return true;
Community
  • 1
  • 1
Daniel Nugent
  • 43,104
  • 15
  • 109
  • 137
  • @Daniel--Funny... I just woke up and implemented your suggestions before the edit. THANKS. I clearly do NOT understand even now, but it DID WORK for me. I even added a `Button` to tell me the preferences at any time and IT WORKS TOO. Now to read your edit. – DSlomer64 May 17 '15 at 00:37
  • 1
    @DSlomer64 No problem! Well, it would have worked halfway before, as you were writing default values for `FIRST_USE`, `focus`, and `screen` preferences to one file, but then your Settings Activity was writing to a different preference file (the default file) for changes made to `focus`, and `screen`. Since it doesn't look like there's a need for you to have multiple preference files, just use `PreferenceManager.getDefaultSharedPreferences(this)` for all preferences, and you'll be good to go! – Daniel Nugent May 17 '15 at 00:43
  • 1
    I removed the code from `Log.w("back...` through the next `Log`. I had already read your edit and that is what prompted me to say that I do not understand, but it's better thanks to you. – DSlomer64 May 17 '15 at 00:49
  • --That last comment did it, I think. I had the wrong idea about get DEFAULT shared prefs. You're right. I don't need two pref files. Thanks yet again. – DSlomer64 May 17 '15 at 00:51
  • @DSlomer64 No problem at all! Glad it's working for you now! – Daniel Nugent May 17 '15 at 00:51
  • --OK! I applied what you taught me to my actual app, and NOW IT WORKS. I DO get it. FINALLY. SHeeesshhh!! I mean, really--how hard could it be?? – DSlomer64 May 17 '15 at 01:30