2

I have a MainActivity and a PreferenceActivity that is called from that Activity. I also have a Service running that queries for those preferences.

When I print those values. I get this:

D/pref_scrobble(4083): true
D/pref_show_notification(4083): true
D/pref_scrobble_only_on_wifi(4083): false
D/pref_scrobble_percentage(4083): 50

Then I open PreferenceActivity. This gets printed:

D/pref_scrobble(4083): true
D/pref_show_notification(4083): true
D/pref_scrobble_only_on_wifi(4083): false
D/pref_scrobble_percentage(4083): 50

I change pref_scrobble_percentage to 7, then force the printing

D/pref_scrobble(4083): true
D/pref_show_notification(4083): true
D/pref_scrobble_only_on_wifi(4083): false
D/pref_scrobble_percentage(4083): 50

I close the PreferenceActivity, then force printing:

D/pref_scrobble(4083): true
D/pref_show_notification(4083): true
D/pref_scrobble_only_on_wifi(4083): false
D/pref_scrobble_percentage(4083): 50

I close the MainActivity, then force printing:

D/pref_scrobble(4083): true
D/pref_show_notification(4083): true
D/pref_scrobble_only_on_wifi(4083): false
D/pref_scrobble_percentage(4083): 50

I kill the app, then force printing:

D/pref_scrobble(4083): true
D/pref_show_notification(4083): true
D/pref_scrobble_only_on_wifi(4083): false
D/pref_scrobble_percentage(4083): 7

Why are the preferences getting saved when the app is killed instead of when I change their values or close the PreferenceActivity?

EDIT Ok, posting relevant code.

Querying the prefs is done like this:

public static boolean getScrobbleEnabled(final Context ctx) {
        final String key = ctx.getString(R.string.pref_scrobble);
        final SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(ctx);
        printPrefs(settings);
        return settings.getBoolean(key, true);
    }

private static void printPrefs(final SharedPreferences settings) {
    Map<String, ?> map = settings.getAll();
    for (String str : map.keySet()) {
        Log.d(str, map.get(str).toString());
    }
}

The xml which I inflate on the PreferenceActivity is this:

<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" >

    <PreferenceCategory android:title="@string/scrobbler_conf" >
        <CheckBoxPreference
            android:defaultValue="true"
            android:key="@string/pref_scrobble"
            android:summary="@string/enable_scrobbling_subtitle"
            android:title="@string/enable_scrobbling" />
        <CheckBoxPreference
            android:defaultValue="true"
            android:dependency="@string/pref_scrobble"
            android:key="@string/pref_show_notification"
            android:summary="@string/show_notification_subtitle"
            android:title="@string/show_notification" />

        <com.garli.lastfm.controller.preferences.SeekBarPreference
            android:defaultValue="50"
            android:dependency="@string/pref_scrobble"
            android:key="@string/pref_scrobble_percentage"
            android:max="100"
            android:summary="@string/scrobble_percentage_subtitle"
            android:title="@string/scrobble_percentage" />

        <CheckBoxPreference
            android:defaultValue="false"
            android:dependency="@string/pref_scrobble"
            android:key="@string/pref_scrobble_only_on_wifi"
            android:summary="@string/scrobble_only_on_wifi_subtitle"
            android:title="@string/scrobble_only_on_wifi" />
    </PreferenceCategory>
    <PreferenceCategory android:title="@string/ads" >
        <Preference
            android:defaultValue="false"
            android:key="@string/pref_remove_ads"
            android:summary="@string/ads_subtitle"
            android:title="@string/ads" />
    </PreferenceCategory>
    <PreferenceCategory android:title="@string/about" >
        <Preference
            android:key="pref_version"
            android:title="@string/version" />
    </PreferenceCategory>

</PreferenceScreen>

Those preferences are handled by default. Changing CheckBoxPreferences doesn't work either.

