Android 共享首选项更改侦听器即使使用侦听器的全局引用也不工作
Android Shared preference change listener not working even with a global refernce of listener
我有一个注册共享首选项更改侦听器的服务。共享首选项属于另一个应用程序并且是世界可读的。尽管按照建议 here 保留了监听器的全局实例,但我的 onSharedPreferenceChanged() 没有被调用。
服务代码如下:
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);
}
}
}
共享偏好相关代码在onStartCommand()中。
任何人都知道出了什么问题吗?
请注意,在实际的 Sharedpreferences 文件中,当我看到使用 adb shell
时,我可以观察到值的变化
context = getApplicationContext().createPackageContext("net.osmand.plus", Context.MODE_WORLD_WRITEABLE);
您的上下文为空
你的 con just use "this" 服务本身就是一个上下文
或者你可以试试 getSharedPreferences("net.osmand.settings", Context.MODE_WORLD_READABLE);
从 this post 看来,Android 不支持我尝试做的事情。 WORLD_READABLE
标志 SharedPreferences
不支持可能导致不一致的多线程支持。 Android 开发者网站还提到 SharedPreferences
的多进程支持不适用于 WORLD_READABLE
首选项。
我有一个注册共享首选项更改侦听器的服务。共享首选项属于另一个应用程序并且是世界可读的。尽管按照建议 here 保留了监听器的全局实例,但我的 onSharedPreferenceChanged() 没有被调用。 服务代码如下:
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);
}
}
}
共享偏好相关代码在onStartCommand()中。 任何人都知道出了什么问题吗? 请注意,在实际的 Sharedpreferences 文件中,当我看到使用 adb shell
时,我可以观察到值的变化context = getApplicationContext().createPackageContext("net.osmand.plus", Context.MODE_WORLD_WRITEABLE);
您的上下文为空
你的 con just use "this" 服务本身就是一个上下文
或者你可以试试 getSharedPreferences("net.osmand.settings", Context.MODE_WORLD_READABLE);
从 this post 看来,Android 不支持我尝试做的事情。 WORLD_READABLE
标志 SharedPreferences
不支持可能导致不一致的多线程支持。 Android 开发者网站还提到 SharedPreferences
的多进程支持不适用于 WORLD_READABLE
首选项。