Using Google Maps in Android

来源:http://mobiforge.com/developing/story/using-google-maps-android?page=1

Google Maps is one of the many applications bundled with the Android platform. In addition to simply using the Maps application, you can also embed it into your own applications and make it do some very cool things. In this article, I will show you how to use Google Maps in your Android applications and how to programmatically perform the following:

  1. Change the views of Google Maps
  2. Obtain the latitude and longitude of locations in Google Maps
  3. Perform geocoding and reverse geocoding
  4. Add markers to Google Maps

Creating the Project


Using Eclipse, create a new Android project and nameGoogleMapsas shown in Figure 1.


Figure 1Creating a new Android project using Eclipse

Obtaining a Maps API key


Beginning with the Android SDK release v1.0, you need to apply for a free Google Maps API key before you can integrate Google Maps into your Android application. To apply for a key, you need to follow the series of steps outlined below. You can also refer to Google's detailed documentation on the process athttp://code.google.com/android/toolbox/apis/mapkey.html.

First, if you are testing the application on the Android emulator, locate the SDK debug certificate located in the default folder of"C:/Documents and Settings/<username>/Local Settings/Application Data/Android". The filename of the debug keystore isdebug.keystore. For deploying to a real Android device, substitute thedebug.keystorefile with your own keystore file. In a future article I will discuss how you can generate your own keystore file.

For simplicity, copy this file (debug.keystore) to a folder inC:/(for example, create a folder called "C:/Android").

Using the debug keystore, you need to extract its MD5 fingerprint using theKeytool.exeapplication included with your JDK installation. This fingerprint is needed to apply for the free Google Maps key. You can usually find theKeytool.exefrom the "C:/Program Files/Java/<JDK_version_number>/bin" folder.

Issue the following command (see also Figure 2) to extract the MD5 fingerprint.

keytool.exe -list -alias androiddebugkey -keystore "C:/android/debug.keystore" -storepass android -keypass android

Copy the MD5 certificate fingerprint and navigate your web browser to:http://code.google.com/android/maps-api-signup.html. Follow the instructions on the page to complete the application and obtain the Google Maps key.


Figure 2Obtaining the MD5 fingerprint of the debug keystore

To use the Google Maps in your Android application, you need to modify yourAndroidManifest.xmlfile by adding the<uses-library>element together with theINTERNETpermission:

<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android"      package="net.learn2develop.GoogleMaps"      android:versionCode="1"      android:versionName="1.0.0">    <application android:icon="@drawable/icon" android:label="@string/app_name">     <uses-library android:name="com.google.android.maps" />           <activity android:name=".MapsActivity"                  android:label="@string/app_name">            <intent-filter>                <action android:name="android.intent.action.MAIN" />                <category android:name="android.intent.category.LAUNCHER" />            </intent-filter>        </activity>    </application>     <uses-permission android:name="android.permission.INTERNET" /> </manifest></xml> 

Displaying the Map


To display the Google Maps in your Android application, modify themain.xmlfile located in theres/layoutfolder. You shall use the<com.google.android.maps.MapView>element to display the Google Maps in your activity. In addition, let's use the<RelativeLayout>element to position the map within the activity:

<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"     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="fill_parent"        android:enabled="true"        android:clickable="true"        android:apiKey="0l4sCTTyRmXTNo7k8DREHvEaLar2UmHGwnhZVHQ"        /> </RelativeLayout> 

Notice from above that I have used the Google Maps key that I obtained earlier and put it into theapiKeyattribute.

In theMapsActivity.javafile, modify the class to extend from theMapActivityclass, instead of the normalActivityclass:

package net.learn2develop.GoogleMaps; import com.google.android.maps.MapActivity;import com.google.android.maps.MapView;import android.os.Bundle; public class MapsActivity extends MapActivity {        /** Called when the activity is first created. */    @Override    public void onCreate(Bundle savedInstanceState)    {        super.onCreate(savedInstanceState);        setContentView(R.layout.main);    }     @Override    protected boolean isRouteDisplayed() {        return false;    }} 

Observe that if your class extends theMapActivityclass, you need to override theisRouteDisplayed()method. You can simply do so by setting the method to return false.

That's it! That's all you need to do to display the Google Maps in your application. PressF11in Eclipse to deploy the application onto an Android emulator. Figure 3 shows the Google map in all its glory.


Figure 3Google Maps in your application

At this juncture, take note of a few troubleshooting details. If your program does not run (i.e. it crashes), then it is likely you forgot to put the following statement in yourAndroidManifest.xmlfile:

    <uses-library android:name="com.google.android.maps" /> 

If your application manages to load but you cannot see the map (all you see is a grid), then it is very likely you do not have a valid Map key, or that you did not specify theINTERNETpermission:

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

Displaying the Zoom View


