2

I have a PreferentFragment whose content is loaded from a .xml file containing a CheckBoxPreference

    <CheckBoxPreference
          android:title="@string/pref_secure_conn"
          android:key="enable_secure_connection"
          android:defaultValue="false"/>

As you know, when the user interacts with this Preference, the SharedPreferences object is automatically updated so that the android:key now contains the proper Boolean.

However, I would like to use a String instead of a Boolean: Is there any way to make CheckBoxPreference use String-valued values instead of Boolean ones, so that I can later call getString with that key?

Currently, I am just listening 'onSharedPreferenceChanged' and manually changuing it, but maybe there is a better way. (Another obvious fix would be to use getBoolean instead of getString when this value is needed, but let's assume I cannot do that)

José D.
  • 4,175
  • 7
  • 28
  • 47
  • 1
    Yes there is a better way. Instead of saving the boolean value when you call `putBoolean` call `putString` and parse the value to string. You can simply do `myboolean + "";` – Pedro Oliveira Oct 16 '14 at 08:24
  • @PedroOliveira I do not call putBoolean nor putString as that is automatically done by the Preference (I have updated the question, hopefully it is more clear now) – José D. Oct 16 '14 at 08:38
  • Look in the preference.xml file and see that already "true" and "false" strings are used as is normal for xml. But you could change to and implement the behaviour yourself. – greenapps Oct 16 '14 at 08:46

3 Answers3

0

When you save SharedPreferences you specify it's type by calling the specific method for example:

SharedPreferences.Editor.putBoolean or SharedPreferences.Editor.putFloat or SharedPreferences.Editor.putString

If you call putBoolean the method will expect a boolean as the second parameter. However since you want to save a string you should call putString. If your variable is a boolean you need to change it to string.

Resuming:

    Boolean myBoolean = false;
    SharedPreferences sharedPref = ctx.getSharedPreferences(AppSettings.PREFERENCES_FILE, Context.MODE_PRIVATE);
    SharedPreferences.Editor editor = sharedPref.edit();
    editor.putString("myBoolean, String.valueOf(myBoolean));
    editor.apply();
Pedro Oliveira
  • 20,442
  • 8
  • 55
  • 82
  • 1
    I am not calling any of those methods, because it is being done automatically by the Preference. I have updated the question so it is more clear. – José D. Oct 16 '14 at 08:38
  • Then you will have to implement it your self. Check http://grepcode.com/file_/repository.grepcode.com/java/ext/com.google.android/android/1.6_r2/android/preference/CheckBoxPreference.java/?v=source for the `CheckBoxPreference` source code and override the necessary methods – Pedro Oliveira Oct 16 '14 at 09:03
0

The easiest way i could think of is inheriting the CheckBoxPreference and save the Preference redundant:

package com.example.preferencestest;

import android.content.Context;
import android.content.SharedPreferences;
import android.preference.CheckBoxPreference;
import android.util.AttributeSet;

public class StringCheckBoxPreference extends CheckBoxPreference {
    public StringCheckBoxPreference(Context context) { super(context); }
    public StringCheckBoxPreference(Context context, AttributeSet attrs) { super(context, attrs); }
    public StringCheckBoxPreference(Context context, AttributeSet attrs,
            int defStyle) { super(context, attrs, defStyle); }

    @Override
    public void setChecked(boolean checked) {
        super.setChecked(checked);
        SharedPreferences p = getSharedPreferences();
        SharedPreferences.Editor e = p.edit();
        e.putString(getKey()+"asString", String.valueOf(checked));
        e.apply();
    }
}

you may add this class to your PreferencesActivity xml like this:

<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" >

    <com.example.preferencestest.StringCheckBoxPreference
        android:defaultValue="true"
        android:key="myCheckBox"
        android:summary="@string/pref_description_social_recommendations"
        android:title="@string/pref_title_social_recommendations"
    />

    <CheckBoxPreference
        android:defaultValue="true"
        android:key="example_checkbox"
        android:summary="@string/pref_description_social_recommendations"
        android:title="@string/pref_title_social_recommendations" />
blender
  • 361
  • 3
  • 16
  • This is the approach I took. I am not sure if my implementation is better or worse than yours. What do you think? (I have very limited experience with Android) http://pastebin.com/rvEaAvXC – José D. Oct 16 '14 at 10:25
0

How about this:

    final String currentBooleanString = sharedPreferences.getString(
            KEY_PREF_CURRENT_BOOLEAN, "true");
    final CheckBoxPreference checkBoxPreference = new CheckBoxPreference(
            this);
    checkBoxPreference.setChecked(currentBooleanString.equals("true"));
    checkBoxPreference
            .setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {

                @Override
                public boolean onPreferenceChange(Preference preference,
                        Object newValue) {
                    if (!checkBoxPreference.isChecked()) {
                        sharedPreferences
                                .edit()
                                .putString(KEY_PREF_CURRENT_BOOLEAN,
                                        "false").commit();
                    } else {
                        sharedPreferences
                                .edit()
                                .putString(KEY_PREF_CURRENT_BOOLEAN,
                                        "true").commit();
                    }
                    return true;
                }
            });
    preferenceScreen.addPreference(checkBoxPreference);

where "KEY_PREF_CURRENT_BOOLEAN" is the key String used to save the preference in the applications SharedPreferences.

electrocrat
  • 446
  • 3
  • 8