MapView isn't very developer friendly now is it?
Here are some hacks I've had to work with:
1) When tapping on the overlay, the app crashes if you're trying to display the dialog.
Unable to add window -- token null is not for an application
Yes, this is due to context. Especially if you're trying to do this in a seperate thread or AsyncTask.
Turns out the context you need to pass to your dialog is mapView.getContext();
AlertDialog.Builder dialog = new AlertDialog.Builder(mapView.getContext());
2) Displaying only the overlays which are within map bounds
Oh yeah, several problems here. You've probably come across at least one of these:
- Wrong map bounds in onCreate (0, 360000000),
Yeah, in onCreate those haven't been calculated yet. onStart doesn't help either. Try this:
Runnable waitForMapTimeTask = new Runnable() {
public void run() {
if(mapView.getLatitudeSpan()==0||mapView.getLongitudeSpan()== 360000000) {
mapView.postDelayed(this, 100);
} else {
redrawMarkers(); // draw here
}
}
};
mapView.postDelayed(waitForMapTimeTask, 100);
You create a new thread and wait until you get the right bounds. Recursively call it again.
- Map bounds ???
Don't worry, it's simple.
public Rect getMapBounds() {
return new Rect(
mapView.getMapCenter().getLongitudeE6() - mapView.getLongitudeSpan()/2,
mapView.getMapCenter().getLatitudeE6() - mapView.getLatitudeSpan()/2,
mapView.getMapCenter().getLongitudeE6() + mapView.getLongitudeSpan()/2,
mapView.getMapCenter().getLatitudeE6() + mapView.getLatitudeSpan()/2
);
}
...
if(!s.drawn && rect.contains(point.getLongitudeE6(), point.getLatitudeE6())) {
- Yeah, okay, but what about panning / zooming?
Well, there are no methods, like onPan or onZoom, but some people found their way around this problem. There is no perfect solution, you'll see.
Check these links out:
- http://stackoverflow.com/questions/2328650/how-can-i-detect-if-an-android-mapview-has-been-panned-or-zoomed
- http://bricolsoftconsulting.com/2011/10/31/extending-mapview-to-add-a-change-event/
- http://stackoverflow.com/questions/3567420/how-to-catch-that-map-panning-and-zoom-are-really-finished
- Zoom in on double tap?
Click here: http://dev.kafol.net/2011/11/how-hard-is-it-to-make-simple-zoom-in.html.
- Overlays don't get drawn immediately!
Try this:
mapView.postInvalidate();
or this:
mapView.invalidate();
But keep in mind, that invalidate() needs to be called from an UI! If you're trying to get it working from a thread, use postInvalidate()!
- MapView java.util.ConcurrentModificationException when adding new overlays
Not sure if I solved this one, but it seems to work now. I read somewhere that this could happen if you add overlays in a non UI thread. I moved the
Nope, sorry, this one was my bad. I was doing some crazy async sorting and all hell broke loose.
itemizedOverlay.populateNow();
mapOverlays.add(itemizedOverlay);
mapView.postInvalidate();
From doInBackground to onPostExecute in AsyncTask.
You could also run something in a UI thread like this:
runOnUiThread(new Runnable() {
@Override
public void run() {
//do stuff here
}
});