8

I have a preferences.xml which contains the following definition:

<ListPreference
    android:title="@string/LimitSetting"
    android:summary="@string/LimitSettingText"
    android:key="limitSetting"
    android:defaultValue="10"
    android:entries="@array/limitArray"
    android:entryValues="@array/limitValues" />

and with values defined as follows:

<string-array name="limitArray">
    <item>1 %</item>
    <item>3 %</item>
    <item>5 %</item>
    <item>10 %</item>
    <item>20 %</item>
</string-array>
<string-array name="limitValues">
    <item>1</item>
    <item>3</item>
    <item>5</item>
    <item>10</item>
    <item>20</item>
</string-array>

which is being called in an activity as follows:

SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
int offsetProgressInitial = sharedPref.getInt("limitSetting", 10);

So far so good, but when the code gets actually called I get this error:

Caused by: java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Integer
at android.app.SharedPreferencesImpl.getInt(SharedPreferencesImpl.java:239)
at com.test.app.NewEntryActivity.onCreate(NewEntryActivity.java:144)
at android.app.Activity.performCreate(Activity.java:5977)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1105)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2258)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2365) 
at android.app.ActivityThread.access$800(ActivityThread.java:148) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1283) 

This error does not make any sense to me. The list only contain values that can be converted into an int, and the default values given in the xml file and in the code also represents just a number. So why do I get this error, and how to fix it?

6
  • 2
    For your limitValues does it allow you to use an integer-array instead? Commented Jan 26, 2016 at 19:36
  • Ah it does. The tutorial I used must have missed this tiny bit of very important infprmation... What do I have to change on the xml file then? Ins' the value still a string: android:defaultValue="10"? Commented Jan 26, 2016 at 19:40
  • Good question. Try it out and see if it works. Maybe you still can't use integer-array. Commented Jan 26, 2016 at 19:42
  • I still get the same error even with an integer-array... Commented Jan 26, 2016 at 19:42
  • It was worth a shot...I posted an answer that should work for you. Commented Jan 26, 2016 at 19:43

3 Answers 3

7

If you look at what getInt() does internally you will see the problem:

Integer v = (Integer)mMap.get(key);

Your key "limitSetting" is returning a String which cannot be cast to an Integer.

You can parse it yourself however:

int offsetProgressInitial = Integer.parseInt(sharedPref.getString("limitSetting", "10"));
7
  • 4
    That works - but does that mean the class SharedPreferences has a bug? Or is the method getInt just for decoration or to confuse android beginners? Commented Jan 26, 2016 at 19:48
  • It is not a bug and by design although it can be confusing. If you look at the documentation for the method it says, "Throws ClassCastException if there is a preference with this name that is not an int." Commented Jan 26, 2016 at 19:49
  • 1
    However, if getInt does not work with an integer-array, how to use getInt at all? There must be a case when I could use getInt, otherwise, if I have only can get a string which I need to convert, a method named getInt does not make any sense... Commented Jan 26, 2016 at 19:58
  • Are you sure it was failing in the same location and not somewhere else when you tried integer-array? You were probably right when you said it won't like the android:defaultValue="10" with an integer-array in use. Commented Jan 26, 2016 at 20:01
  • 1
    There is a long time issue reported on this...code.google.com/p/android/issues/detail?id=2096 Commented Jan 26, 2016 at 20:03
1

First let's have a look at SharedPreferences.getInt() method.

public abstract int getInt (String key, int defValue)

  • Added in API level 1
  • Retrieve an int value from the preferences.

Parameters

  1. key : The name of the preference to retrieve.
  2. defValue : Value to return if this preference does not exist.

Returns : Returns the preference value if it exists, or defValue. Throws ClassCastException if there is a preference with this name that is not an int.

So in your case, all the entry values have been defined as a string array. Therefore the class cast exception will be thrown.

You can simply solve this problem by modifying your code as follows.

SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
int offsetProgressInitial = Integer.parseInt(sharedPref.getString("limitSetting", "10"));
2
  • The documentation seems to be incorrect. I still get the error, even when I use getInt and I specify an integer-array instead of a string-array in the array.xml. Commented Jan 26, 2016 at 20:01
  • Let me reproduce the issue and check. Commented Jan 26, 2016 at 20:12
0

The problem is that if putInt was never called then getInt will return a null value, even if you set a default integer value.

This seems to be a bug that was never fixed. So the solution is to call the putInt before calling getInt.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.