The previous section showed how you can display the Google Maps in your Android device. You can drag the map to any desired location and it will be updated on the fly. However, observe that there is no way to zoom in or out from a particular location. Thus, in this section, you will learn how you can let users zoom into or out of the map.

First, add a<LinearLayout>element to themain.xmlfile as shown below:

<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"     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="fill_parent"        android:enabled="true"        android:clickable="true"        android:apiKey="0l4sCTTyRmXTNo7k8DREHvEaLar2UmHGwnhZVHQ"        />     <LinearLayout android:id="@+id/zoom"         android:layout_width="wrap_content"         android:layout_height="wrap_content"         android:layout_alignParentBottom="true"         android:layout_centerHorizontal="true"         />  </RelativeLayout> 

You will use the<LinearLayout>element to hold the two zoom controls in Google Maps (you will see this shortly).

In theMapsActivity.javafile, add the following imports:

import com.google.android.maps.MapView.LayoutParams;  import android.view.View;import android.widget.LinearLayout;

and add the following code after the linesetContentView(R.layout.main);

 mapView = (MapView) findViewById(R.id.mapView);        LinearLayout zoomLayout = (LinearLayout)findViewById(R.id.zoom);          View zoomView = mapView.getZoomControls();          zoomLayout.addView(zoomView,             new LinearLayout.LayoutParams(                LayoutParams.WRAP_CONTENT,                 LayoutParams.WRAP_CONTENT));         mapView.displayZoomControls(true); 

The completeMapsActivity.javafile is given below:

