Lee Lee - 8 days ago 6
Android Question

moveCamera with CameraUpdateFactory.newLatLngBounds crashes

I'm making use of the new Android Google Maps API.

I create an activity which includes a MapFragment. In the activity

onResume
I set the markers into the GoogleMap object and then define a bounding box for the map which includes all of the markers.

This is using the following pseudo code:

LatLngBounds.Builder builder = new LatLngBounds.Builder();
while(data) {
LatLng latlng = getPosition();
builder.include(latlng);
}
CameraUpdate cameraUpdate = CameraUpdateFactory
.newLatLngBounds(builder.build(), 10);
map.moveCamera(cameraUpdate);


The call to
map.moveCamera()
causes my application to crash with the following stack:

Caused by: java.lang.IllegalStateException:
Map size should not be 0. Most likely, layout has not yet

at maps.am.r.b(Unknown Source)
at maps.y.q.a(Unknown Source)
at maps.y.au.a(Unknown Source)
at maps.y.ae.moveCamera(Unknown Source)
at com.google.android.gms.maps.internal.IGoogleMapDelegate$Stub
.onTransact(IGoogleMapDelegate.java:83)
at android.os.Binder.transact(Binder.java:310)
at com.google.android.gms.maps.internal.IGoogleMapDelegate$a$a
.moveCamera(Unknown Source)
at com.google.android.gms.maps.GoogleMap.moveCamera(Unknown Source)
at ShowMapActivity.drawMapMarkers(ShowMapActivity.java:91)
at ShowMapActivity.onResume(ShowMapActivity.java:58)
at android.app.Instrumentation
.callActivityOnResume(Instrumentation.java:1185)
at android.app.Activity.performResume(Activity.java:5182)
at android.app.ActivityThread
.performResumeActivity(ActivityThread.java:2732)


If - instead of the
newLatLngBounds()
factory method I use
newLatLngZoom()
method then the same trap does not occur.

Is the
onResume
the best place to draw the markers onto the GoogleMap object or should I be drawing the markers and setting the camera position somewhere else?

Lee Lee
Answer

OK I worked this out. As documented here that API can't be used pre-layout.

The correct API to use is described as:

Note: Only use the simpler method newLatLngBounds(boundary, padding) to generate a CameraUpdate if it is going to be used to move the camera after the map has undergone layout. During layout, the API calculates the display boundaries of the map which are needed to correctly project the bounding box. In comparison, you can use the CameraUpdate returned by the more complex method newLatLngBounds(boundary, width, height, padding) at any time, even before the map has undergone layout, because the API calculates the display boundaries from the arguments that you pass.

To fix the problem I calculated my screen size and provided the width and height to

public static CameraUpdate newLatLngBounds(
    LatLngBounds bounds, int width, int height, int padding)

This then allowed me to specify the bounding box pre-layout.