【问题标题】:How to store and retrieve Location object in SharedPreferences?如何在 SharedPreferences 中存储和检索 Location 对象?
【发布时间】:2015-04-02 14:47:39
【问题描述】:

我想存储一个 Location 对象,并且我正在尝试选择一种好方法来做到这一点。 请给我建议如何做到这一点

我正在使用此代码,但是当我从首选项中获取位置时,位置返回如下...

位置[mProvider=STORAGE,mTime=0,mLatitude=30.0,mLongitude=76.0,mHasAltitude=false,mAltitude=0.0,mHasSpeed=false,mSpeed=0.0,mHasBearing=false,mBearing=0.0,mHasAccuracy=false,mAccuracy =0.0,mExtras=null]

/** Store Location object in SharedPreferences */
public void storeLocation(Context context, Location location) {
    SharedPreferences settings;
    Editor editor;
    try {
        JSONObject locationJson = new JSONObject();
        locationJson.put(LATITUDE, location.getLatitude());
        locationJson.put(LONGITUDE, location.getLongitude());

        settings = context.getSharedPreferences(PREFS_NAME,Context.MODE_PRIVATE);
        editor = settings.edit();

        editor.putString(KEY_LOCATION, locationJson.toString());
        editor.commit();
        Log.i("location_util_store", "Location" + location);
    } catch (Exception e) {
        e.printStackTrace();
    }
}

/** Retrieve Location object from SharedPreferences
 * @return */
public Location getPrevLocation(Context context) {

    SharedPreferences settings;
    try {
        settings = context.getSharedPreferences(PREFS_NAME,Context.MODE_PRIVATE);
        String jsonLocation = settings.getString(KEY_LOCATION, null);
        if (jsonLocation != null) {

            JSONObject locationJson = new JSONObject(jsonLocation);
            Location location = new Location("STORAGE");
            location.setLatitude(locationJson.getInt(LATITUDE));
            location.setLongitude(locationJson.getInt(LONGITUDE));
            Log.i("location_util_get", "Location" + location);
            return location;
        }

    } catch (Exception e) {
        e.printStackTrace();
    }
    return null;
}

【问题讨论】:

  • 我认为你不能将对象存储到 sharedPereference 中,你只能存储字符串和 int 尝试将你的对象分解为一些字符串或整数
  • 是否显示任何错误。 KEY_LOCATION 只是字符串。
  • 没有显示任何错误,我已将 KEY_LOCATION 定义为类中的字符串

标签: java android sharedpreferences


【解决方案1】:

最佳解决方案:将位置 lat & long 参数提取为字符串并将它们保存在 prefs 中。您也可以根据您的用例从位置提取其他信息。

保存位置:-

        if (location == null) {
            sharedPreferences.edit().removeKey("LOCATION_LAT").apply();
            sharedPreferences.edit().removeKey("LOCATION_LON").apply();
            sharedPreferences.edit().removeKey("LOCATION_PROVIDER").apply();
        } else {
            sharedPreferences.edit().putString("LOCATION_LAT", String.valueOf(location.getLatitude())).apply();
            sharedPreferences.edit().putString("LOCATION_LON", String.valueOf(location.getLongitude())).apply();
            sharedPreferences.edit().putString("LOCATION_PROVIDER", location.getProvider()).apply();
        }

检索位置:-

        String lat = sharedPreferences.getString("LOCATION_LAT", null);
        String lon = sharedPreferences.getString("LOCATION_LON", null);
        Location location = null;
        if (lat != null && lon != null) {
            String provider = sharedPreferences.getString("LOCATION_PROVIDER", null);
            location = new Location(provider);
            location.setLatitude(Double.parseDouble(lat));
            location.setLongitude(Double.parseDouble(lon));
        }
        return location;

糟糕的解决方案:改用 Gson 来持久化您的位置:

保存位置:

String json = location == null ? null : new Gson().toJson(location);
sharedPreferences.edit().putString("Location", json).apply();

