21

Suppose that I have an application which saves preferences onto two files, preferences1.xml and preferences2.xml. Then, I can retrieve references to the corresponding objects with the following code:

SharedPreferences sharedPrefs1 = getSharedPreferences("preferences1", MODE_PRIVATE);
SharedPreferences sharedPrefs2 = getSharedPreferences("preferences2", MODE_PRIVATE);

In this way I can manipulate the preferences for both and register listeners for changes on both.

I have some doubts about the initialization of those two files, with setDefaultValues:

Question 1 - PreferenceFragment context: I've created a PreferenceActivity with two PreferenceFragments and within the onCreate method of each one I execute the following code (replace X with 1 and 2 for fragment 1 and 2):

PreferenceManager pm = getPreferenceManager();
pm.setSharedPreferencesName("preferencesX");

PreferenceManager.setDefaultValues(getActivity(),R.xml.preference_fragmentX, false);

I've seen that both fragments correctly set their preferences with their default values when launched.. but, given the fact that I can see only a single _has_set_default_values.xml file in the shared_prefs directory of the app, how does it understand when properties of preferences1.xml and preferences2.xml have been already set? This file is created as soon as setDefaultValues is called in the first opened PreferenceFragment, but even after that, if I open the second PreferenceFragment it correctly initializes default values. How does it understand that it has not yet initialized preferences2.xml and what is the purpose of _has_set_default_values.xml given the fact that it does not contains information about which prefereces files have been initialized?

Question 2 - Standard Activity context: when I start my app, the PreferenceActivity is not the first activity started and the user may never open it, so I'd like to initialize the two preference files with their default values also in the main Activity, how can I do that? For default shared preferences it is easy:

PreferenceManager.setDefaultValues(this, R.xml.default_preferences, false); 

For two preference files how should I do? I can not do something like the following since I can not retrieve an instance of PreferenceManager like in the PreferenceFragment classes:

PreferenceManager pm = getPreferenceManager(); // NOT AVAILABLE AND NOT WANTED
pm.setSharedPreferencesName("preferences1");
PreferenceManager.setDefaultValues(getActivity(),R.xml.preference_fragment1, false);

PreferenceManager pm = getPreferenceManager(); // NOT AVAILABLE AND NOT WANTED
pm.setSharedPreferencesName("preferences2");            
PreferenceManager.setDefaultValues(getActivity(),R.xml.preference_fragment2, false);

Here in the main Activity I do not have the need to change the preference files on which the PreferenceManager will work, since we're not in a PreferenceActivity, I simply want to initialize those two files... any help? I hope I've posted a clear question, even if too long.

Gianni Costanzi
  • 6,054
  • 11
  • 48
  • 74
  • 1
    @crazymaik I've deleted my answer as I don't think it answers the question satisfactorily. I've spent some hours looking into this by now, and it's still a complete mystery...Hope someone else can shed some light on it. – Gunnar Karlsson Nov 15 '12 at 15:19
  • can u plz explain more on SO Chat? – KOTIOS Dec 26 '13 at 07:37
  • try using a .Namespace prefix within a Single physical file to manage 2 logical sets or categories of prefs within single filehandle. Your respective fragments should be able to apply the NS prefix in a manner that is not too disruptive to your CRUD operations on the pref properties. – Robert Rowntree Dec 27 '13 at 15:28

3 Answers3

1

you can create a preference like this:

public class MyPreference {

    private static final String APP_SHARED_PREFS1 = "myPrefc1"; 
    private static final String APP_SHARED_PREFS2 = "myPrefc2"; 
    private SharedPreferences   appSharedPrefs1;
    private SharedPreferences   appSharedPrefs2;
    private Editor              prefsEditor1;
    private Editor              prefsEditor2;


    public MyPreference(Context context) {
        this.appSharedPrefs1 = context.getSharedPreferences(APP_SHARED_PREFS1, Activity.MODE_PRIVATE);
        this.appSharedPrefs2 = context.getSharedPreferences(APP_SHARED_PREFS2, Activity.MODE_PRIVATE);
        this.prefsEditor1 = appSharedPrefs1.edit();
        this.prefsEditor2 = appSharedPrefs2.edit();
    }

 public void saveServices(String servicName, boolean isActivated) {
        prefsEditor1.putBoolean(servicName, isActivated);
        prefsEditor1.commit();
        prefsEditor2.putBoolean(servicName, isActivated);
        prefsEditor2.commit();
    }

on your save service or something else you wanna do with your preference the data will save in both file.

and for your second question:

create a Global class like G

and then declare your preference like this:

public class G extends Application{

    public static Activity currentActivity = null;
    public static MyPreference myAppPref = null;


    @Override
    public void onCreate() {

        super.onCreate();

         myAppPref = new MyPreference(G.this);


    }


}

and when your main activity runs you should do like this:

G.currentActivity = MainActivity.this;
G. myAppPref.saveServices("testpref", true);
Mahdi
  • 6,139
  • 9
  • 57
  • 109
0

For Question 1

I believe the _has_set_default_values.xml file is just another preference file... and it stores key/value pairs in there with the key being the name of the preference file and the value being whether the default values have been set.

For Question 2

Why not use the version of PreferenceManager.setDefaultValues() that takes the name of the shared preferences file? This is the method signature:

public static void setDefaultValues (Context context, String sharedPreferencesName, int sharedPreferencesMode, int resId, boolean readAgain)

http://developer.android.com/reference/android/preference/PreferenceManager.html

Justin
  • 6,564
  • 6
  • 37
  • 34
-3

1) I'm guessing that those default values will only be loaded if getDefaultSharedPreferences() method is used, and will be ignored if you provide your own preferences file. Not really sure on this one.

2) You can set them up on an Application subclass.

http://developer.android.com/reference/android/app/Application.html

Application.onCreate is the first thing to be executed when the user launches your app. It's a single point of entrance to your app, and therefore, a good place to initialize all the data that your app needs system-wide.

Since Application extends ContextWrapper, you have access to the SharedPreferences through the getSharedPreferences(file, mode) method. You can use it to retrieve your two preferences files.

Robert Estivill
  • 12,369
  • 8
  • 43
  • 64