Ответ 1
Если вы используете только один SharedPreferences
для своего приложения, все, ваш код получит его через PreferenceManager.getDefaultSharedPreferences()
.
У меня есть общие настройки (широта, долгота), которые я хочу получить от службы, которая не подклассифицирована из Activity.
В частности, когда я пытаюсь получить доступ к getPreferences, эта функция не существует в службе. Мой код размещен ниже
Моя цель здесь - разрешить WRITE эти общие настройки с моей службой. Любые предложения/примеры, которые могут помочь мне?
public class MyService extends Service implements Runnable {
LocationManager mLocationManager;
Location mLocation;
MyLocationListener mLocationListener;
Location currentLocation = null;
static SharedPreferences settings;
static SharedPreferences.Editor configEditor;
public IBinder onBind(Intent intent) {
return null;
}
public void onCreate() {
settings = this.getPreferences(MODE_WORLD_WRITEABLE);
configEditor = settings.edit();
writeSignalGPS();
}
private void setCurrentLocation(Location loc) {
currentLocation = loc;
}
private void writeSignalGPS() {
Thread thread = new Thread(this);
thread.start();
}
@Override
public void run() {
mLocationManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
if (mLocationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
Looper.prepare();
mLocationListener = new MyLocationListener();
mLocationManager.requestLocationUpdates(
LocationManager.GPS_PROVIDER, 1000, 0, mLocationListener);
Looper.loop();
//Looper.myLooper().quit();
} else {
Toast.makeText(getBaseContext(),
getResources().getString(R.string.gps_signal_not_found),
Toast.LENGTH_LONG).show();
}
}
private Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
if (currentLocation!=null) {
configEditor.putString("mylatitude", ""+currentLocation.getLatitude());
configEditor.putString("mylongitude", ""+currentLocation.getLongitude());
configEditor.commit();
}
}
};
private class MyLocationListener implements LocationListener {
@Override
public void onLocationChanged(Location loc) {
if (loc != null) {
Toast.makeText(getBaseContext(),
getResources().getString(R.string.gps_signal_found),
Toast.LENGTH_LONG).show();
setCurrentLocation(loc);
handler.sendEmptyMessage(0);
}
}
@Override
public void onProviderDisabled(String provider) {}
@Override
public void onProviderEnabled(String provider) {}
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {}
}
Я получаю ошибку на строке settings = this.getPreferences(MODE_WORLD_WRITEABLE);
Если вы используете только один SharedPreferences
для своего приложения, все, ваш код получит его через PreferenceManager.getDefaultSharedPreferences()
.
На самом деле, большинство из вас могут столкнуться с проблемой, что на устройствах с API >= 11 общие настройки больше не устанавливаются для использования нескольких процессов по умолчанию.
Решение:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
prefs = getSharedPreferences(PREFS, 0 | Context.MODE_MULTI_PROCESS);
} else {
prefs = getSharedPreferences(PREFS, 0);
}
Немного поздно, чтобы помочь вам в этом, но я надеюсь, что это поможет кому-то в будущем. Вот ваша проблема:
public void onCreate() {
settings = this.getPreferences(MODE_WORLD_WRITEABLE);
configEditor = settings.edit();
writeSignalGPS();
}
Поскольку вы только извлекаете файл общих предпочтений при создании службы, файл никогда не обновляется службой, и поэтому данные никогда не будут совместно использоваться приложением. Перед тем, как писать в общие настройки или получать любые данные, которые могут быть изменены, убедитесь, что вы снова загрузили файл общей настройки (перезагрузка), например:
private Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
if (currentLocation!=null) {
settings = this.getPreferences(MODE_WORLD_WRITEABLE);
configEditor = settings.edit();
configEditor.putString("mylatitude", ""+currentLocation.getLatitude());
configEditor.putString("mylongitude", ""+currentLocation.getLongitude());
configEditor.commit();
}
}
то в вашем приложении:
settings = this.getPreferences(MODE_WORLD_WRITEABLE);
String myLat = setttings.getString("mylatitude","");
Кроме того, что-либо на Android 3.0, где есть сценарий, в котором служба и активность разделяют общие префы, вы должны использовать:
settings = this.getPreferences(MODE_MULTI_PROCESS);
Если вы объявили SharedPreferences как:
private static final String PREFS_NAME = "UserData";
private static final String PREFS_VALUE1 = "value1";
затем используйте приведенный ниже код для выбора значений:
SharedPreferences preferences = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE);
value1 = preferences.getString(PREFS_VALUE1, "0");
Таким же образом вы даже можете сохранить значения в SharedPreferences.
Для людей, которые сталкиваются с этим... У меня была аналогичная проблема... Истинная причина проблемы заключается в том, что мы пытаемся получить/использовать контекст, который не полностью инициализирован. Я мог нормально использовать sharedPreferences вне моего конструктора для моего IntentService.