PreferenceActivity: save value as integer

You could extend EditTextPreference:

public class IntEditTextPreference extends EditTextPreference {

    public IntEditTextPreference(Context context) {
        super(context);
    }

    public IntEditTextPreference(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public IntEditTextPreference(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    @Override
    protected String getPersistedString(String defaultReturnValue) {
        return String.valueOf(getPersistedInt(-1));
    }

    @Override
    protected boolean persistString(String value) {
        return persistInt(Integer.valueOf(value));
    }
}

It would be better to overwrite onSetInitialValue() and setText() methods, but then you would have to copy some code from a base class. Above solution is simplier, but it's quite tricky - "string" methods do something with ints. Try to not extend this class further ;-)

You could use it from XML by:

<package.name.IntEditTextPreference
    android:key="SomeKey"
    android:title="@string/some_title"
    android:summary="..."
    android:numeric="integer"
    android:maxLength="2"
/>

I know this is an old question with an already accepted answer but I think my solution can be helpful for someone searching for a more complete answer. I have just improved @broot answer a litte and there goes my solution:

Override the EditTextPreference to provide text to int conversion:

public class IntEditTextPreference extends EditTextPreference implements EditTextPreference.OnBindEditTextListener {
    private String mText;
    
    public IntEditTextPreference(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        setOnBindEditTextListener(this);
    }

    public IntEditTextPreference(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        setOnBindEditTextListener(this);
    }

    public IntEditTextPreference(Context context, AttributeSet attrs) {
        super(context, attrs);
        setOnBindEditTextListener(this);
    }

    public IntEditTextPreference(Context context) {
        super(context);
        setOnBindEditTextListener(this);
    }

    /**
     * Saves the text to the current data storage.
     *
     * @param text The text to save
     */
    public void setText(String text) {
        final boolean wasBlocking = shouldDisableDependents();

        mText = text;

        int value = Integer.parseInt(text);

        persistInt(value);

        final boolean isBlocking = shouldDisableDependents();
        if (isBlocking != wasBlocking) {
            notifyDependencyChange(isBlocking);
        }

        notifyChanged();
    }

    /**
     * Gets the text from the current data storage.
     *
     * @return The current preference value
     */
    public String getText() {
        return mText;
    }

    @Override
    protected void onSetInitialValue(Object defaultValue) {
        int value;
        if (defaultValue != null) {
            String strDefaultValue = (String) defaultValue;

            int defaultIntValue = Integer.parseInt(strDefaultValue);
            value = getPersistedInt(defaultIntValue);
        } else {
            value = getPersistedInt(0);
        }

        setText(Integer.toString(value));
    }

    @Override
    public boolean shouldDisableDependents() {
        return TextUtils.isEmpty(mText) || super.shouldDisableDependents();
    }

    @Override
    public void onBindEditText(@NonNull EditText editText) {
        editText.setInputType(InputType.TYPE_CLASS_NUMBER);
    }
}

In the preferences xml:

<your.package.here.IntEditTextPreference
            android:key="some_key"
            android:title="@string/some_title"
            android:defaultValue="5"
            app:useSimpleSummaryProvider="true"/>

Note: Don't use android:numeric nor android:inputType. Since EditTextPreference is not an EditText itself setting those attributes will do nothing. In order to achieve the desired effect on the EditText from the Dialog opened by the EditTextPreference, just set the input type in your custom EditTextPreference by implementing EditTextPreference.OnBindEditTextListener as you can see in the code above.

That's what worked for me.


Even if you set android:numeric="integer" it'll be text preference - as its name suggest. You could easily convert string value to int using Integer.valueOf(). Also you could overwrite PreferenceActivity to do conversion automatically on exit.


I think the best solution is to write simple method to get this value from preferences. Something like:

public static int getSomePref(Context context) {
    SharedPreferences prefs =
        PreferenceManager.getDefaultSharedPreferences(context);
    String value = prefs.getString("SomeKey", null);
    return value == null ? -1 : Integer.valueOf(value);
}

Then you could very easily use it from your code.


Even though an Answer has been parked accepted I would like to share one more shorter way to achieve this :

SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
int value = Integer.parseInt(preferences.getString("SomeKey", "-1"));

Since you have already set that only numbers can be entered this won't through any exception. yet to complete my answer :

<EditTextPref
    android:key="SomeKey"
    android:title="@string/some_title"
    android:summary="..."
    android:numeric="integer"
    android:maxLength="2" />