ClemM
ClemM

Reputation: 452

Remote service & PreferenceActivity

My application contains a Service to refresh datas depending on preferences values. I also have in my application a PreferenceActivity to change these values.

My service implements OnSharedPreferenceChangeListener, get preferences and register the listener. I can get preferences values but if i change preferences in the data activity, onSharedPreferencesChanged isn't called (so datas aren't updated).

Is there a way to fix this without binding the PreferenceActivity and the service ?

Thanks

public class EventsService extends Service implements OnSharedPreferenceChangeListener {
    ...
    private SharedPreferences preferences;
    ...

    @Override
    public void onCreate() {
    super.onCreate();
    ...
    preferences = PreferenceManager.getDefaultSharedPreferences(this);
    preferences.registerOnSharedPreferenceChangeListener(this);
    ...
    }

    //On the same way i unregistered the listener onDestroy()

    private TimerTask updateTask = new TimerTask() {      
       @Override
       public void run() {     
              ....
               Log.v(TAG,"PREF : "+Integer.parseInt(preferences.getString("special_reminder_minutes","10")));
              ....
        }
    }

   @Override
   public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
      Log.d(TAG,"PREF CHANGED O -----------------------");

   }
 }

NB: For now, the preferences only contains a string array.

Upvotes: 2

Views: 1098

Answers (2)

ClemM
ClemM

Reputation: 452

Thanks for your answer.

I solved my problem using another way. In fact, i forgot to mention that my service is a remote one. So i add a method in the AIDL to set the new value in it. My service connection is inside a singleton pattern so basically my PrefActivity use this connection and by using the AIDL method, set the variable used in my service.

The question is, which way would be the best practice here ?

Upvotes: 1

larham1
larham1

Reputation: 12236

Decouple the service and the preferences by using an intent sent to "startService()". That function is poorly named--it isn't just to start the service (it will start it if necessary). startService() will also send a message to a service that is already running.

So in your preference listener, INSIDE your pref activity, you'd call something like:

Intent messageIntent = new Intent(context, MyService.class);
messageIntent.setAction(MyService.GAME_ALERT);
messageIntent.putExtra(MyService.GAME_ID, gameId);
context.startService(messageIntent);

To receive this message in the service, you override onStartService() something like this (note that stickiness is optional--depends on your service's use-case):

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        if (intent == null)
            return START_STICKY;

        try {
            String action = intent.getAction();
            if (GAME_ALERT.equals(action)) {
                // handle it
                String gameId = intent.getStringExtra(GAME_ID);
                if (gameId != null) {
//
                }
            } 
        } catch (Throwable e) {
            Log.e("me", "problem: ", e);
        }

        // We want this service to continue running until it is explicitly
        // stopped, so return sticky.
        return START_STICKY;
    }

Upvotes: 2

Related Questions