package net.learn2develop.GoogleMaps; import com.google.android.maps.MapActivity;import com.google.android.maps.MapView;import com.google.android.maps.MapView.LayoutParams;   import android.os.Bundle;import android.view.View;import android.widget.LinearLayout; public class MapsActivity extends MapActivity {        MapView mapView;      /** Called when the activity is first created. */    @Override    public void onCreate(Bundle savedInstanceState)     {        super.onCreate(savedInstanceState);        setContentView(R.layout.main);          mapView = (MapView) findViewById(R.id.mapView);        LinearLayout zoomLayout = (LinearLayout)findViewById(R.id.zoom);          View zoomView = mapView.getZoomControls();          zoomLayout.addView(zoomView,             new LinearLayout.LayoutParams(                LayoutParams.WRAP_CONTENT,                 LayoutParams.WRAP_CONTENT));         mapView.displayZoomControls(true);     }     @Override    protected boolean isRouteDisplayed() {        // TODO Auto-generated method stub        return false;    }} 

Basically, you obtain theMapViewinstance on the activity, obtain its zoom controls and then add it to theLinearLayoutelement you added to the activity earlier on. In the above case, the zoom control will be displayed at the bottom of the screen. When you now pressF11in Eclipse, you will see the zoom controls when you touch the map (see Figure 4).


Figure 4Using the zoom controls in Google Maps

Using the zoom control, you can zoom in or out of a location by simply touching the "+ or "-" buttons on the screen.

Alternatively, you can also programmatically zoom in or out of the map using thezoomIn()andzoomOut()methods from theMapControllerclass:

package net.learn2develop.GoogleMaps; //...import android.os.Bundle;import android.view.KeyEvent; public class MapsActivity extends MapActivity {        MapView mapView;      public boolean onKeyDown(int keyCode, KeyEvent event)     {        MapController mc = mapView.getController();         switch (keyCode)         {            case KeyEvent.KEYCODE_3:                mc.zoomIn();                break;            case KeyEvent.KEYCODE_1:                mc.zoomOut();                break;        }        return super.onKeyDown(keyCode, event);    }         /** Called when the activity is first created. */    @Override    public void onCreate(Bundle savedInstanceState)     {        //...    }     @Override    protected boolean isRouteDisplayed() {        // TODO Auto-generated method stub        return false;    }} 

In the above code, when the user presses the number 3 on the keyboard the map will zoom in into the next level. Pressing number 1 will zoom out one level.

Changing Views of the Map


By default, the Google Maps displays in the map mode. If you wish to display the map in satellite view, you can use thesetSatellite()method of theMapViewclass, like this:

     mapView.setSatellite(true); 

You can also display the map in street view, using thesetStreetView()method:

  mapView.setStreetView(true); 

Figure 5 shows the Google Maps displayed in satellite and street views, respectively.


Figure 5Displaying Google Maps in satellite and street views

Displaying a Particular Location


Be default, the Google Maps displays the map of the United States when it is first loaded. However, you can also set the Google Maps to display a particular location. In this case, you can use theanimateTo()method of theMapControllerclass.

The following code shows how this is done:

package net.learn2develop.GoogleMaps; import com.google.android.maps.GeoPoint;import com.google.android.maps.MapActivity;import com.google.android.maps.MapController;import com.google.android.maps.MapView;import com.google.android.maps.MapView.LayoutParams; import android.os.Bundle;import android.view.View;import android.widget.LinearLayout; public class MapsActivity extends MapActivity {        MapView mapView;     MapController mc;    GeoPoint p;     /** Called when the activity is first created. */    @Override    public void onCreate(Bundle savedInstanceState)     {        super.onCreate(savedInstanceState);        setContentView(R.layout.main);         mapView = (MapView) findViewById(R.id.mapView);        LinearLayout zoomLayout = (LinearLayout)findViewById(R.id.zoom);          View zoomView = mapView.getZoomControls();          zoomLayout.addView(zoomView,             new LinearLayout.LayoutParams(                LayoutParams.WRAP_CONTENT,                 LayoutParams.WRAP_CONTENT));         mapView.displayZoomControls(true);         mc = mapView.getController();        String coordinates[] = {"1.352566007", "103.78921587"};        double lat = Double.parseDouble(coordinates[0]);        double lng = Double.parseDouble(coordinates[1]);         p = new GeoPoint(            (int) (lat * 1E6),             (int) (lng * 1E6));         mc.animateTo(p);        mc.setZoom(17);         mapView.invalidate();    }     @Override    protected boolean isRouteDisplayed() {        // TODO Auto-generated method stub        return false;    }} 

In the above code, you first obtain a controller from theMapViewinstance and assign it to aMapControllerobject (mc). You use aGeoPointobject to represent a geographical location. Note that for this class the latitude and longitude of a location are represented in micro degrees. This means that they are stored as integer values. For a latitude value of 40.747778, you need to multiply it by 1e6 to obtain 40747778.

To navigate the map to a particular location, you can use theanimateTo()method of theMapControllerclass (an instance which is obtained from the MapView object). ThesetZoom()method allows you to specify the zoom level in which the map is displayed. Figure 6 shows the Google Maps displaying the map of Singapore.


Figure 6Navigating to a particular location on the map

Adding Markers


Very often, you may wish to add markers to the map to indicate places of interests. Let's see how you can do this in Android. First, create a GIF image containing a pushpin (see Figure 7) and copy it into theres/drawablefolder of the project. For best effect, you should make the background of the image transparent so that it does not block off parts of the map when the image is added to the map.


Figure 7Adding an image to the res/drawable folder

To add a marker to the map, you first need to define a class that extends theOverlayclass:

package net.learn2develop.GoogleMaps; import java.util.List; import com.google.android.maps.GeoPoint;import com.google.android.maps.MapActivity;import com.google.android.maps.MapController;import com.google.android.maps.MapView;import com.google.android.maps.Overlay;import com.google.android.maps.MapView.LayoutParams; import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.graphics.Canvas;import android.graphics.Point;import android.os.Bundle;import android.view.View;import android.widget.LinearLayout; public class MapsActivity extends MapActivity {        MapView mapView;     MapController mc;    GeoPoint p;     class MapOverlay extends com.google.android.maps.Overlay    {        @Override        public boolean draw(Canvas canvas, MapView mapView,         boolean shadow, long when)         {            super.draw(canvas, mapView, shadow);                                //---translate the GeoPoint to screen pixels---            Point screenPts = new Point();            mapView.getProjection().toPixels(p, screenPts);             //---add the marker---            Bitmap bmp = BitmapFactory.decodeResource(                getResources(), R.drawable.pushpin);                        canvas.drawBitmap(bmp, screenPts.x, screenPts.y-50, null);                     return true;        }    }      /** Called when the activity is first created. */    @Override    public void onCreate(Bundle savedInstanceState)     {        //...    }     @Override    protected boolean isRouteDisplayed() {        // TODO Auto-generated method stub        return false;    }} 

In theMapOverlayclass that you have defined, override thedraw()method so that you can draw the pushpin image on the map. In particular, note that you need to translate the geographical location (represented by aGeoPointobject, p) into screen coordinates.

As you want the pointed tip of the push pin to indicate the position of the location, you would need to deduct the height of the image (which is 50 pixels) from the y-coordinate of the point (see Figure 8) and draw the image at that location.


Figure 8Adding an image to the map

To add the marker, create an instance of theMapOverlapclass and add it to the list of overlays available on theMapViewobject:

    @Override    public void onCreate(Bundle savedInstanceState)     {        super.onCreate(savedInstanceState);        setContentView(R.layout.main);         //...         mc.animateTo(p);        mc.setZoom(17);          //---Add a location marker---        MapOverlay mapOverlay = new MapOverlay();        List<Overlay> listOfOverlays = mapView.getOverlays();        listOfOverlays.clear();        listOfOverlays.add(mapOverlay);                 mapView.invalidate();    } 

Figure 9 shows how the pushpin looks like when added to the map.


Figure 9Adding a marker to the map

Getting the Location that was touched


After using Google Maps for a while, you may wish to know the latitude and longitude of a location corresponding to the position on the screen that you have just touched. Knowing this information is very useful as you can find out the address of a location, a process known as Geocoding (you will see how this is done in the next section).

If you have added an overlay to the map, you can override the onTouchEvent() method within theOverlayclass. This method is fired every time the user touches the map. This method has two parameters -MotionEventandMapView. Using theMotionEventparameter, you can know if the user has lifted his finger from the screen using thegetAction()method. In the following code, if the user has touched and then lifted his finger, you will display the latitude and longitude of the location touched:

class MapOverlay extends com.google.android.maps.Overlay { @Override public boolean draw(Canvas canvas, MapView mapView, boolean shadow, long when) { //... } @Override public boolean onTouchEvent(MotionEvent event, MapView mapView) { //---when user lifts his finger--- if (event.getAction() == 1) { GeoPoint p = mapView.getProjection().fromPixels( (int) event.getX(), (int) event.getY()); Toast.makeText(getBaseContext(), p.getLatitudeE6() / 1E6 + "," + p.getLongitudeE6() /1E6 , Toast.LENGTH_SHORT).show(); } return false; } }

  Figure 10 shows this in action.


Figure 10Displaying the latitude and longitude of a point touched on the map

Geocoding and Reverse Geocoding


If you know the latitude and longitude of a location, you can find out its address using a process known as Geocoding. Google Maps in Android supports this via theGeocoderclass. The following code shows how you can find out the address of a location you have just touched using thegetFromLocation()method:

class MapOverlay extends com.google.android.maps.Overlay { @Override public boolean draw(Canvas canvas, MapView mapView, boolean shadow, long when) { //... } @Override public boolean onTouchEvent(MotionEvent event, MapView mapView) { //---when user lifts his finger--- if (event.getAction() == 1) { GeoPoint p = mapView.getProjection().fromPixels( (int) event.getX(), (int) event.getY()); Geocoder geoCoder = new Geocoder( getBaseContext(), Locale.getDefault()); try { List<Address> addresses = geoCoder.getFromLocation( p.getLatitudeE6() / 1E6, p.getLongitudeE6() / 1E6, 1); String add = ""; if (addresses.size() > 0) { for (int i=0; i<addresses.get(0).getMaxAddressLineIndex(); i++) add += addresses.get(0).getAddressLine(i) + "/n"; } Toast.makeText(getBaseContext(), add, Toast.LENGTH_SHORT).show(); } catch (IOException e) { e.printStackTrace(); } return true; } else return false; } }

    Figure 11 shows the above code in action.


Figure 11Performing Geocoding in Google Maps

If you know the address of a location but want to know its latitude and longitude, you can do so via reverse-Geocoding. Again, you can use theGeocoderclass for this purpose. The following code shows how you can find the exact location of the Empire State Building by using thegetFromLocationName()method:

   Geocoder geoCoder = new Geocoder(this, Locale.getDefault());            try {            List<Address> addresses = geoCoder.getFromLocationName(                "empire state building", 5);            String add = "";            if (addresses.size() > 0) {                p = new GeoPoint(                        (int) (addresses.get(0).getLatitude() * 1E6),                         (int) (addresses.get(0).getLongitude() * 1E6));                mc.animateTo(p);                    mapView.invalidate();            }            } catch (IOException e) {            e.printStackTrace();        } 

Once the location is found, the above code navigates the map to the location. Figure 12 shows the code in action.


Figure 12Navigating to the Empire State Building

Summary


In this article, you have learnt a few tricks for the Google Maps in Android. Using Google Maps, there are many interesting projects you can work on, such as geo-tagging, geo-tracking, etc. If you have cool ideas on building cool location-based services, share with us in the comments box below. Have fun!

更多相关文章

  1. 用Javascript判断访问来源操作系统, 设备, 浏览器类型
  2. android-GooglePlay安装来源追踪PlayInstallReferrer
  3. 日常收集的Android开发资料来源
  4. 上百个android小项目源码(来源于网络)
  5. 在模仿中精进数据可视化02:温室气体排放来源可视化
  6. 在php中获取引荐来源网址(包括参数)
  7. 跟踪来自特定来源的用户
  8. 无法弄清楚mySQL语法错误的来源
  9. js 区分浏览器来源是PC端还是移动端

随机推荐

  1. 我可以禁用“后退”按钮浏览器功能吗?
  2. JavaScript实际应用:父子页面交互
  3. JavaScript - 检查是否在全局上下文中
  4. 将一个youtube iframe放在另一个具有关闭
  5. 隐藏时如何暂停jquery计时器
  6. res.json返回无意中修改的输入
  7. Aptana Studio 3 IDE中有运行JavaScript
  8. 使用异步库汇编数据库中的所有标记
  9. 在angularjs中动态添加/删除checked属性
  10. HTML最简单的隐藏/显示和类过滤器