web-dev-qa-db-fra.com

Problèmes utilisant SharedPreferences sur un service (GetPreferences n'existe pas sur un service)

J'ai des préférences partagées (latitude, longitude) que je souhaite accéder à un service, qui n'est pas sous-classée de l'activité.

En particulier, lorsque j'essaie d'accéder à GetPreferences, cette fonction n'existe pas sur un service. Mon code est affiché ci-dessous

Mon objectif ici est de permettre d'écrire ces préférences partagées avec mon service. Toute suggestions/exemples qui peuvent m'aider?

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) {}
}

Je reçois l'erreur sur la ligne settings = this.getPreferences(MODE_WORLD_WRITEABLE);

28

Si vous n'utilisez que SharedPreferences pour votre application, avez-vous (( tout Votre code l'obtenir via PreferenceManager.getDefaultSharedPreferences().

45
CommonsWare

En réalité, la plupart d'entre vous risquent de fonctionner dans le problème, que sur des périphériques avec API> = 11, les préférences partagées ne sont pas définies pour une utilisation multi-processus par défaut.

Solution:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
    prefs = getSharedPreferences(PREFS, 0 | Context.MODE_MULTI_PROCESS);
} else {
    prefs = getSharedPreferences(PREFS, 0);
}
19
Till

Peu de retard pour vous aider, mais j'espère que cela aide quelqu'un à l'avenir. Voici votre problème:

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

Puisque vous ne récupérez que le fichier de préférences partagé lorsque le service est créé, le fichier n'est jamais correctement mis à jour par le service et que les données ne sont donc jamais partagées avec l'application. Avant de rédiger des préférences partagées ou de récupérer toutes les données pouvant être modifiées, assurez-vous de récupérer à nouveau le fichier de préférences partagé (recharger) à nouveau comme:

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

ensuite, dans votre application:

     settings = this.getPreferences(MODE_WORLD_WRITEABLE);
     String myLat = setttings.getString("mylatitude","");

En outre, n'importe quoi sur Android 3.0 a un scénario dans lequel un service et une activité partage d'activité PREFS partagés, vous devez utiliser:

     settings = this.getPreferences(MODE_MULTI_PROCESS);
2
Droid Chris

Si vous avez déclaré SharedPreferences comme:

private static final String PREFS_NAME = "UserData"; 
private static final String PREFS_VALUE1 = "value1"; 

ensuite, utilisez le code ci-dessous pour récupérer des valeurs:

SharedPreferences preferences = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE);
value1 = preferences.getString(PREFS_VALUE1, "0");

De la même manière, vous pouvez même économiser des valeurs aux préférences partagées.

1
Harpreet

Pour les personnes qui tombent dans cette situation ... J'ai eu un problème similaire ... La vraie cause du problème est que nous essayons d'obtenir/utiliser un contexte qui n'est pas complètement initialisé. J'ai pu utiliser des préférences partagées normalement en dehors de mon constructeur pour mon intenteservice.

1
Arjun