Uso de la API com.google.android.maps, tengo una MapActivity
que utiliza ItemizedOverlay
colocar varios (hasta 1000) iconos en un MapView
. Quiero actualizar (o quizás solo agregar a la lista de) los íconos cuando el LocationListener
detecta que el dispositivo se ha movido a cierta distancia (actualmente 5 metros, pero eso es solo para probar).mapa refrescante ItemizedOverlay da ArrayIndexOutOfBoundsException
He añadido setLastFocusedIndex(-1)
y populate()
, pero mi ItemizedOverlay sigue estrelándose. Creo que está fallando cuando agrego más elementos a la lista, pero a veces parece fallar incluso si no muevo mi teléfono. Se bloquea en la primera actualización. No puedo decir desde LogCat exactamente qué desencadena el error.
Mi MapActivity está basada en varios tutoriales:
EDIT: ajustados código para hacer un batch update of items pero todavía falla
public class NearbyActivity extends MapActivity implements VenueCatalogListener {
private final String TAG = this.getClass().getSimpleName();
List<Overlay> mapOverlays;
HelloItemizedOverlay itemizedOverlay;
private MapController mapController;
private MapView mapView;
private LocationManager locationManager;
private int latE6;
private int lonE6;
private Location current_location;
private VenuesFromServer venues_from_server;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
venues_from_server = new VenuesFromServer(this);
setupViews();
}
private void setupViews() {
setContentView(R.layout.nearby_view);
RelativeLayout linearLayout = (RelativeLayout) findViewById(R.id.mapMainLayout);
mapView = new MapView(this, PreferencesManager.CLUBBERIA_MAPS_API_KEY);
initializeMap();
linearLayout.addView(mapView);
}
private void initializeMap() {
mapView.setKeepScreenOn(true);
mapView.setClickable(true);
mapView.setBuiltInZoomControls(true);
mapController = mapView.getController();
mapController.setZoom(mapView.getMaxZoomLevel()-5); // Zoom 1 is world view
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, new GeoUpdateHandler());
mapOverlays = mapView.getOverlays();
if(itemizedOverlay == null) {
Drawable drawable = this.getResources().getDrawable(R.drawable.icon);
itemizedOverlay = new HelloItemizedOverlay(drawable);
mapOverlays.add(itemizedOverlay);
}
}
@Override
protected boolean isRouteDisplayed() {
return false;
}
public class GeoUpdateHandler implements LocationListener {
@Override
public void onLocationChanged(Location location) {
if(current_location == null) {
current_location = location;
}
int lat = (int) (location.getLatitude() * 1E6);
int lng = (int) (location.getLongitude() * 1E6);
GeoPoint point = new GeoPoint(lat, lng);
if(current_location.distanceTo(location) > 5) {
// this kicks off an async task that will call back to venueListUpdated() below
venues_from_server.getVenueJSONFromServer(location.getLatitude(), location.getLongitude(), 19);
}
mapController.animateTo(point); // mapController.setCenter(point);
}
@Override
public void onProviderDisabled(String provider) {
}
@Override
public void onProviderEnabled(String provider) {
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
}
@Override
public void venueListUpdated() {
// Base.B.arrayVenuesMap is an ArrayList<Venue>
for(int i=0;i<Base.B.arrayVenuesMap.size();i++) {
Venue _venue = Base.B.arrayVenuesMap.get(i);
latE6 = (int) (_venue.latitude*1e6);
lonE6 = (int) (_venue.longitude*1e6);
GeoPoint point = new GeoPoint(latE6, lonE6);
OverlayItem overlayitem = new OverlayItem(point, _venue.name, "");
Drawable drawable = this.getResources().getDrawable(R.drawable.icon);
itemizedOverlay.addOverlay(overlayitem, drawable);
}
itemizedOverlay.batchPopulate();
}
}
Mi ItemizedOverlay se parece a esto:
public class HelloItemizedOverlay extends ItemizedOverlay<OverlayItem> {
private ArrayList<OverlayItem> mOverlays = null;
public HelloItemizedOverlay(Drawable defaultMarker) {
super(boundCenterBottom(defaultMarker));
mOverlays = new ArrayList<OverlayItem>();
setLastFocusedIndex(-1);
populate();
}
public void addOverlay(OverlayItem overlay, Drawable defaultMarker) {
if(!mOverlays.contains(overlay)) {
setLastFocusedIndex(-1);
overlay.setMarker(boundCenterBottom(defaultMarker));
mOverlays.add(overlay);
}
}
public void batchPopulate() {
setLastFocusedIndex(-1);
populate();
}
@Override
protected OverlayItem createItem(int i) {
return mOverlays.get(i);
}
@Override
public int size() {
return mOverlays.size();
}
}
Logcat presenta las siguientes líneas:
11-24 18:28:02.245: D/AsyncJSONClient(18382): starting connect with this many pairs: 0; thread 17
11-24 18:28:02.255: E/AndroidRuntime(18382): FATAL EXCEPTION: main
11-24 18:28:02.255: E/AndroidRuntime(18382): java.lang.ArrayIndexOutOfBoundsException
11-24 18:28:02.255: E/AndroidRuntime(18382): at com.google.android.maps.ItemizedOverlay.getIndexToDraw(ItemizedOverlay.java:211)
11-24 18:28:02.255: E/AndroidRuntime(18382): at com.google.android.maps.ItemizedOverlay.draw(ItemizedOverlay.java:240)
11-24 18:28:02.255: E/AndroidRuntime(18382): at com.google.android.maps.Overlay.draw(Overlay.java:179)
11-24 18:28:02.255: E/AndroidRuntime(18382): at com.google.android.maps.OverlayBundle.draw(OverlayBundle.java:42)
11-24 18:28:02.255: E/AndroidRuntime(18382): at com.google.android.maps.MapView.onDraw(MapView.java:530)
11-24 18:28:02.255: E/AndroidRuntime(18382): at android.view.View.draw(View.java:6918)
11-24 18:28:02.255: E/AndroidRuntime(18382): at android.view.ViewGroup.drawChild(ViewGroup.java:1646)
11-24 18:28:02.255: E/AndroidRuntime(18382): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1373)
11-24 18:28:02.255: E/AndroidRuntime(18382): at android.view.ViewGroup.drawChild(ViewGroup.java:1644)
11-24 18:28:02.255: E/AndroidRuntime(18382): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1373)
11-24 18:28:02.255: E/AndroidRuntime(18382): at android.view.View.draw(View.java:6921)
11-24 18:28:02.255: E/AndroidRuntime(18382): at android.widget.FrameLayout.draw(FrameLayout.java:357)
11-24 18:28:02.255: E/AndroidRuntime(18382): at android.view.ViewGroup.drawChild(ViewGroup.java:1646)
11-24 18:28:02.255: E/AndroidRuntime(18382): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1373)
11-24 18:28:02.255: E/AndroidRuntime(18382): at android.view.ViewGroup.drawChild(ViewGroup.java:1644)
11-24 18:28:02.255: E/AndroidRuntime(18382): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1373)
11-24 18:28:02.255: E/AndroidRuntime(18382): at android.view.ViewGroup.drawChild(ViewGroup.java:1644)
11-24 18:28:02.255: E/AndroidRuntime(18382): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1373)
11-24 18:28:02.255: E/AndroidRuntime(18382): at android.view.ViewGroup.drawChild(ViewGroup.java:1644)
11-24 18:28:02.255: E/AndroidRuntime(18382): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1373)
11-24 18:28:02.255: E/AndroidRuntime(18382): at android.view.ViewGroup.drawChild(ViewGroup.java:1644)
11-24 18:28:02.255: E/AndroidRuntime(18382): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1373)
11-24 18:28:02.255: E/AndroidRuntime(18382): at android.view.View.draw(View.java:6921)
11-24 18:28:02.255: E/AndroidRuntime(18382): at android.widget.FrameLayout.draw(FrameLayout.java:357)
11-24 18:28:02.255: E/AndroidRuntime(18382): at android.view.ViewGroup.drawChild(ViewGroup.java:1646)
11-24 18:28:02.255: E/AndroidRuntime(18382): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1373)
11-24 18:28:02.255: E/AndroidRuntime(18382): at android.view.View.draw(View.java:6921)
11-24 18:28:02.255: E/AndroidRuntime(18382): at android.widget.FrameLayout.draw(FrameLayout.java:357)
11-24 18:28:02.255: E/AndroidRuntime(18382): at com.android.internal.policy.impl.PhoneWindow$DecorView.draw(PhoneWindow.java:1947)
11-24 18:28:02.255: E/AndroidRuntime(18382): at android.view.ViewRoot.draw(ViewRoot.java:1539)
11-24 18:28:02.255: E/AndroidRuntime(18382): at android.view.ViewRoot.performTraversals(ViewRoot.java:1275)
11-24 18:28:02.255: E/AndroidRuntime(18382): at android.view.ViewRoot.handleMessage(ViewRoot.java:1876)
11-24 18:28:02.255: E/AndroidRuntime(18382): at android.os.Handler.dispatchMessage(Handler.java:99)
11-24 18:28:02.255: E/AndroidRuntime(18382): at android.os.Looper.loop(Looper.java:123)
11-24 18:28:02.255: E/AndroidRuntime(18382): at android.app.ActivityThread.main(ActivityThread.java:3728)
11-24 18:28:02.255: E/AndroidRuntime(18382): at java.lang.reflect.Method.invokeNative(Native Method)
11-24 18:28:02.255: E/AndroidRuntime(18382): at java.lang.reflect.Method.invoke(Method.java:507)
11-24 18:28:02.255: E/AndroidRuntime(18382): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:864)
11-24 18:28:02.255: E/AndroidRuntime(18382): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:622)
11-24 18:28:02.255: E/AndroidRuntime(18382): at dalvik.system.NativeStart.main(Native Method)
11-24 18:28:02.255: W/ActivityManager(308): Force finishing activity com.clubberia.android/.ClubberiaMain
¿Cómo puedo ocasionalmente agregar elementos a ItemizedOverlay sin bloqueos?
. Acabo de probar tu sugerencia, pero no funcionó. ¡Gracias de cualquier manera! –
Genial, lo siento, no funcionó, ya resolvió el problema en el pasado. – cgwyllie