blob: 7a21485ed3d5fa29e0cb54bbf83ca8f3b79b9a73 [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001page.title=Hello, MapView
2parent.title=Hello, Views
3parent.link=index.html
4@jd:body
5
Dirk Doughertye1d9b552009-04-21 20:39:18 -07006<div class="special">
7<p>This tutorial requires that you have the Google Maps external library
Dirk Doughertyf11d7d52009-08-05 19:04:18 -07008installed in your SDK environment. By default the Android SDK includes the
Dirk Doughertye1d9b552009-04-21 20:39:18 -07009Google APIs add-on, which in turn includes the Maps external library. If you
10don't have the Google APIs SDK add-on, you can download it from this
11location:</p>
12
13<p style="margin-left:2em;"><a
14href="http://code.google.com/android/add-ons/google-apis">http://code.google.com/android/add-ons/google-apis</a></p>
15
16<p>The Google APIs add-on requires Android 1.5 SDK or later release. After
17installing the add-on in your SDK, set your project properties to use the build
18target called "Google APIs Add-on". See the instructions for setting a build
19target in <a href="{@docRoot}guide/developing/eclipse-adt.html">Developing in
20Eclipse with ADT</a> or <a
21href="{@docRoot}guide/developing/other-ide.html">Developing in Other IDEs</a>,
22as appropriate for your environment. </p>
23
24<p>You will also need to use the android tool to set up an AVD that uses the
25Google APIs deployment target. See <a
26href="{@docRoot}guide/developing/tools/avd.html">Android Virtual Devices</a> for
27more information. Once you have set up your environment, you will be able to
28build and run the project described in this tutorial</a></p>
29
30</div>
31
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080032<p>A MapView allows you to create your own map-viewing Activity.
33First, we'll create a simple Activity that can view and navigate a map. Then we will add some overlay items.</p>
34
35<ol>
36 <li>Start a new project/Activity called HelloMapView.
37
38 <li>Because we're using the Google Maps library,
39 which is not a part of the standard Android library, we need to
40 declare it in the Android Manifest. Open the AndroidManifest.xml
41 file and add the following as a child of the <code>&lt;application></code> element:
42
43 <pre>&lt;uses-library android:name="com.google.android.maps" /></pre>
44 </li>
45 <li>We also need access to the internet in order to retrieve the Google Maps tiles,
46 so the application must request the {@link android.Manifest.permission#INTERNET INTERNET} permissions.
47 In the manifest file, add the following as a child of the <code>&lt;manifest></code> element:
48 <pre>&lt;uses-permission android:name="android.permission.INTERNET" /></pre>
49 </li>
50 <li>Now open the main layout file for your project. Define a layout with a com.google.android.maps.MapView
51 inside a android.widget.RelativeLayout:
52
53<pre>
54&lt;?xml version="1.0" encoding="utf-8"?>
55&lt;RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
56 android:id="@+id/mainlayout"
57 android:orientation="vertical"
58 android:layout_width="fill_parent"
59 android:layout_height="fill_parent" >
60
61 &lt;com.google.android.maps.MapView
62 android:id="@+id/mapview"
63 android:layout_width="fill_parent"
64 android:layout_height="fill_parent"
65 android:clickable="true"
66 android:apiKey="<em>Your Maps API Key</em>"
67 />
68
69&lt;/RelativeLayout>
70</pre>
71 <p>The <code>clickable</code> attribute defines whether you want to allow user-interaction with the map.
72 In this case, we set it "true" so that the user can navigate.</p>
73
74 <p>The <code>apiKey</code> attribute holds the Google Maps API Key that proves your application and signer
75 certificate has been registered with the Google Maps service. Because MapView uses Google Maps data, this key is required
76 in order to receive the map data, even while you are developing. Registration is free and it only takes a couple
77 minutes to register your certificate and receive a Maps API Key. For instructions on getting a key, read
Dirk Dougherty392d29a2009-05-01 13:01:24 -070078 <a href="http://code.google.com/android/add-ons/google-apis/mapkey.html">Obtaining a Maps API Key</a>.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080079 (For the purpose of this tutorial, you should register with the fingerprint of the SDK debug certificate.)
80 Once you've acquired the Maps API Key, insert it for the <code>apiKey</code> value.</p></li>
81
82 <li>Now open the HelloMapView.java file. For this Activity, we're going to extend the special sub-class of
83 Activity called MapActivity, so change the class declaration to extend
84 MapActicity, instead of Activity:</p>
85
86 <pre>public class HelloMapView extends MapActivity {</pre>
87
88 <li>The <code>isRouteDisplayed()</code> method is required, so add it inside the class:
89<pre>
90&#64;Override
91protected boolean isRouteDisplayed() {
92 return false;
93}
94</pre>
95<p>You can actually run this now, but all it does is allow you to pan around the map.</p>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080096
97 <li>Now go back to the HelloMapView class. We'll now retrieve the ZoomControls object from
98 the MapView and add it to our new layout element. First, at the top of the HelloMapView,
99 instantiate handles for the MapView and LinearLayout, plus a ZoomControl object:
100<pre>
101LinearLayout linearLayout;
102MapView mapView;
Yusuf T. Mobile6ee299a2009-07-21 14:51:39 -0700103</pre>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800104
105 <li>Then initialize each of these in <code>onCreate()</code>. We'll capture the LinearLayout and
106 MapView through their layout resources. Then get the ZoomControls from the MapView::
107<pre>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800108mapView = (MapView) findViewById(R.id.mapview);
Yusuf T. Mobile6ee299a2009-07-21 14:51:39 -0700109mapView.setBuiltInZoomControls(true);
110</pre>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800111
Yusuf T. Mobile6ee299a2009-07-21 14:51:39 -0700112 <p>By using the built-in zoom control provided by MapView, we don't have to do any of the work
113 required to actually perform the zoom operations. The controls will appear whenever the user
114 touches the map, then disappear after a few moments of inactivity.</p></li>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800115
116 <li>Run it.</li>
117</ol>
118
119<hr/>
120
121<p>So, we now have full interaction controls. All well and good, but what we really want our map
122for is custom markers and layovers. Let's add some Overlay
123objects to our map. To do this, we're going to
124implement the ItemizedOverlay
125class, which can manage a whole set of Overlay items for us.</p>
126
127<ol>
128 <li>Create a new Java class named HelloItemizedOverlay that implements ItemizedOverlay.
129
130 <p>When using Eclipse, right-click the package name in the Eclipse Package Explorer, and select New > Class. Fill-in
131 the Name field as <em>HelloItemizedOverlay</em>. For the Superclass, enter
132 <em>com.google.android.maps.ItemizedOverlay</em>. Click the checkbox for <em>Constructors from
133 superclass</em>. Click Finish.</p></li>
134
135 <li> First thing, we need an OverlayItem ArrayList, in which we'll put each of the OverlayItem
136 objects we want on our map. Add this at the top of the HelloItemizedOverlay class:
137
138 <pre>private ArrayList&lt;OverlayItem> mOverlays = new ArrayList&lt;OverlayItem>();</pre></li>
139
140 <li>All the constructor does is define the default marker to be used on each of the OverlayItems.
141 In order for the Drawable to actually get drawn, it must have its bounds defined. And we want the
142 center-point at the bottom of the image to be the point at which it's attached to the map
143 coordinates. We handle all this with the boundCenterBottom() method. Wrap this around our
144 defaultMarker, so the super constructor call looks like this:
145
146 <pre>super(boundCenterBottom(defaultMarker));</pre></li>
147
148 <li>In order to add new OverlayItems to our ArrayList, we need a new public method. We'll handle
149 this with the following method:
150
151<pre>
152public void addOverlay(OverlayItem overlay) {
153 mOverlays.add(overlay);
154 populate();
155}</pre>
156
157 <p>Each time we add a new OverlayItem, we must call <code>populate()</code>, which will read each of out
158 OverlayItems and prepare them to be drawn.</p></li>
159
160 <li>In order for the <code>populate()</code> method to read each OverlayItem, it will make a request to
161 <code>createItem(int)</code>. We must define this method to properly read from our ArrayList. Replace the
162 existing contents of the createItem method with a <code>get()</code> call to our ArrayList:
163
164<pre>
165&#64;Override
166protected OverlayItem createItem(int i) {
167 return mOverlays.get(i);
168}
169</pre></li>
170
171 <li>We're also required to override the <code>size()</code> method. Replace the existing contents of the
172 method with a size request to our ArrayList:
173
174 <pre>return mOverlays.size();</pre></li>
175</ol>
176
177
178<p>That's it for the HelloItemizedOverlay class. We're now ready to use it.</p>
179
180<hr/>
181<p>Go back to the HelloMapView
182class. We'll start by creating one OverlayItem, adding to an instance of our HelloItemizedOverlay,
183and then adding this to the MapView.</p>
184
185<img src="images/androidmarker.png" align="right" />
186<p>First, we need the image that we'll use for our map overlay. Here, we'll use the Android on the
187right as our marker. Drag this image (or your own) to the res/drawable/ directory of your project workspace.</p>
188
189<p>Now we're ready to work in the HelloMapView:</p>
190
191<ol>
192 <li>First we need some more types. Add the following at the top of the HelloMapView class:
193
194<pre>
195List&lt;Overlay> mapOverlays;
196Drawable drawable;
197HelloItemizedOverlay itemizedOverlay;</pre></li>
198
199 <li>Now pick up where we left off in the <code>onCreate()</code> method. Instantiate the
200 new fields:
201
202<pre>
203mapOverlays = mapView.getOverlays();
204drawable = this.getResources().getDrawable(R.drawable.androidmarker);
205itemizedoverlay = new HelloItemizedOverlay(drawable);</pre>
206
207 <p>All overlay elements on a map are held by the MapView, so when we want to add some, we must
208 first retrieve the List with <code>getOverlays()</code> methods. We instantiate the Drawable, which will
209 be used as our map marker, by using our Context resources to get the Drawable we placed in
210 the res/drawable/ directory (androidmarker.png). Our HelloItemizedOverlay takes the Drawable in order to set the
211 default marker.</p></li>
212
213 <li>Now let's make our first OverlayItem by creating a GeoPoint
214 that defines our map coordinates, then pass it to a new OverlayItem:
215
216<pre>
217GeoPoint point = new GeoPoint(19240000,-99120000);
218OverlayItem overlayitem = new OverlayItem(point, "", "");</pre>
219
220 <p>GeoPoint coordinates are based in microdegrees (degrees * 1e6). The OverlayItem takes this
221 GeoPoint and two strings. Here, we won't concern ourselves with the strings, which can display
222 text when we click our marker, because we haven't yet written the click handler for the OverlayItem.</p></li>
223
224 <li>All that's left is for us to add this OverlayItem to our collection in the HelloItemizedOverlay,
225 and add this to the List of Overlay objects retrieved from the MapView:
226
227<pre>
228itemizedoverlay.addOverlay(overlayitem);
229mapOverlays.add(itemizedoverlay);</pre></li>
230
231 <li>Run it!</li>
232</ol>
233
234<p>We've sent our droid to Mexico City. Hola, Mundo!</p>
235<p>You should see the following:</p>
236<img src="images/hello-mapview.png" width="150px" />
237
238<p>Because we created our ItemizedOverlay class with an ArrayList, we can continue adding new
239OverlayItems. Try adding another one. Before the <code>addOverlay()</code> method is called, add these lines:</p>
240<pre>
241GeoPoint point2 = new GeoPoint(35410000, 139460000);
242OverlayItem overlayitem2 = new OverlayItem(point2, "", "");
243</pre>
244<p>Run it again... We've sent a new droid to Tokyo. Sekai, konichiwa!</p>
245