Search code examples
android-studiokotlinbroadcastreceiversharedpreferences

How do I call a SharedPreference function from my BroadcastReceiver in Kotlin


new to programming. I've made a BroadcastReciever which is triggering effectively. I need it to update SharedPreferences to save user input for the day(its set at shorter intervals right now for testing purposes). I tried to create the SharedPref function inside the Receiver, but the Receiver can't see -getSharedPreferences().

So I moved the function which does all the SharedPreference work. I have tried calling it from the extension file, and I've also tried calling it directly from an Activity. The BroadcastReceiver can't seem to see any functions in the rest of the app.

Manifest permissions and receiver '''

<uses-permission android:name="android.permission.USE_EXACT_ALARM" />
    <uses-permission android:name="android.permission.WAKE_LOCK" />
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
    <uses-permission android:name="android.permission.ACCESS_FORGROUND_SERVICE" />
...
<receiver
            android:name=".SaveReceiver"
            android:enabled="true"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED" />
            </intent-filter>
        </receiver>

'''

BroadcastReceiver '''

class SaveReceiver : BroadcastReceiver() {
    
    
    override fun onReceive(context: Context?, intent: Intent?) {
        Log.d(
            "SaveAlarmLog",
            "Save Receiver Broadcast Recieved"
        )

        shuffleMoods()
    }

    fun shuffleMoods() {
        myApp.sixDaysAgoMood = preferenceToObject(myApp.SIX_DAYS_AGO_MOOD)
        objectToPreference(myApp.sixDaysAgoMood, myApp.SEVEN_DAYS_AGO_MOOD)

        myApp.fiveDaysAgoMood = preferenceToObject(myApp.FIVE_DAYS_AGO_MOOD)
        objectToPreference(myApp.fiveDaysAgoMood, myApp.SIX_DAYS_AGO_MOOD)

        myApp.fourDaysAgoMood = preferenceToObject(myApp.FOUR_DAYS_AGO_MOOD)
        objectToPreference(myApp.fourDaysAgoMood, myApp.FIVE_DAYS_AGO_MOOD)

        myApp.threeDaysAgoMood = preferenceToObject(myApp.THREE_DAYS_AGO_MOOD)
        objectToPreference(myApp.threeDaysAgoMood, myApp.FOUR_DAYS_AGO_MOOD)

        myApp.twoDaysAgoMood = preferenceToObject(myApp.TWO_DAYS_AGO_MOOD)
        objectToPreference(myApp.twoDaysAgoMood, myApp.THREE_DAYS_AGO_MOOD)

        myApp.yesterdayMood = preferenceToObject(myApp.YESTERDAY_MOOD)
        objectToPreference(myApp.yesterdayMood, myApp.THREE_DAYS_AGO_MOOD)

        currentMood = preferenceToObject(myApp.CURRENT_MOOD)
        objectToPreference(currentMood, myApp.YESTERDAY_MOOD)

    }

    fun preferenceToObject(MOOD_DAY_PREFERENCE: String): Mood {
        myApp.moodSharedPref = getSharedPreferences(FILE_NAME, AppCompatActivity.MODE_PRIVATE)

        val moodJsonString = myApp.moodSharedPref.getString(MOOD_DAY_PREFERENCE, null)
        myApp.dayMoodObject = Gson().fromJson<Mood>(moodJsonString, Mood::class.java)

        return myApp.dayMoodObject
    }

    fun objectToPreference(mood: Mood, PREFERENCE_NAME: String) {
        myApp.moodSharedPref = getSharedPreferences(FILE_NAME, MODE_PRIVATE)
        val moodSharedPrefEditor = myApp.moodSharedPref.edit()

        val moodJsonString = Gson().toJson(mood)

        moodSharedPrefEditor.putString(PREFERENCE_NAME, moodJsonString).apply()

    }
}

''' In the above code, I put all the functions in the receiver just to show what I'm trying to do. I know it's too much to put there. In this format, the getSharedPreferences() is not recognized at all. When I put the functions in an Activity or Extension file, the function name isn't recognized here. Been going round in circles for a while.


Solution

  • Call context.getSharedPreferences(). If you need it in functions outside onReceive(), give those functions a Context parameter so it can be passed to them. The Context in onReceive is never null, so you can remove the question mark to make your code simpler (won't have to check for null).

    A lot of the functions that you are used to calling in an Activity can be found on a Context, because Activity itself is a subclass of Context.

    For example, in your case preferenceToObject and preferenceToObject need Context parameters, so you need to add them as function arguments. And so that ripples back to shuffleMoods, so that needs one too. Putting it all together:

    class SaveReceiver : BroadcastReceiver() {
    
        override fun onReceive(context: Context, intent: Intent) {
            //...
    
            shuffleMoods(context)
        }
    
        fun shuffleMoods(context: Context) {
            myApp.sixDaysAgoMood = preferenceToObject(context, myApp.SIX_DAYS_AGO_MOOD)
            objectToPreference(context, myApp.sixDaysAgoMood, myApp.SEVEN_DAYS_AGO_MOOD)
    
            //...
        }
    
        fun preferenceToObject(context: Context, MOOD_DAY_PREFERENCE: String): Mood {
            myApp.moodSharedPref = context.getSharedPreferences(FILE_NAME, AppCompatActivity.MODE_PRIVATE)
            //...
        }
    
        fun objectToPreference(context: Context, mood: Mood, PREFERENCE_NAME: String) {
            myApp.moodSharedPref = context.getSharedPreferences(FILE_NAME, MODE_PRIVATE)
            //...
        }
    }