Reputation: 41
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
Reputation: 134
Notice that:
getLastLocation()
method might return a null value if no previous location is available: getLastLocation Documentationsuper.onStart()
, super.onPause()
and super.onStop()
should be the first instructions in your onStart()
, onPause()
and onStop()
methods. More infos about Activity Lifecycle and methods overridingIn 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):
openFileOutput("latlngpoints.txt", Context.MODE_APPEND)
instead of Context.MODE_PRIVATE
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