检索位置:

String json = sharedPreferences.getString("location", null);
return json == null ? null : new Gson().fromJson(json, Location.class);

this answer 中所述。

这不应该崩溃,但它会在某些设备上崩溃。如上所述here

【讨论】:

  • @ArthurMelo Gson 方法有效,但应用程序在某些设备上崩溃,如“应用程序崩溃(有时)与致命信号 11 (SIGSEGV),代码 1”stackoverflow.com/questions/37101603/… 中所述
  • 不要使用这种方法,stackoverflow.com/questions/44090552/…
  • @KirillVashilo,已经提到 Gson 方法在某些设备上不起作用。因此,请使用此答案的第二个解决方案中已经提到的普通序列化。
【解决方案2】:

已解决
存储位置对象:

SharedPreferences settings;
    Editor editor;
    try {

        settings = context.getSharedPreferences(PREFS_NAME,Context.MODE_PRIVATE);
        editor = settings.edit();

        Gson gson = new Gson();
        String json = gson.toJson(location);
        editor.putString(KEY_LOCATION, json);
        editor.commit();

    } catch (Exception e) {
        e.printStackTrace();
    }

检索位置对象

SharedPreferences settings;
    try {
        settings = context.getSharedPreferences(PREFS_NAME,Context.MODE_PRIVATE);

        Gson gson = new Gson();
        String json = settings.getString(KEY_LOCATION, "");
        Location obj = gson.fromJson(json, Location.class);

        if (obj != null) {

            return obj;
        }

    } catch (Exception e) {
        e.printStackTrace();
    }

【讨论】:

  • 这将出现工作,但你会得到原生 android 崩溃(没有堆栈跟踪),因为 Location 没有默认构造函数,并且在使用 Gson 序列化时会导致问题。
  • 不要使用这种方法,stackoverflow.com/questions/44090552/…
【解决方案3】:

如果只有 Lat Long 对您很重要,那么您可以使用以下答案。正如您在 cmets 中看到的那样,最受欢迎的答案是错误的

你可以通过调用SharedPreferencesHelper.getInstance(context).setCurrentLocation(location);来使用它

public class SharedPreferencesHelper {
    private static SharedPreferencesHelper sharedPreferencesHelper;
    private static SharedPreferences pref;
    private String CURRENT_LOCATION_LAT = "CURRENT_LOCATION_LAT";
    private String CURRENT_LOCATION_LONG = "CURRENT_LOCATION_LONG";

    public static SharedPreferencesHelper getInstance(Context context) {
        if (null == sharedPreferencesHelper) {
            pref = PreferenceManager.getDefaultSharedPreferences(context);
            sharedPreferencesHelper = new SharedPreferencesHelper();
        }
        return sharedPreferencesHelper;
    }

    public Location getCurrentLocation() {
        Location location = new Location("");//provider name is unnecessary
        location.setLatitude(getDouble(CURRENT_LOCATION_LAT));
        location.setLongitude(getDouble(CURRENT_LOCATION_LONG));
        return location;
    }

    public void setCurrentLocation(Location location) {
        setDouble(CURRENT_LOCATION_LAT, location.getLatitude());
        setDouble(CURRENT_LOCATION_LONG, location.getLongitude());
    }

    private double getDouble(String key) {
        return Double.longBitsToDouble(pref.getLong(key, Double.doubleToLongBits(0)));
    }

    private void setDouble(String key, double val) {
        SharedPreferences.Editor editor = pref.edit();
        editor.putLong(key, Double.doubleToRawLongBits(val));
        editor.commit();
    }

}

【讨论】:

    【解决方案4】:

    我还需要将Location 与它的大多数成员一起保存,而不仅仅是纬度和经度。我最终编写了自己的Serializable 课程。看我的回答here

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-08-10
      • 1970-01-01
      • 2011-09-30
      • 1970-01-01
      • 1970-01-01
      • 2020-07-13
      • 2012-09-02
      相关资源
      最近更新 更多