Charlie-Blake
  • 10,832
  • 13
  • 55
  • 90
  • Without seeing the **relevant** code, how are we supposed to guess? – Simon Mar 04 '14 at 21:54
  • I hope you have enough relevant code now :) – Charlie-Blake Mar 04 '14 at 21:59
  • OK, point taken ;). This is weird. +1 to attract more attention! – Simon Mar 04 '14 at 22:05
  • So, I've been doing my research. My actual question can be resumed to: How the f*** do I persist my PreferenceActivity preferences to the APPLICATION context instead of the Activity context? – Charlie-Blake Mar 04 '14 at 22:08
  • Are you saying that you have found somewhere that using an Activity context causes the problem you are seeing? Do you have a link? – Simon Mar 04 '14 at 22:11
  • No, I am saying I cannot access to the preferences bound to the PreferenceActivity from a Service or Application context. If I can link the preferences to the Application instead of the Activity, theoretically I should be able to read them. – Charlie-Blake Mar 04 '14 at 22:13
  • Could you pass `getApplicationContext()` from the `Activity` rather than `this`? – Simon Mar 04 '14 at 22:16
  • 2
    the correct spelling of f*** is F)@#. – danny117 Mar 04 '14 at 22:26
  • I'm testing this approach and it doesn't work either. – Charlie-Blake Mar 04 '14 at 22:34
  • I don't see any commits to make the save happen. See my answer below. – danny117 Mar 04 '14 at 22:40
  • @danny117 You don't need to "committ" in a PreferenceActivity. The platform is *supposed* to autosave when a preference is modified. – Simon Mar 04 '14 at 23:02
  • I think you might need to show more code. I've used PreferenceActivity often and never had a problem. My test cases are broadly the same as yours. Can I leave the activity and see the changes on other activities and if I kill my app, do they reload correctly? – Simon Mar 04 '14 at 23:04
  • The problem is I'm loading the preferences not from an Activity, but from a Service. The ones I load from activities work as they should. – Charlie-Blake Mar 04 '14 at 23:08
  • Did you already see this similar (solved) problem? http://stackoverflow.com/questions/12889753/sharedpreference-changes-not-reflected-in-my-wallpaper-service – CodeShane Mar 06 '14 at 00:45
  • You don't need a shared pref change listener for this, but since killing the prefs act resolves it, I suggest looking through its lifecycle methods for errors, and try hard - coding at least one preference key until you get it working to rule out a resource issue. Also verifying there aren't any copy - paste errors in the keys / xml ;) – CodeShane Mar 06 '14 at 00:52
  • @Simon then maybe the relevant code that changes the preferences is at fault if you can't see the changes. – danny117 Mar 06 '14 at 04:33

2 Answers2

1

I've had this issue with a Service not seeing the preferences before, I can't remember the details but returning the SharedPreferences like this resolved it. I remember thinking it seemed odd since the Service wasn't actually in a separate process, but it fixed the problem. The documentation seems a little confusing on this flag.

public static SharedPreferences getPref(Context context)
{
    int mode = android.os.Build.VERSION.SDK_INT >= 11 ? 
                   Context.MODE_MULTI_PROCESS : 
                   Context.MODE_PRIVATE;
    return context.getSharedPreferences(SHARED_PREF_NAME, mode);
}

Also, are you inflating the XML the proper way in onCreate()?

addPreferencesFromResource(R.xml.preferences);

Check out this for changing the default shared preferences name and mode.

public class MyPreferencesActivity extends PreferenceActivity {
    protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);

         PreferenceManager prefMgr = getPreferenceManager();
         prefMgr.setSharedPreferencesName("my_preferences");
         prefMgr.setSharedPreferencesMode(MODE_MULTI_PROCESS);

         addPreferencesFromResource(R.xml.preferences);
    }
}

Let us know if you solve the problem.

Simon
  • 14,407
  • 8
  • 46
  • 61
Steve M
  • 9,296
  • 11
  • 49
  • 98
0

I use these static methods to save integer prefs for the application. This works with all my apps because I use a common R.string.app_name and activity which is a context to identify my preferences file.

I call it like this.

int x = GoPreferences.getInt(getActivity(),MAP_TYPE,GoogleMap.MAP_TYPE_NORMAL);

...

GoPreferences.putInt(getActivity(),MAP_TYPE, x);

...

//simple static preferences methods  
public class GoPreferences {

public static void putInt(Context context, String s, int b) {
    SharedPreferences sharedPref = context.getSharedPreferences(
            context.getString(R.string.app_name), Context.MODE_PRIVATE);
    sharedPref.edit().putInt(s, b).commit();
}

public static int getInt(Context context, String s, int defaultvalue) {
    defaultvalue = context.getSharedPreferences(context.getString(R.string.app_name),
            Context.MODE_PRIVATE).getInt(s, defaultvalue);
    return defaultvalue;
}
}

Good Luck

Danny117

danny117
  • 5,581
  • 1
  • 26
  • 35