【问题标题】:How to save latitude and longitude (location) in Shared Preference如何在共享首选项中保存纬度和经度(位置)
【发布时间】:2014-11-08 06:56:33
【问题描述】:

我想获取某个位置的经度和纬度坐标并保存在 ArrayList 中,然后将此列表提交到 SharedPreference 文件,这样当地图加载时,所有以前的位置都可以使用 SharedPreference 文件中的数据使用标记进行设置.

我只知道 SharedPreference 只会存储原始数据类型而不是数组。

我的问题是,是否有人知道通过共享首选项技术或任何替代方式来保存这些数据的方法?

任何意见表示赞赏。

【问题讨论】:

    标签: android arrays sharedpreferences


    【解决方案1】:

    您可以将它们存储为用句点/逗号分隔的字符串。但是在纬度和经度的情况下,您不应该使用句点,因为它们有句点 (latitude = 27 . 345)

    例如

    String aLocation = latitude + "," + longitude//store this to sharedpreference
    

    这对于经度和纬度来说不是问题,因为没有逗号(但有句点)会与您的限制器冲突。

    在检索位置时,您可以将其拆分并获得相应的经度和纬度。

    String[] locationArray = pref.getString(KEY_LOCATION, "").split(","); 
    String retrievedLat = locationArray[0];
    String retrievedLong = locationArray[1];//you may need to use trim() method
    

    您也可以将其转换为 JSON 并保存。但我更喜欢上面的方法,因为它更容易,不会给你的场景带来任何问题。

    但如果您需要存储带有特殊字符(如句点)的字符串,则需要将其设为 JSON,因为它可能与您的限制器冲突

    所以你可以这样做:

    public void addToPref(LatLng location){//I'm supposing you are using LatLang class
        String aLocation = location.getLatitude() + "," + location.getLongitude();
    //and save to shared preference
        }
    

    更新:

    如果您想输入多个位置,则需要使用 JSON(首选),但第一种方法更容易。 见下文

    1. Get string from preference
    2. Concatenate it with the new location
    

    喜欢:

    oldLocation,newLocation,newerLocation
    

    附:您可能有每个位置的经度和纬度,因此字符串必须像

    {lat1,long1}:{lat2,lat2}:{lat3,long3}
    

    在这种情况下,您需要有多个限制器并做(相应地拆分)。

    使用 split(":") 方法将为您提供多个位置。

    并使用 split(",") 进一步拆分它,这将为您提供相应的纬度和经度。

    【讨论】:

    • 尝试了第一种使用 Shred 首选项的方法,但在尝试将多个位置保存为共享首选项中的字符串时陷入困境,因为无法使每个字符串都拥有一个唯一的位置,因为每个单独的位置都可以称为 rfm 共享首选项之后 。那么他的 JSON 是否持久化数据?没用过
    • 对不起!但是不明白你的意思?请解释一下。
    • 我在类似的应用程序中使用了第一种方法。它运行良好
    • 当然,所以对于每个位置,我将经纬度坐标转换为字符串(纬度/经度),然后使用“/”分隔符进行拆分。那么我们如何让每个 String 位置都提交给 SP 的唯一性,以便我们以后可以得到相同的 String 而不会被下一个位置字符串覆盖呢?希望没有很好的解释是有道理的....
    • 为您的所有帮助干杯,我使用序列化对象方法作为内存管理的预期问题,用于使用共享 pref 方法将数据存储在字符串中。
    【解决方案2】:

    1- 创建一个类并放置您想要存储的所有内容,例如您的latitudelongitude 中的arraylist,并使该类实现Serializable 接口。

    class MyBundle  implements Serializable {
    
       ArrayList<Double> mLat;
       ArrayList<Double> mLan;
    
       MyBundle( ArrayList<Double> latitude, ArrayList<Double> longitude ){
    
        mLat = latitude;
        mLan = longitude;
    
       }
    
    }
    

    2- 将其写入文件:

     ObjectOutputStream oos = null;
     FileOutputStream fout = null;
     try{
            FileOutputStream fout = new FileOutputStream("Your file path");
            ObjectOutputStream oos = new ObjectOutputStream(fout);
            oos.writeObject(mb); // mb is an instance of MyBundle
     } catch (Exception ex) {
            e.printStackTrace();
     }finally {
       if(oos  != null){
         oos.close();
       } 
     }
    

    并取回一切:

     ObjectInputStream objectinputstream = null;
     try {
            streamIn = new FileInputStream("Your file address");
            objectinputstream = new ObjectInputStream(streamIn);
            MyBundle mb = (MyBundle) objectinputstream.readObject();
    
       } catch (Exception e) {
            e.printStackTrace();
       }finally {
         if(objectinputstream != null){
            objectinputstream .close();
         } 
       }
    

    【讨论】:

    • 所以我可以创建实现可序列化的内部类,使用 setter/getter 存储/retrive long/lat doubles 并写入/从文件中取回。文件路径应该是什么?这必须是 ant 特定目录吗?
    • 第一个内部类还必须实现serializable,第二个文件路径可以是您的外部存储或内部的任何内容,例如它可以是您的内部缓存Activity.getCacheDir().getAbsolutePath().toString()
    • 如果每次用户在活动/应用程序启动之间选择一个新位置时将一个新对象写入文件,或者对象只是在文件中被覆盖,这会起作用吗?
    • 这取决于你如何写它如果你覆盖你丢失了以前的数据,如果你附加它不是。我不明白你想要做什么可能是你需要数据库,因为我认为你想存储从你的应用程序的第一次午餐到现在的所有用户位置。
    • 我想你可以读取对象表单文件,然后通过 arrayList 添加额外的坐标并再次保存,从而不会覆盖任何以前的数据??.....想要避免使用和修改当前数据库模式如果可能的话
    【解决方案3】:

    我通过简单的函数使用了这些方法

    // Saving GeoFence marker with prefs mng
        private void saveGeofence() {
            Log.d(TAG, "saveGeofence()");
            SharedPreferences sharedPref = getPreferences( Context.MODE_PRIVATE );
            SharedPreferences.Editor editor = sharedPref.edit();
    
            editor.putLong( KEY_GEOFENCE_LAT, Double.doubleToRawLongBits( geoFenceMarker.getPosition().latitude ));
            editor.putLong( KEY_GEOFENCE_LON, Double.doubleToRawLongBits( geoFenceMarker.getPosition().longitude ));
            editor.apply();
        }
    
        // Recovering last Geofence marker
        private void recoverGeofenceMarker() {
            Log.d(TAG, "recoverGeofenceMarker");
            SharedPreferences sharedPref = getPreferences( Context.MODE_PRIVATE );
    
            if ( sharedPref.contains( KEY_GEOFENCE_LAT ) && sharedPref.contains( KEY_GEOFENCE_LON )) {
                double lat = Double.longBitsToDouble( sharedPref.getLong( KEY_GEOFENCE_LAT, -1 ));
                double lon = Double.longBitsToDouble( sharedPref.getLong( KEY_GEOFENCE_LON, -1 ));
                LatLng latLng = new LatLng( lat, lon );
                markerForGeofence(latLng);
                drawGeofence();
            }
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-10-03
      • 2012-11-08
      • 1970-01-01
      • 1970-01-01
      • 2020-06-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多