Search code examples
androidsharedpreferencesandroid-sharedpreferences

SharedPreferencesChangeListener not working


SharedPrefencesChangeListener is not working in this code. Please point out if anything is missed.

I am wondering if it is happening because I have declared it in a service.

Code to change the SharedPreferences from another activity:

getSharedPreferences("TRACKER", Context.MODE_PRIVATE).edit().putString("TRIP_LIST", String.valueOf(trip_list)).apply();

///

package com.tracker;

import android.app.Service;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.IBinder;
import android.preference.PreferenceManager;
import android.support.v4.content.LocalBroadcastManager;

import org.json.JSONException;
import org.json.JSONObject;

public class SharedPrefMonService extends Service implements SharedPreferences.OnSharedPreferenceChangeListener {


    LocalBroadcastManager broadcaster = LocalBroadcastManager.getInstance(this);



    public SharedPrefMonService() {

    }

    @Override
    public IBinder onBind(Intent intent) {
        // TODO: Return the communication channel to the service.
       return null;
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
        prefs.unregisterOnSharedPreferenceChangeListener(this);
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
        prefs.registerOnSharedPreferenceChangeListener(this);
        return Service.START_STICKY;
    }

    @Override
    public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
        if(key.equals("TRIP_LIST")){
            try {
                JSONObject trip_list = new JSONObject(sharedPreferences.getString("TRIP_LIST", "{}"));

                if(trip_list.keys().hasNext()){
                    //start location service
                }else{
                    //stop location service
                }
                //update trip list view   here
                Intent intent = new Intent("SharedPrefMonService");
                intent.putExtra("updated_trip_list", trip_list.toString());
                broadcaster.sendBroadcast(intent);
            } catch (JSONException e) {
                e.printStackTrace();
            }

        }
    }
}

Solution

  • It's not that you have the listener in a Service, necessarily. You're not setting the listener on the same SharedPreferences that you're modifying.

    Context#getSharedPreferences() creates a SharedPreferences with the name you give it. PreferenceManager.getDefaultSharedPreferences() creates a SharedPreferences from your package name with _preferences appended. They're both ultimately XML files, but a listener on one won't be notified of changes on another.

    Either change the SharedPreferences you're modifying to use the default - PreferenceManager.getDefaultSharedPreferences() - or set your listener on the one you're currently saving to - getSharedPreferences("TRACKER", Context.MODE_PRIVATE).

    I would also mention that an OnSharedPreferenceChangeListener will only fire when a particular key's value changes. If you save a key with the same value it already had, onSharedPreferenceChanged() won't run.