【问题标题】:Save Markers on Android Map App在 Android 地图应用上保存标记
【发布时间】:2016-09-16 17:46:18
【问题描述】:

我正在创建一个 Android 地图应用程序,我想在当前位置创建标记并显示以前的此类标记。我可以在当前位置创建标记,但是当我在其他位置恢复应用程序时,我的应用程序只显示当前位置标记而不是以前的位置标记。请帮忙。这是我尝试过的:

public class Main extends FragmentActivity implements OnMapReadyCallback, GoogleApiClient.ConnectionCallbacks,
    GoogleApiClient.OnConnectionFailedListener {

private GoogleMap mMap;
private GoogleApiClient mGoogleApiClient;
public Location mLastLocation;
ArrayList<LatLng> listOfPoints = new ArrayList<>();
public boolean isMapReady = false;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
            .findFragmentById(R.id.map);
    mapFragment.getMapAsync(this);

    if (mGoogleApiClient == null) {
        mGoogleApiClient = new GoogleApiClient.Builder(this)
                .addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this)
                .addApi(LocationServices.API)
                .build();

    }
}


public void onMapReady(GoogleMap googleMap) {
    mMap = googleMap;
    isMapReady = true;
}

public boolean onMarkerClick(final Marker marker) {
    return false;
}

public void onConnected(Bundle connectionHint) {
    if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {

        return;
    }
    if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {

        return;
    }
    mLastLocation = LocationServices.FusedLocationApi.getLastLocation(
            mGoogleApiClient);

    MarkerOptions mp = new MarkerOptions();
    mp.position(new LatLng(mLastLocation.getLatitude(), mLastLocation.getLongitude()));

    mp.title("my position");

    mMap.addMarker(mp);

    mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(
            new LatLng(mLastLocation.getLatitude(), mLastLocation.getLongitude()), 16));
    LatLng newLatLng = new LatLng(mLastLocation.getLatitude(), mLastLocation.getLongitude());
    listOfPoints.add(newLatLng);


   }

public void onConnectionSuspended(int i) {

}

public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {

}

protected void onStart() {
    super.onStart();
    mGoogleApiClient.connect();
}

protected void onStop() {
    super.onStop();
    mGoogleApiClient.disconnect();

}

protected void onPause() {
    super.onPause();
    try {
        // Modes: MODE_PRIVATE, MODE_WORLD_READABLE, MODE_WORLD_WRITABLE
        FileOutputStream output = openFileOutput("latlngpoints.txt",
                Context.MODE_PRIVATE);
        DataOutputStream dout = new DataOutputStream(output);
        dout.writeInt(listOfPoints.size()); // Save line count
        for (LatLng point : listOfPoints) {
            dout.writeUTF(point.latitude + "," + point.longitude);
            Log.v("write", point.latitude + "," + point.longitude);
        }
        dout.flush(); // Flush stream ...
        dout.close(); // ... and close.
    } catch (IOException exc) {
        exc.printStackTrace();
    }
}

protected void onResume(){
    super.onResume();
    if (isMapReady==true){
        try {
            FileInputStream input = openFileInput("latlngpoints.txt");
            DataInputStream din = new DataInputStream(input);
            int sz = din.readInt(); // Read line count
            for (int i = 0; i < sz; i++) {
                String str = din.readUTF();
                Log.v("read", str);
                String[] stringArray = str.split(",");
                double latitude = Double.parseDouble(stringArray[0]);
                double longitude = Double.parseDouble(stringArray[1]);
                listOfPoints.add(new LatLng(latitude, longitude));
            }
            din.close();
            loadMarkers(listOfPoints);
        } catch (IOException exc) {
            exc.printStackTrace();
        }
    }
}
protected void onSaveInstanceState(Bundle outState){
    super.onSaveInstanceState(outState);

    outState.putParcelableArrayList("places",  listOfPoints);
}
private void restore(Bundle outState){
    if (outState != null) {
        listOfPoints =(ArrayList<LatLng>)outState.getSerializable("places");
    }
}
protected void onRestoreInstanceState(Bundle outState) {
    super.onRestoreInstanceState(outState);
    restore(outState);
}
private void loadMarkers(List<LatLng> listOfPoints) {
    int i=listOfPoints.size();
    while(i>0){
        i--;
        double Lat=listOfPoints.get(i).latitude;
        double Lon=listOfPoints.get(i).longitude;
        MarkerOptions mp = new MarkerOptions();

        mp.position(new LatLng(Lat, Lon));

        mp.title("my previous position");

        mMap.addMarker(mp);

        mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(
                new LatLng(Lat, Lon), 16));
    }
}
}

【问题讨论】:

  • 看起来你真的很接近这个了。
  • 浏览您的代码,您似乎在做所有正确的事情来保存和加载标记。有趣的一件事是 if (isMapReady==true) 现在这个条件在 onResume 发生时不成立吗?可能是在 onResume 发生时地图还没有准备好。你能验证一下吗?
  • @CrashOverride 应用程序的那部分现在正在运行。现在我面临的问题是,当应用程序被销毁并重新启动时,它没有显示以前保存的标记。请看一下。

标签: android google-maps google-maps-markers


【解决方案1】:

注意:

onPause() 方法中,您将listOfPoints 中包含的位置保存在文件中,但您永远不会将最后一个已知位置添加到该列表中。您可能想在 onConnect() 方法中添加它。

编辑:当您启动应用程序时,会调用onCreate()onStart()onResume() 方法(see Activity Lifecycle)。这意味着,addMarker() 方法可能会在地图尚未准备好时被调用。只有在之前调用过 onMapReady() 方法时,您才可能想要添加标记。

编辑(因为您更新了代码):

  • 使用openFileOutput("latlngpoints.txt", Context.MODE_APPEND) 而不是Context.MODE_PRIVATE
  • 您还应该在onMapReady()onConnected(Bundle connectionHint) 中读取文件中的标记,就像在onResume() 方法中所做的那样(因为当您运行应用程序时,地图还没有准备好,您不会执行任何操作但是onResume() 中的 if 语句)

另请注意,您的文件可能包含重复项

【讨论】:

  • 我修改了我的代码以在 onConnect() 方法中包含这些行: LatLng newLatLng = new LatLng(mLastLocation.getLatitude(), mLastLocation.getLongitude()); listOfPoints.add(newLatLng);但是现在当我尝试运行代码时,它给了我错误“无法恢复活动,因为尝试在 loadMarkers 代码中调用虚拟方法 addMarkers”。
  • 你能推荐一下方法吗?
  • @AkhilAgarwal 您可以使用isMapReady 布尔属性(默认为false)并在onMapReady() 方法中将其设置为true。只有当isMapReadytrue 时,您才应该在onResume() 方法中更新地图。如果您还没有设置onMapReady() 回调,请查看developers.google.com/maps/documentation/android-api/…
  • 现在我的应用程序正在运行,但它仍然没有显示以前的位置标记。每次我打开应用程序时,它只会在我当前的位置显示标记。
  • @AkhilAgarwal 你能发布你更新的代码吗?
猜你喜欢
  • 1970-01-01
  • 2018-05-26
  • 1970-01-01
  • 2014-09-22
  • 1970-01-01
  • 1970-01-01
  • 2019-04-09
  • 1970-01-01
  • 2014-03-22
相关资源
最近更新 更多