Проблемы с использованием SharedPreferences на Сервисе (getPreferences на сервисе не существует) - PullRequest
28 голосов
/ 18 ноября 2010

У меня есть общие параметры (широта, долгота), к которым я хочу получить доступ из службы, которая не подкласса из Activity

В частности, когда я пытаюсь получить доступ к getPreferences, эта функция не существует в службе. Мой код размещен ниже

Моя цель - разрешить ЗАПИСАТЬ эти общие настройки с помощью моего сервиса. Любые предложения / примеры, которые могут мне помочь?

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);

Ответы [ 5 ]

45 голосов
/ 18 ноября 2010

Если вы используете только один SharedPreferences для своего приложения, наберите all , чтобы ваш код получил через PreferenceManager.getDefaultSharedPreferences().

19 голосов
/ 06 сентября 2013

На самом деле, большинство из вас могут столкнуться с проблемой, что на устройствах с API> = 11 общие предпочтения больше не устанавливаются для многопроцессорного использования по умолчанию.

Решение:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
    prefs = getSharedPreferences(PREFS, 0 | Context.MODE_MULTI_PROCESS);
} else {
    prefs = getSharedPreferences(PREFS, 0);
}
2 голосов
/ 29 марта 2013

Немного поздно, чтобы помочь вам в этом, но я надеюсь, что это поможет кому-то в будущем.Вот ваша проблема:

    public void onCreate() {
       settings = this.getPreferences(MODE_WORLD_WRITEABLE);
       configEditor = settings.edit();
       writeSignalGPS();
    }

Поскольку вы извлекаете файл Shared Preference только при создании службы, файл никогда не обновляется должным образом службой, и поэтому данные никогда не передаются приложению.Перед записью в Shared Preferences или извлечением любых данных, которые могли измениться, убедитесь, что снова получили файл Shared Preferences (перезагрузите), например:

    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);
1 голос
/ 21 ноября 2016

Для людей, которые сталкиваются с этим ... У меня была похожая проблема ... Истинная причина проблемы в том, что мы пытаемся получить / использовать контекст, который не полностью инициализирован. Я смог нормально использовать sharedPreferences за пределами моего конструктора для моего IntentService.

1 голос
/ 18 марта 2013

Если вы объявили 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.

...