Alex
Alex

Reputation: 91

Android Shared Preferences inside Fragment not working - Kotlin

I have spent hours researching and trying to find a solution but in vein. So here comes my first question on stackoverflow. For years I could do without having to ask my own questions because of the vast amount of topics.

Please be kind to me if I do something wrong. I will do my best to enhance in asking questions.

My problem is, that it won't store nor read data from the preferences. It says that they don't exist. I took the sample code from google for the preference screen. Inside there are many fragments. Inside one of those fragments I catch a preference click and want to change a value of one of the other preferences with it.

Following you find my code.

The problem in my opinion lies in the onPreferenceTreeClick of the AlveolPreferencesFragment.

Thanks for all your help and all the help you have given me before not knowing that you did :))

Alveol_Preferences XML

<androidx.preference.PreferenceScreen
    xmlns:app="http://schemas.android.com/apk/res-auto">
    <PreferenceCategory
        app:title="@string/heart_alveol">

        <EditTextPreference
            app:key="latitude"
            app:dialogTitle="@string/latitude_summary"
            app:useSimpleSummaryProvider="true"
            app:title="@string/latitude"
            app:defaultValue="-34.0"/>

        <EditTextPreference
            app:key="longitude"
            app:dialogTitle="@string/longitude_summary"
            app:useSimpleSummaryProvider="true"
            app:title="@string/longitude"
            app:defaultValue="151.0"/>

        <Preference
            app:key="gpsheart"
            app:title="@string/gpsheart"
            app:summary="@string/gpsheart_summary"/>
    </PreferenceCategory>

</androidx.preference.PreferenceScreen>

Class AlveolPreferencesFragment

class AlveolPreferencesFragment : PreferenceFragmentCompat() {



        override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {


            setPreferencesFromResource(R.xml.alveol_preferences, rootKey)
        }
        override fun onPreferenceTreeClick(preference: Preference): Boolean {

            return when (preference.key) {
                "gpsheart" -> {

                    var sharedPref : SharedPreferences? = activity?.getPreferences(Context.MODE_PRIVATE)
                    val editor = sharedPref?.edit()
                    editor?.putString("latitude", "Test").apply()


                    val text = sharedPref?.getString("longitude","Longitude doesn't exist")
                    val duration = Toast.LENGTH_SHORT

                    val toast = Toast.makeText(context, text, duration)
                    toast.show()



                    true
                }
                else -> {
                    super.onPreferenceTreeClick(preference)
                }
            }

        }

The AlveolPreferencesFragment class lies inside this class SettingsActivity : AppCompatActivity()

This was preconfigured by google and I have the assumption this is kind of complicated. But I don't know maybe I'm wrong.

Additional Question

This question comes on top if you want to also help me here. Inside the OnPreferenceTreeClick I want to get the last known location. This already works from my code. The only problem is, that I can't seem to put the fusedLocationClient inside the class. It won't work there.

Because inside this call:

 fusedLocationClient = LocationServices.getFusedLocationProviderClient(activity)

activity returns FragmentActivity?But it needs Activity.

So how can I get my SettingsActivity inside of this FragmentActivity?

Maybe something with companion object? I have no clue.

Thanks for the help.

Upvotes: 5

Views: 2801

Answers (3)

Muhammad Etisam Zafar
Muhammad Etisam Zafar

Reputation: 452

create an instance in the fragment like this:

protected val defaultPreferences: SharedPreferences
        get() = PreferenceManager.getDefaultSharedPreferences(activity)

Set value in default shared preferences

defaultPreferences.edit {
            putBoolean("clone_active", false)
        }

get value of default shared preference:

val sharedPrefBooleanFromDefaultPref = defaultPreferences.getBoolean("clone_active", false)

Upvotes: 0

Mick
Mick

Reputation: 25471

As an update in May 2021, PreferenceManager.getDefaultSharedPreferences appears to have been deprecated.

The Kotlin code below will work and was tested in a Dialogue Fragment:

val sharedPref = activity?.getPreferences(Context.MODE_PRIVATE)
sharedPref?.edit()?.putInt(YOUR_SHARED_PREF_STRING_INDEX_VALUE, yourValueToStore)

Upvotes: 0

Alex
Alex

Reputation: 91

After some days of searching I finally found the answer myself. I will post it here, if someone has the same problem.

In Germany we have a saying "Der Teufel steckt im Detail" ;) Which translates roughly to "The devil is in the details"

Instead of calling this function:

var sharedPref : SharedPreferences? = Activity?.getPreferences(Context.MODE_PRIVATE)

We need to call this function

val sharedPref = PreferenceManager.getDefaultSharedPreferences(context)

Then the rest works.

Upvotes: 4

Related Questions