Search code examples
androidkotlinexceptioncastingsharedpreferences

Android: Cannot read integer value from preferences with SharedPreferences getInt


In my AppSettings class I have an annotation class used to store preferences default values as follows (I use "Any" so I can use lateinit):

annotation class PrefDefValues {
    companion object {
        lateinit var TestTime: Any
        ...
    }
}

In my app startup I read all preferences default values like this:

private fun readDefaultValues(){
    PrefDefValues.TestTime = resources.getInteger(R.integer.pref_testtime_default)
    ...
}

This is my xml default values resources file:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <integer name="pref_testtime_default">5</integer>
    ...
</resources>

In one of my classes I try to read the preference as follows:

val sharedPref = PreferenceManager.getDefaultSharedPreferences(this)
val timerPreference = sharedPref.getInt(TMSettings.TESTTIME.key, PrefDefValues.TestTime as Int)

but it crashes with

java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Integer

I'm stuck and I cannot understand why it complains. The PrefDefValues.TestTime returns an Integer, not a String, and in sharedPrefs I'm using the method getInt, so at first they both match.

If I do:

val timerPreference = sharedPref.getString(TMSettings.TESTTIME.key, PrefDefValues.TestTime.toString())!!.toInt()

then it works just fine, but I found it ridiculous to have to cast to string and then to int again (what I need then is an Integer.

Edit 1: Extra info

This is my preferences.xml:

<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
                  xmlns:app="http://schemas.android.com/apk/res-auto">
    <PreferenceCategory
        android:key="pref_category_test"
        android:title="@string/pref_category_test"
        app:iconSpaceReserved="false">
        <ListPreference
            android:key="pref_testtime"
            android:title="@string/pref_testtime"
            android:entries="@array/testtime_texts"
            android:entryValues="@array/testtime_values"
            android:defaultValue="@integer/pref_testtime_default"
            app:iconSpaceReserved="false" />
        ...
</PreferenceScreen>

Solution

  • OK, @Ivo pointed me in the right direction (thanks for that).

    If you see my preferences.xml (posted in my question) you'll notice I read the values from an array.

    This is the relevant part in my arrays file where I store the values:

    <string-array name="testtime_values">
        <item>1</item>
        <item>2</item>
        <item>3</item>
        <item>5</item>
        <item>-1</item>
    </string-array>
    

    I am currently using string-array, but after I changed to integer-array everything started to work as expected.