Akhil Agarwal
Akhil Agarwal

Reputation: 41

Save Markers on Android Map App

I am creating an Android Map App where I want to create marker at my current location and also display previous such markers. I am able to create marker at my current location but when I resume the app at a different location, my app is only showing current location marker not the previous ones. Please help. Here is what I tried:

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

Upvotes: 0

Views: 1002

Answers (1)

Sith
Sith

Reputation: 134

Notice that:

In the onPause() method you save in your file the Locations contained in the listOfPoints but you never add the last known location to that list. You probably want to add that in the onConnect() method.

EDIT: When you start the app, onCreate(), onStart() and onResume() methods are invoked (see Activity Lifecycle). Which means, the addMarker() method will likely be called when the map is not ready yet. You might want to add the markers only if the onMapReady() method was invoked before.

EDIT (since you updated the code):

  • Use openFileOutput("latlngpoints.txt", Context.MODE_APPEND) instead of Context.MODE_PRIVATE
  • You should read markers from file also in onMapReady() or in onConnected(Bundle connectionHint) exactly like you do in onResume() method (because when you run the app the map won't be ready yet and you won't execute anything but the if statement in your onResume())

Also notice that your file will likely containt duplicates

Upvotes: 1

Related Questions