Mr2uang
Mr2uang

Reputation: 55

java.lang.Integer cannot be cast to java.lang.String on addPreferencesFromResource

I have an example about Preferences like this:

public class UserPreferences extends PreferenceActivity {
    @Override
    public void onCreate(Bundle saveInstanceState){
        super.onCreate(saveInstanceState);
        getFragmentManager().beginTransaction().replace(android.R.id.content, new MynewFracment()).commit();
    }
    public static class MynewFracment extends PreferenceFragment{
        @Override
        public void onCreate(Bundle saveInstanceState){
            super.onCreate(saveInstanceStates);
            addPreferencesFromResource(R.xml.userpreference);
        }
    }
}

But the result return is java.lang.Integer cannot be cast to java.lang.String on the line addPreferencesFromResource(R.xml.userpreferences); . I really don't know what did I do wrong here?


Update 1

<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
    <CheckBoxPreference
        android:key="PREF_AUTO_UPDATE"
        android:title="Auto refresh"
        android:summary="Select to turn on automatic updateing"
        android:defaultValue="true"
        ></CheckBoxPreference>
    <ListPreference
        android:key="PREF_UPDATE_FREQ"
        android:title="Refresh frequency"
        android:summary="Frequency at which to refresh earthquake list"
        android:entries="@array/update_freq_option"
        android:entryValues="@array/update_freq_values"
        android:dialogTitle="Refresh frequency"
        android:defaultValue="60"
        ></ListPreference>
    <ListPreference
        android:key="PREF_MIN_MAG"
        android:title="Minimum magnitude"
        android:summary="Select the minimum magnitude earthquake to report"
        android:entries="@array/magnitude_options"
        android:entryValues="@array/magnitude"
        android:dialogTitle="Magnitude"
        android:defaultValue="3"
        ></ListPreference>
</PreferenceScreen>

Update 2

My R.values

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string-array name="update_freq_option">
        <item>Every Minutes</item>
        <item>5 mins</item>
        <item>10 mins</item>
        <item>15 mins</item>
        <item>Every Hours</item>
    </string-array>

    <array name="magnitude">
        <item>3</item>
        <item>5</item>
        <item>6</item>
        <item>7</item>
        <item>8</item>
    </array>

    <string-array name="magnitude_options">
        <item>3</item>
        <item>5</item>
        <item>6</item>
        <item>7</item>
        <item>8</item>
    </string-array>

    <array name="update_freq_values">
        <item>1</item>
        <item>5</item>
        <item>10</item>
        <item>15</item>
        <item>60</item>
    </array>
</resources>

And my stacktrace

E/AndroidRuntime: FATAL EXCEPTION: main
                                                                     java.lang.RuntimeException: Unable to start activity ComponentInfo{com.begood.earthquake/com.begood.earthquake.UserPreferences}: java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String
                                                                         at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2059)
                                                                         at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2084)
                                                                         at android.app.ActivityThread.access$600(ActivityThread.java:130)
                                                                         at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1195)
                                                                         at android.os.Handler.dispatchMessage(Handler.java:99)
                                                                         at android.os.Looper.loop(Looper.java:137)
                                                                         at android.app.ActivityThread.main(ActivityThread.java:4745)
                                                                         at java.lang.reflect.Method.invokeNative(Native Method)
                                                                         at java.lang.reflect.Method.invoke(Method.java:511)
                                                                         at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
                                                                         at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
                                                                         at dalvik.system.NativeStart.main(Native Method)
                                                                      Caused by: java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String
                                                                         at android.app.SharedPreferencesImpl.getString(SharedPreferencesImpl.java:205)
                                                                         at android.preference.Preference.getPersistedString(Preference.java:1399)
                                                                         at android.preference.ListPreference.onSetInitialValue(ListPreference.java:278)
                                                                         at android.preference.Preference.dispatchSetInitialValue(Preference.java:1315)
                                                                         at android.preference.Preference.onAttachedToHierarchy(Preference.java:1127)
                                                                         at android.preference.PreferenceGroup.addPreference(PreferenceGroup.java:156)
                                                                         at android.preference.PreferenceGroup.addItemFromInflater(PreferenceGroup.java:97)
                                                                         at android.preference.PreferenceGroup.addItemFromInflater(PreferenceGroup.java:38)
                                                                         at android.preference.GenericInflater.rInflate(GenericInflater.java:488)
                                                                         at android.preference.GenericInflater.inflate(GenericInflater.java:326)
                                                                         at android.preference.GenericInflater.inflate(GenericInflater.java:263)
                                                                         at android.preference.PreferenceManager.inflateFromResource(PreferenceManager.java:269)
                                                                         at android.preference.PreferenceFragment.addPreferencesFromResource(PreferenceFragment.java:278)
                                                                         at com.begood.earthquake.UserPreferences$MynewFracment.onCreate(UserPreferences.java:20)
                                                                         at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:796)
                                                                         at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1035)
                                                                         at android.app.BackStackRecord.run(BackStackRecord.java:635)
                                                                         at android.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1397)
                                                                         at android.app.Activity.performStart(Activity.java:5017)
                                                                         at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2032)
                                                                         at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2084) 
                                                                         at android.app.ActivityThread.access$600(ActivityThread.java:130) 
                                                                         at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1195) 
                                                                         at android.os.Handler.dispatchMessage(Handler.java:99) 
                                                                         at android.os.Looper.loop(Looper.java:137) 
                                                                         at android.app.ActivityThread.main(ActivityThread.java:4745) 
                                                                         at java.lang.reflect.Method.invokeNative(Native Method) 
                                                                         at java.lang.reflect.Method.invoke(Method.java:511) 
                                                                         at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786) 
                                                                         at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553) 
                                                                         at dalvik.system.NativeStart.main(Native Method) 

Upvotes: 1

Views: 2863

Answers (3)

soggypants
soggypants

Reputation: 425

My problem was manually doing putInt in overrided PreferenceChangeListener. When I switched to storing String and later parsing that string to integer, no problems anymore.

Upvotes: 0

njzk2
njzk2

Reputation: 39386

As you can see from the stacktrace, when you call addPreferencesFromResource, the prefs are loaded, and onSetInitialValue is called to set the value of the pref to whatever was saved before, if at all.

Because it is a ListPreference, it uses getPersistedString, which tries to load a String.

This throws a ClassCastException because the pref used to be of an Integer type, and was saved as such.

You know have an existing version of your preferences on the device that is not compatible with the new version of your application.

To solve this, clear the app data, or simply uninstall it.

If you can't do that (if you have users that have the previous version of the app), you need a migration strategy, and probably to change the name of the new preference to avoid conflicts like this one.

Upvotes: 5

Doug Stevenson
Doug Stevenson

Reputation: 317362

Unfortunately, you have to use a string-array for the values as well, even though they are taken to be integers.

<string-array name="magnitude">
    <item>3</item>
    <item>5</item>
    <item>6</item>
    <item>7</item>
    <item>8</item>
</string-array>

<string-array name="update_freq_values">
    <item>1</item>
    <item>5</item>
    <item>10</item>
    <item>15</item>
    <item>60</item>
</string-array>

Upvotes: 1

Related Questions