I've created a simple app with a Maps fragment. With a help of onInfoWindowClick listener user could click on the marker's info window and another activity with nested fragment opens. I'm using HashMap to link marker with a certain object to populate 2nd activity's fragment with relevant info.
When user clicks on the marker's info window first time 2nd activity launches OK and shows details screen. But when user hits Back button and clicks on this or other info window - app crashes.
I've tried to debug app and found out that after 2nd click on info window marker couldn't be found in HashMap.
I hit a wall here - couldn't find out why the same marker could be found in map first time but second time is not.
Error:
03-27 12:50:34.637: E/AndroidRuntime(31198): FATAL EXCEPTION: main
03-27 12:50:34.637: E/AndroidRuntime(31198): Process: com.example.testingmap, PID: 31198
03-27 12:50:34.637: E/AndroidRuntime(31198): java.lang.NullPointerException
03-27 12:50:34.637: E/AndroidRuntime(31198): at com.example.testingmap.MapActivity$1.onInfoWindowClick(MapActivity.java:166)
03-27 12:50:34.637: E/AndroidRuntime(31198): at com.google.android.gms.maps.GoogleMap$12.zze(Unknown Source)
03-27 12:50:34.637: E/AndroidRuntime(31198): at com.google.android.gms.maps.internal.zzh$zza.onTransact(Unknown Source)
03-27 12:50:34.637: E/AndroidRuntime(31198): at android.os.Binder.transact(Binder.java:361)
03-27 12:50:34.637: E/AndroidRuntime(31198): at com.google.android.gms.maps.internal.al.a(SourceFile:82)
P.S. I've cleaned up the code a bit so the stack trace should point somewhere around line 91 instead of 166.
Activity's code:
public class MapActivity extends FragmentActivity implements ConnectionCallbacks, OnConnectionFailedListener {
private GoogleMap mMap;
private LatLng mDogPosition = new LatLng(0.0, 0.0);
private ArrayList<Dog> mDogList;
private HashMap<Marker, Dog> mHashMap;
private GoogleApiClient mGoogleApiClient;
private Location mLastLocation;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_map);
mDogList = DogCollection.get(this).getDogs();
buildGoogleApiClient();
}
@Override
protected void onStart(){
super.onStart();
mGoogleApiClient.connect();
}
@Override
protected void onStop(){
mGoogleApiClient.disconnect();
super.onStop();
}
@Override
protected void onResume(){
super.onResume();
initializeMap();
}
private void addingMyMarker(){
Marker dog = mMap.addMarker(new MarkerOptions()
.position(mDogPosition)
.title("The Dog")
.snippet("Woof-woof!")
.icon(BitmapDescriptorFactory
.fromResource(R.drawable.dog_icon_m)));
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(mDogPosition, 15));
mMap.setMyLocationEnabled(true);
}
private void addingMarkers(){
mHashMap = new HashMap<Marker, Dog>();
for (Dog dog : mDogList) {
Marker m = mMap.addMarker(new MarkerOptions()
.position(dog.getPosition())
.title(dog.getName())
.snippet(dog.getDescription())
.icon(BitmapDescriptorFactory
.fromResource(dog.getIcon())));
mHashMap.put(m, dog);
}
}
protected synchronized void buildGoogleApiClient(){
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
}
@Override
public void onConnected(Bundle connectionHint){
mLastLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
if (mLastLocation != null && mMap != null) {
mDogPosition = new LatLng (mLastLocation.getLatitude(), mLastLocation.getLongitude());
addingMyMarker();
addingMarkers();
}
}
private void initializeMap(){
if (mMap == null){
mMap = ((MapFragment) getFragmentManager().findFragmentById(R.id.map)).getMap();
}
if (mMap != null){
mMap.setOnInfoWindowClickListener(new OnInfoWindowClickListener(){
@Override
public void onInfoWindowClick(Marker marker){
Dog dog = mHashMap.get(marker);
Intent intent = new Intent(MapActivity.this, DetailsActivity.class);
intent.putExtra(DetailsFragment.EXTRA_DOG_ID, dog.getId());
startActivity(intent);
}
});
}
}
}
SOLVED The problem was with markers that were recreated by initializeMap method each time onResume was called. Every time new marker was added on exactly the same position as former one. I was clicking on old marker which somehow was in front of the new one. In my HashMap actual markers were stored but when I clicked on old one app crashed. Solved this problem by adding mMap.clear() call to delete all old markers in my initializeMap() method.