Skip to content
This repository was archived by the owner on Feb 26, 2023. It is now read-only.
This repository was archived by the owner on Feb 26, 2023. It is now read-only.

Better handling of float/integer in preferences #503

Description

@PerfectCarl

Hello,

I'm using the @PREF annotations along with PreferenceFragment so that the built-in preference UI can publish my AA generated preferences.

It works great with string/checkbox pref (edited with : EditTextPreference / CheckBoxPreference), but there is an issue with a number (int or float).

I use a this declaration to publish my float preference :

    <EditTextPreference
        android:key="listMaxSpeed"
        android:numeric="integer"
        android:title="Max speed for list" />

When I update the value and try to use it with the Pref_ class, I get this error :

 Caused by: java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Float
    at android.app.SharedPreferencesImpl.getFloat(SharedPreferencesImpl.java:254)
    at com.googlecode.androidannotations.api.sharedpreferences.FloatPrefField.getOr(FloatPrefField.java:34)

The reason is EditTextPreference convert the value to string which is not very smart.
Of course, the Pref_ class expects a float (and rightfully so).

Would it possible to add this use case when doing :

    public float getOr(float defaultValue) {
        return sharedPreferences.getFloat(key, defaultValue);
    }

... and add a conversion from string to float if the value has been converted to a string by the (stupid) preference UI ?

Note : I can provide a patch (and tests).

Activity

  1. PerfectCarl commented on Feb 13, 2013

    @PerfectCarl
    ContributorAuthor

    Meanwhile, one solution would be to use customized preference editors.

    Like EditFloatPreference

    Here's a sample :

        <PATH_TO_NAMESPACE.EditFloatPreference
            android:key="listMaxSpeed"
            android:numeric="decimal"
            android:title="Max speed for list" />
    

    Note : more information about android:numeric

    Or even fancier, a sliding preference editor or other SeekBarPreference...

  2. pyricau commented on Feb 27, 2013

    @pyricau
    Contributor

    Could you please tell us what your patch would do ? AFAIK SharedPreferences API doesn't allow type checking.

  3. PerfectCarl commented on Dec 29, 2013

    @PerfectCarl
    ContributorAuthor

    Well the patch would be something pretty basic, like this:

        public float getOr(float defaultValue) {
            try{ 
                    return sharedPreferences.getFloat(key, defaultValue);
            }catch( ClassCastException e ){
                    // The pref could be a String, if that is the case try this 
                    // recovery bit 
                    try{ 
                            String value = sharedPreferences.getString(key, ""+defaultValue);
                            float result = Float.parseFloat(value);
                            return result ; 
                    }catch( Exception e2){
                            // our  recovery bit failed. The problem is elsewhere. Send the original error
                            throw e ; 
                    }
             }
        }
    

    (I hope this makes sense as I am not in front of compiler)

    And the same for the integer.

  4. PerfectCarl commented on Jan 2, 2014

    @PerfectCarl
    ContributorAuthor

    I updated to doc to show how to use the prefs with a PreferenceActivity

    https://github.com/PerfectCarl/androidannotations/wiki/SharedPreferencesHelpers

  5. PerfectCarl commented on Jan 3, 2014

    @PerfectCarl
    ContributorAuthor

    So the heart and soul of this issue is to have the @Prefs class and the EditTextPreference coexist nicely for numeric values (int, long and float).

    The issue is: the EditTextPreference reads and writes a string, while the typesafe @Pref uses the real numeric type.

    So even if the classCastException is handled in the Prefs's side, EditTextPreference will crash with another ClassCastException.

    Falling from Charybdis to Scylla

    So there two solutions here:

    1. @Pref writing the data as strings and converting them to the "real type" at each call
    2. Giving up on EditTextPreference and using a better suited replacement (as mentionned in my first post). The UI to input number is pretty terrible to begin with.

    I think that 2) makes more sense. Maybe adding documentation on how to use @Pref with a PreferenceActivity would be a good idea...
    In that regard, the ClassCastException is worth fixing even if the application will break when the @Pref attempts to write those number values.
    At least, we went from an issue happening on read/write cases to one that happens only when writing.

    As I said, from Charybdis to Scylla...

  6. removed this from the Someday milestone on May 4, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions