1

I have a service which registers a shared preference change listener. The shared preference belongs to another app and is world readable. Despite of keeping a global instance of listener as suggested here, My onSharedPreferenceChanged() is not getting called . The code of the service is as follows:

public class ClientService extends Service {
public static FileObserver observer;  
public static final String addr = "127.0.0.1";
public static final int port = 5001;
public Socket socket = null;
InputStream inputStream;
OutputStream outputStream;
String buffer = new String();
OnSharedPreferenceChangeListener listener;


@Override
public IBinder onBind(Intent arg0) {
    // TODO Auto-generated method stub
    return null;
}
@Override
public void onDestroy() {
    // TODO Auto-generated method stub
    Log.d(MainActivity.TAG, "killing service");
    super.onDestroy();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    // TODO Auto-generated method stub
    Log.d(MainActivity.TAG, "Starting Activity");
    Context context = null;
    /*try {
        socket = new Socket(addr, port);
        inputStream = socket.getInputStream();
        outputStream = socket.getOutputStream();
    } catch (Exception e) {
        // TODO: handle exception
        e.printStackTrace();
        Log.e(MainActivity.TAG, "Error in opening Socket");
    }*/
    Log.d(MainActivity.TAG,"Carrying on...");

    final MyClientTask clientTask = new MyClientTask(addr, port);
    SharedPreferences sp = null;
    try {
        context = getApplicationContext().createPackageContext("net.osmand.plus", Context.MODE_WORLD_WRITEABLE);
    } catch (Exception e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
        Log.e(MainActivity.TAG,"OSMAnd Package not found");
    }

    if(context != null) {
        sp = context.getSharedPreferences("net.osmand.settings", Context.MODE_WORLD_READABLE);
        Log.d(MainActivity.TAG, ""+sp.getFloat("last_known_map_lat", 0));

        listener = new SharedPreferences.OnSharedPreferenceChangeListener() {

            @Override
            public void onSharedPreferenceChanged(SharedPreferences sharedPreferences,
                    String key) {
                // TODO Auto-generated method stub
                Log.d(MainActivity.TAG,"Shared preference "+key+" changed");
                if(key == "last_known_map_lat" || key == "last_known_map_lon") {
                    /* Send this via socket */
                    float data = sharedPreferences.getFloat(key, 0);

                    Log.d(MainActivity.TAG, "Sending data: "+data);
                    clientTask.execute(""+data);

                }
            }
        };
        sp.registerOnSharedPreferenceChangeListener(listener);
    }


    observer = new FileObserver("/data/data/net.osmand.plus/shared_prefs/net.osmand.settings.xml" ) {

        @Override
        public void onEvent(int event, String path) {
            // TODO Auto-generated method stub
            if(event  == FileObserver.MODIFY) {
                Log.d(MainActivity.TAG, "Changed");
            }
        }
    };

    return super.onStartCommand(intent, flags, startId);
}



public class MyClientTask extends AsyncTask<String, Void, Void> {

    String dstAddress;
    int dstPort;
    String response = "";

    MyClientTask(String addr, int port){
        dstAddress = addr;
        dstPort = port;
    }

    @Override
    protected Void doInBackground(String... buffer) {
        try {
            byte[] bytes = buffer[0].getBytes();
            //outputStream.write(bytes);
            Log.d(MainActivity.TAG, "blah");
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return null;

    }

    @Override
    protected void onPostExecute(Void result) {

        super.onPostExecute(result);
    }

}

}

The shared preference related code is in onStartCommand(). Anyone has any clue what is wrong ? Note that in the actual Sharedpreferences file, I can observe the value changing when I see using adb shell

Community
  • 1
  • 1
SDG99
  • 21
  • 7

2 Answers2

1
context = getApplicationContext().createPackageContext("net.osmand.plus", Context.MODE_WORLD_WRITEABLE);

your context is null your con just use "this" service is itself a context or you can try getSharedPreferences("net.osmand.settings", Context.MODE_WORLD_READABLE);

SAM
  • 399
  • 2
  • 9
  • Here 'context' is used to store the context of the other app whose SharedPreferences I want to access.. – SDG99 Apr 01 '15 at 07:18
1

It seems from this post that what I am trying to do is unsupported in Android. WORLD_READABLE flag for SharedPreferences does not support multi-thread support which might be causing the inconsistencies. In the Android developer site also it is mentioned that multiple process support for SharedPreferences is not available for WORLD_READABLE preferences.

Community
  • 1
  • 1
SDG99
  • 21
  • 7