Understanding Map View and Map Activity

A lot of the mapping technology in Android relies on the MapView UI control and an extension of android.app.Activity called MapActivity. The MapView and MapActivity classes take care of the heavy lifting when it comes to displaying and manipulating a map in Android. One of the things that you'll have to remember about these two classes is that they have to work together. Specifically, in order to use a MapView, you need to instantiate it within a MapActivity. In addition, when instantiating a MapView, you need to supply the map-api key. If you instantiate a MapView using an XML layout, you need to set the android:apiKey property. If you create a MapView programmatically, you have to pass the map-api key to the MapView constructor. Lastly, because the underlying data for the map comes from Google Maps, your application will need permission to access the Internet. This means you need at least the following permission request in your AndroidManifest. xml file:

<uses-permission android:name="android.permission.INTERNET" />

In fact, whenever you use location-based services (maps, GPS, and so on), you should include three permissions in your AndroidManifest.xml file (see Listing 7-11).

Listing 7-11. Minimum Required Permissions to Use Location-Based Services

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> <uses-permission android:name="android.permission.INTERNET" />

Recall from Table 7-2 that android.permission.ACCESS_FINE_LOCATION allows you to obtain "fine" location data such as GPS data. android.permission.ACCESS_COARSE_LOCATION allows you to obtain "coarse" location data, which includes WiFi location information. With the prerequisites out of the way, have a look at Figure 7-6.

Figure 7-6. AMapView control in street-view mode

Figure 7-6 shows an application that displays a map in street-view mode. The application also demonstrates how you can zoom in, zoom out, and change the map's view mode. The XML layout is shown in Listing 7-12.

Listing 7-12. XML Layout of MapView Demo

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent">

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

android:orientation="horizontal" android:layout_width="fill_parent" android:layout_height="wrap_content">

<Button android:id="@+id/zoomin" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="+"/>

<Button android:id="@+id/zoomout" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="-"/>

<Button android:id="@+id/sat" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Satellite"/>

<Button android:id="@+id/street" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Street"/>

<Button android:id="@+id/traffic" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Traffic"/>

</LinearLayout>

<com.google.android.maps.MapView android:id="@+id/mapview" android:layout_width="fill_parent" android:layout_height="wrap_content" android:apiKey="07vhL0usFXryRakmo2A4t8aKViWwKyGJGEDqpdg" />

</LinearLayout>

As shown in Listing 7-12, a parent LinearLayout contains a child LinearLayout and a MapView. The child LinearLayout contains the buttons shown at the top of Figure 7-6. Also note that you need to update the MapView control's android:apiKey value with the value of your own map-api key.

The code for our sample mapping application is shown in Listing 7-13.

Listing 7-13. The MapActivity Extension Class That Loads the XML Layout import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button;

import com.google.android.maps.MapActivity; import com.google.android.maps.MapView;

public class MapViewDemoActivity extends MapActivity {

private MapView mapView; ^Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState);

setContentView(R.layout.mapview);

mapView = (MapView)findViewById(R.id.mapview);

Button zoominBtn = (Button)findViewById(R.id.zoomin); Button zoomoutBtn = (Button)findViewById(R.id.zoomout);

Button satBtn = (Button)findViewByld(R.id.sat); Button streetBtn = (Button)findViewByld(R.id.street); Button trafficBtn = (Button)findViewByld(R.id.traffic);

// zoomin zoominBtn.setOnClickListener(new OnClickListener(){ ^Override public void onClick(View view) {

mapView.getController().zoomIn();

}}); // zoom out zoomoutBtn.setOnClickListener(new OnClickListener(){ ^Override public void onClick(View view) {

mapView.getController().zoomOut();

}}); // satellite satBtn.setOnClickListener(new OnClickListener(){ ^Override public void onClick(View view) {

mapView.setStreetView(false);

mapView.setTraffic(false);

mapView.setSatellite(true);

// street streetBtn.setOnClickListener(new OnClickListener(){ ^Override public void onClick(View view) {

mapView.setTraffic(false);

mapView.setSatellite(false);

mapView.setStreetView(true);

}}); // traffic trafficBtn.setOnClickListener(new OnClickListener(){

244 CHApTER 7 ■ EXpLORING SECURITY AND LOCATION-BASED SERVICES

^Override public void onClick(View view) {

mapView.setSatellite(false);

mapView.setStreetView(false);

mapView.setTraffic(true);

^Override protected boolean isRouteDisplayed() { return false;

As shown in Listing 7-13, displaying the MapView using onCreate() is no different from displaying any other control. That is, you set the content view of the UI to a layout file that contains the MapView, and that takes care of it. Suprisingly, supporting zoom features is also fairly easy. To zoom in or zoom out, you use the MapController class of the MapView. Do this by calling mapView.getController() and then calling the approproiate zoomIn() or zoomOut() method. Zooming this way produces a one-level zoom; users need to repeat the action to increase the amount of magnification or reduction.

You'll also find it straightforward to offer the ability to change view modes. The MapView supports several modes: map, street, satellite, and traffic. Map is the default mode. Street mode places a layer on top of the map that contains street information such as road names. Satellite mode shows the map in satellite view. Traffic mode shows traffic information on the map. Note that traffic mode is supported on a limited number of major highways. To change modes, you must call the appropriate setter method with true and set the other modes to false. The reason for this is that one mode can overlay another mode. For example, you can overlay satellite and street modes one on top of the other.

You'll probably agree that the amount of code required to display a map and to implement zoom and mode changes is minimal with Android (see Listing 7-13). Android's mapping capability is definitely unbeatable. It might come as a shock to some of you that the code gets even easier. Take a look at the XML layout and code shown in Listing 7-14.

Listing 7-14. Zooming and Panning Made Easier

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent">

<com.google.android.maps.MapView android:id="@+id/mapview" android:layout_width="fill_parent" android:layout_height="wrap_content" android:apiKey="07vhL0usFXryRakmo2A4t8aKViWwKyGJGEDqpdg" />

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/zoomCtrls"

android:orientation="horizontal" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_alignParentBottom="true">

</LinearLayout> </RelativeLayout>

public class MapViewDemoActivity extends MapActivity {

private MapView mapView;

^Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState);

setContentView(R.layout.mapview);

mapView = (MapView)findViewById(R.id.mapview);

LinearLayout layout = (LinearLayout)findViewById(R.id.zoomCtrls); layout.addView(mapView.getZoomControls());

mapView.setClickable(true);

^Override protected boolean isRouteDisplayed() { return false;

The difference between Listing 7-14 and Listing 7-13 is that we changed the XML layout for our view to use RelativeLayout. We removed all the zoom controls and view-mode controls and replaced them with an empty LinearLayout oriented at the bottom of the screen. The magic in this example is in the code and not the layout. Specifically, notice that we populated the LinearLayout with mapView.getZoomControls(). This means that the MapView already has controls that allow you to zoom in and out. All you have to do is get a reference to the controls and then add it to your view (wherever you want it). Figure 7-7 shows the MapView's default zoom controls.

We are not done yet. The MapView control is very powerful. The last line in the onCreate() method of Listing 7-14 calls mapView.setClickable(true). This, in fact, enables panning of the map.

Now let's learn how to add custom data to the map.

Figure 7-7. The MapView's built-in zoom controls
+1 0

Responses

  • beau
    How to zoom in and zoom out of opengl?
    7 years ago

Post a comment