It is a rather common case that an Android application uses maps to provide a functionality, which depends on a geographical location. Our “My Seven Wonders” application was not an exception – the user should be able to define geographical locations of targets he will see on the compass. We decided to go with a minimalistic interface of a location selection:
* the world map is displayed
* the user can scroll and zoom through the map to find the required location
* the user can tap on a desired point to define a precise location. The selected location is represented by a flag sign.

Android Maps API gives all the required tools to make this task as simple as possible, but as with any (for the first sight) simple task some tricks may be required to achieve a perfect result. We will explain some of them here.
Note: Before running the provided example, you will need to specify the debug API key in android:apiKey attribute from the res/layout/map.xml. The details on map API keys generation are available in http://code.google.com/intl/en-EN/android/add-ons/google-apis/mapkey.html
To display a map we will use the MapView from Android Maps API. The MapView usage is thoroughly explained in the Android documentation, just do not forget to add the uses-library (com.google.android.maps) and uses-permission (android.permission.INTERNET) tags in the appropriate places of your AndroidManifest.xml file.
To draw our own flag pointer we will use the overlays feature of the MapView. Our LocationOverlay class will draw a flag as a bitmap on a provided canvas. In this class we will also handle the onTap event, where we will reposition the flag and animate the map to the tapped point.
The MapView from Android API allows zoom in and out using multi touch. When the user makes the zoom using multi-touch, the tap event is also received, so after the multi touch zoom is performed the flag will jump into undesired location. Such behavior may confuse the user. Therefore we will disable multi touch zooming by overriding dispatchTouchEvent method in our MapDisplay class.
Though we disabled the multi touch zooming, we anyway need the user be able to zoom on the map. Android MapView features the built in zoom controls, which are shown, when we tap on a map screen once. The problem is, when we will tap on a screen, our flag will jump to the position we tapped – this is not what we want to happen. To workaround this we will make our own zoom controls, which will be always visible to the user. Android API has appropriate widget available, so it is an easy task. You can look at MapDisplay.onCreate method to see how this is accomplished.
There is one more thing where custom zoom controls may be handy. MapActivity loads a lot of scenery images, when you zoom on the map. If there will be a lot of zooming actions it is easy to get OutOfMemory error (especially when other activities of your application use the memory extensively). Since we have our own zoom controls, we may minimize the possibility of OutOfMemory by explicitly requesting garbage collection during every zoom in MapDisplay.onZoom method. Also, we will catch the OutOfMemory error here (in case it will appear anyhow).
Now everything is fine, but there is one more thing we need to take care about. When the user will change the orientation of the phone while searching for desired location, the map activity will be restarted and currently visible map area will be replaced by the default the user saw when he first started the activity. To avoid the user be frustrated with this, we should remember current flag position, current map center and current zoom level, when the activity is reloaded.

This is achieved by overriding onSaveInstanceState and onRestoreInstanceState methods. The GeoPoint object is not Parcelable so we will get its latitude and longitude and store them as an int array, when saving the state.
What we got finally is a geographic location selection activity. We can tap on a screen and the flag will jump to the tapped point. If we will scroll/zoom a map or change the phone orientation the flag will stay at the previously defined position.