Android Google Map API 开发

开发基于谷歌地图的应用和普通的android应用差不多都要使用它提供给我们的类库,所不同的是google map的类库不是android平台的基本类库,是google api的一部分,所以建立项目时,SDK要选择Google APIs;

还有一点,开发基于地图的应用时候需要使用google map的APIkey,必须先申请key,然后才能开发基于地图的应用。

下边分步骤记录下,整个过程:

一、申请google Maps API key(用于开发和debug)

为了能顺利的申请Android Map API Key,必须要准备google的账号和系统的证明书。一般Google发布Key都需要Google账号,Google账号是通用的,Gmail的账号就可以。当一个程序发布时必须要证明书,证明书其实就是MD5.我们这里并不是发布,而只是为了开发测试,可以使用Debug版的证明书,下面我们就来学习如何申请Debug版的Key:

1.找到你的debug.keystore文件

在Eclipse工具下,选择windows-->Preference-->Android-->Build,其中Default debug keystore的值便是debug.keystore的路径了。

2.取得debug.keystore的MD5值

首先cmd命令行进入debug.keystore文件所在的路径,执行命令:keytool -list -v -keystore debug.keystore,这时可能会提示你输入密码,这里默认的密码是“android",这样即可取得MD5值。

3.申请Android Map 的API Key.

打开浏览器,输入网址:http://code.google.com/android/maps-api-signup.html,填入你的认证指纹(MD5)即可获得apiKey了,结果显示如下:

感谢您注册 Android 地图 API 密钥!
您的密钥是:
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
我IE打开的时候是乱码,不知道是不是自己电脑有问题。后来改用了chrome就正常显示了(在国内一般需要翻*qiang才能正常打开)。

到此,我们就完成了API Key的申请了,记录下Key值,在后续开发中使用。(放在layout中加入的MapView中)

二.Google Map API的使用

Android中定义了一个名为com.google.android.map的包,其中包含了一系列用于在google map上显示、控制和叠层信息的功能类,以下是该包中最重要的几个类:

1.MapActivity:这个类是用于显示Google Map的Activity类,它需要连接底层网络。MapActivity是一个抽象类,任何想要显示MapView的activity都需要派生自MapActivity,并且在其派生类的onCreate()中,都要创建一个MapView实例。

2.MapView:MapView是用于显示地图的View组件。它派生自android.view.ViewGroup。它必须和MapActivity配合使用,而且只能被MapActivity创建,这是因为MapView需要通过后台的线程来连接网络或者文件系统,而这些线程需要有MapActivity来管理。

3.MapController:MapController用于控制地图的移动、缩放等。

4.OverLay:这是一个可显示于地图之上的可绘制的对象。

5.GeoPoint:这是一个包含经纬度位置的对象。

三.实例开发

1.创建工程,注意SDK选择为"Goolge APIs”

2.修改AndroidManifest.xml文件

由于使用Google Map API,所以必须添加<uses-library android:name="com.google.android.maps" />

由于需要从网络获取地图数据,所以需要访问网络的权限<uses-permission android:name="android.permission.INTERNET"/>

可能还需要添加其他权限。

例如:

AndroidManifest.xml
<? xml version = " 1.0 " encoding = " utf-8 " ?>
< manifest xmlns:android = " http://schemas.android.com/apk/res/android "
package
= " com.yarin.android.Examples_09_03 "
android:versionCode
= " 1 "
android:versionName
= " 1.0 " >
< application android:icon = " @drawable/icon " android:label = " @string/app_name " >
< uses - library android:name = " com.google.android.maps " />
< activity android:name = " .Activity01 "
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 " />
< uses - sdk android:minSdkVersion = " 5 " />
</ manifest >

3.创建MapView

要显示地图,需要创建一个MapView,在Xml文件中的布局如下。其中的android:apiKey的值就是我们第一步申请的Key了。

main.xml
<? 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/MapView01 "
android:layout_width
= " fill_parent "
android:layout_height
= " fill_parent "
android:apiKey
= " 0AubmfALdupLSlQkE67OTXgcQgWtyhXcO7uhsIQ " />
</ RelativeLayout >

当然,可以在程序中通过如下代码来创建MapView:

MapView map = new MapView( this, "(android maps api key)");

4.实现MapActivity

MapView需要由MapActivity来管理,所以程序部分应该继承自MapActivity类,必须实现isRouteDisplay方法。

MapView提供了3中模式的地图,分别可以通过以下方式设置采用什么模式来显示地图。

mMapView.setTraffic(true); //设置为交通模式

mMapView.setSatellite(true); //设置为卫星模式//

mMapView.setStreetView(false); //设置为街景模式

通过setBuiltZoomControls方法设置地图是否支持缩放。

5.MapController的使用

如果需要设置地图显示的地点以及放大倍数等,就需要使用MapController来控制地图。可以通过如下代码获得MapController对象:

mMapController = mMapView.getController();

要定位地点,需要构造一个GeoPoint来表示地点的经纬度,然后使用animateTo方法将地图定位到指定的GeoPoint上,代码如下:

// 设置起点为成都
//关于地址坐标可到以下网址获取
//http://www.mygeoposition.com/
mGeoPoint = new GeoPoint(( int ) ( 30.659259 * 1000000 ), ( int ) ( 104.065762 * 1000000 ));
// 定位到成都
mMapController.animateTo(mGeoPoint);

6.Ovelay的使用

如果需要在地图上标注一些图标文字等信息,就需要使用Overlay。这里我们首先要将地图上的经度和纬度转换成屏幕上的实际坐标,才能将信息绘制上去。Map API中提供了Projection.toPixels(GeoPoint in,GeoPoint out)方法,可以将经度和纬度转换成屏幕上的坐标。

7.getFromLocation的使用(搜索)

public List

getFromLocation(double latitude, double longitude, int maxResults)

根据给定的经纬度返回一个描述此区域的地址数组。返回的地址将根据构造器提供的语言环境进行本地化。

返回值有可能是通过网络获取。返回结果是一个最好的估计值,但不能保证其完全正确。

参数

  latitude 纬度

  longitude经度

maxResults要返回的最大结果数,推荐1~5

返回值

  一组地址对象。如果没找到匹配项,或者后台服务无效的话则返回null或者空序列。

异常

IllegalArgumentException 纬度小于-90或者大于90

IllegalArgumentException 果经度小于-180或者大于180

IOException 如果没有网络或者IO错误

public List

getFromLocationName(String locationName, int maxResults, double lowerLeftLatitude, double lowerLeftLongitude, double upperRightLatitude, double upperRightLongitude)

返回一个由给定的位置名称参数所描述的地址数组。名称参数可以是一个位置名称,如:“Dalvik, Iceland”,一个地址,如:“1600 Amphitheatre Parkway, Mountain View, CA”,一个机场代号,如:“SFO”,等等……返回的地址将根据构造器提供的语言环境进行本地化。

你也可以指定一个搜索边界框,该边界框由左下方坐标经纬度和右上方坐标经纬度确定。

返回值有可能是通过网络获取。返回结果是一个最好的估计值,但不能保证其完全正确。通过UI主线程的后台线程来调用这个方法可能更加有用。

参数

locationName 用户提供的位置描述

maxResults要返回的最大结果数,推荐1~5

lowerLeftLatitude左下角纬度,用来设定矩形范围

lowerLeftLongitude左下角经度,用来设定矩形范围

upperRightLatitude右上角纬度,用来设定矩形范围

upperRightLongitude右上角经度,用来设定矩形范围

返回值

一组地址对象。如果没找到匹配项,或者后台服务无效的话则返回null或者空序列。

异常

IllegalArgumentException如果位置描述为空

IllegalArgumentException如果纬度小于-90或者大于90

IllegalArgumentException如果经度小于-180或者大于180

IOException如果没有网络或者IO错误

 

最终效果图

 

全部代码如下:

 
package com.demo.zjmap;

import java.io.IOException;
import java.util.List;
import java.util.Locale;

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.MyLocationOverlay;
import com.google.android.maps.Overlay;

import android.app.Activity;
//import android.content.DialogInterface.OnClickListener;
import android.location.Address;
import android.location.Geocoder;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.TextView;
import android.widget.Toast;

@SuppressWarnings("unused")
public class ZjmapActivity extends MapActivity {
 

//确定按钮
 private Button button1;
 //定位按钮

 private Button mylocation_button;
 private TextView mTextView1;
 private EditText input_add;
    private MapView map;
    private MapController mc;

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle icicle) {
        super.onCreate(icicle);
        setContentView(R.layout.main);
        findViews();
        initmap();
        setupMap();
        input_add=(EditText)findViewById(R.id.input);

       button1 = (Button)findViewById(R.id.search);
       mylocation_button = (Button)findViewById(R.id.location);
       button1.setOnClickListener(find_add);
       mylocation_button.setOnClickListener(mylocation);
       onSearchRequested();
    }

 private void findViews()
    {
     map=(MapView) findViewById(R.id.map);
     mc = map.getController();
    }
 
 //初始化地图
 private void initmap(){
  GeoPoint station_zj = new GeoPoint(
       (int) (30.170304 * 1000000),
       (int) (120.073249 * 1000000)
       );
     //map.setTraffic(true);
  map.setStreetView(true);
     map.setBuiltInZoomControls(true);
     mc.setZoom(15);
     mc.animateTo(station_zj);
 }
 
    //地图图层
 private MyLocationOverlay mylayer;
 
 @SuppressWarnings("deprecation")
 private void setupMap() {
  
     //mc.animateTo(station_zj);
  
  List<Overlay> overlays=map.getOverlays();
  mylayer=new MyLocationOverlay(this,map);
  mylayer.runOnFirstFix(new Runnable() {
   public void run() {
    //map.setTraffic(true);
    map.setStreetView(true);
    mc.setZoom(17);
    mc.animateTo(mylayer.getMyLocation());
   }   
  });
  overlays.add(mylayer);}
 
  @Override
  protected void onResume() {
   super.onResume();
   mylayer.enableMyLocation();    
  }
  @Override
  protected void onStop() {   
   mylayer.disableMyLocation();
   super.onStop(); 
  }
        

//搜索模块
 private String performGeocode(String in)  //输入地址信息获取经纬度
 {
  String result = "无法搜索到" + in;
  Location location = getlocation();
  double lat = (int)(location.getLatitude());
  double lon = (int)(location.getLongitude());
  //Geocoder mygeoCoder = new Geocoder(this,Locale.getDefault());
  Geocoder mygeoCoder = new Geocoder(getBaseContext(),Locale.CHINA);
  try {
   //设置搜索范围为当前位置 lat-1 lon-1 lat +1 lon +1 矩形之内
   List<Address> lstAddress =
     mygeoCoder.getFromLocationName(in, 1,lat-1,lon-1,lat+1,lon+1);
   
   if( !lstAddress.isEmpty())
   {
    Toast.makeText(getApplicationContext(), "正在搜索"+in, Toast.LENGTH_LONG).show();
    Address address = lstAddress.get(0);
    lat = address.getLatitude()*1E6;
    lon = address.getLongitude()*1E6;
    GeoPoint geopoint = new GeoPoint((int)lat,(int)lon);   
    mc.animateTo(geopoint); 
   } 
  } catch (IOException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
   Toast.makeText(getApplicationContext(), "搜索不到"+in, Toast.LENGTH_LONG).show();
  }
  return result;
 }
  
  //搜索按键监听动作
    private OnClickListener find_add = new OnClickListener() {
  
  public void onClick(View v) {
   // TODO Auto-generated method stub
   //EditText inputadd = (EditText) findViewById(R.id.add);
   //mTextView1.setText("Hi,Everyone!");
   performGeocode(input_add.getText().toString());
  }
 };
 
 //获取当前经纬度
 private Location getlocation()
 {   
  LocationManager mgr;
  mgr = (LocationManager) getSystemService(LOCATION_SERVICE);
  Location location = mgr.getLastKnownLocation("gps");
  return location;
 }
 //定位按键监听动作
    private OnClickListener mylocation = new OnClickListener() {
  
  @SuppressWarnings("null")
  public void onClick(View v) {
   // TODO Auto-generated method stub

   LocationManager mgr;
   mgr = (LocationManager) getSystemService(LOCATION_SERVICE);
   Location location = mgr.getLastKnownLocation("gps");
   if(location !=null)
   {
    updateToNewLocation(location);
   }
   else
   {
    Toast.makeText(getApplicationContext(), "无法定位,确认开启GPS...", Toast.LENGTH_LONG).show();
   }
    setupMap();
   //mylayer.enableMyLocation();
   //locationlistener.onLocationChanged(location);
  }
   
 };
 //更新地图为当前位置
 private void updateToNewLocation(Location location) {
  
  if(location != null)
  {
   int lat = (int)(location.getLatitude()*1000000);
   int lon = (int)(location.getLongitude()*1000000);
   GeoPoint geoPoint = new GeoPoint(lat,lon);
   //map.setTraffic(true);
      //mc.setZoom(17);
      mc.animateTo(geoPoint);
      //mgr.removeUpdates((location));
      Toast.makeText(getApplicationContext(), "正在定位...", Toast.LENGTH_LONG).show();
  }
  else
  {
   Toast.makeText(getApplicationContext(), "No location found", Toast.LENGTH_LONG).show();
  }
 }

 @Override
 protected boolean isRouteDisplayed() {
  // TODO Auto-generated method stub
  return false;
 }
}

 

 Manifest.xml代码如下:
 

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.demo.zjmap"
    android:versionCode="1"
    android:versionName="1.0" >
    <!--
 <meta-data
             android:name="android.app.default_searchable"
             android:value="*" />
  -->
    <uses-sdk android:minSdkVersion="7"
          android:targetSdkVersion="10"/>
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
    <uses-permission android:name="android.permission.INTERNET"/>

    <application
       
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name" >
        <uses-library android:name="com.google.android.maps"/>
        <activity
            android:name=".ZjmapActivity"
            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>

</manifest>

 
main.xml代码如下:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >
  
    <LinearLayout
         android:layout_width="fill_parent"
         android:layout_height="wrap_content"
         android:orientation="horizontal"
         android:background="@drawable/searchbg"
         >
    
    <EditText
        android:id="@+id/input"
        android:layout_width="150dp"
        android:layout_height="wrap_content"
        android:hint="搜索"
        android:singleLine="true"
        android:layout_marginLeft="12dp"
        />
   
    <Button android:id="@+id/search"
  android:layout_marginLeft="15dp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:hint="确定"
        android:textSize="17sp"
        android:textColor="#000000"
        />
   
    <Button android:id="@+id/location"

  android:layout_marginLeft="15dp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:hint="我的位置"
        android:textSize="17sp"
        android:textColor="#000000"
        />
    </LinearLayout>

<RelativeLayout android:layout_width="fill_parent" android:layout_height="fill_parent"
            android:orientation="vertical"
        >
 <!--        <TableRow  android:layout_weight="1">   -->
        <com.google.android.maps.MapView
        android:id="@+id/map"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:apiKey="0hzHU_WQC9vnaOK_hH7WROjk-dZ8oaGtlurXb-Q"

        android:clickable="true" >
    </com.google.android.maps.MapView>
     <!--
        开发密钥  0hzHU_WQC9vk9I34QW3EAb_G978GschIsQy****
        发布密钥    0hzHU_WQC9vnaOK_hH7WROjk-dZ8oaGtlur****
     -->
           
   <!--     </TableRow> -->

    </RelativeLayout>
</LinearLayout>

很久之前做过的了,一直没总结,今天重新理了下。我也是第一次接触Android应用,无论架构,还是界面,纯属菜鸟,写出来给有需要的同学看下。
参考链接:
模拟器运行正常,真机缺少文件:
Android中文API(136) —— GeoCoder:
官方API:
 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要在 Android 应用程序中使用 Google 地图进行定位,可以使用 Google Play Services SDK 提供的 Location APIs。首先,确保你的应用程序已经在 AndroidManifest.xml 文件中声明了使用定位权限: ``` <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> ``` 然后,在你的代码中使用以下步骤: 1. 检查设备上是否安装了 Google Play Services,如果没有则提示用户安装。 2. 创建 GoogleApiClient 实例并连接到 Google Play Services。 3. 实现 LocationListener 接口并注册位置更新监听器。 4. 请求位置更新。 以下是示例代码: ```java public class MapsActivity extends AppCompatActivity implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, LocationListener { private GoogleMap mMap; private GoogleApiClient mGoogleApiClient; private LocationRequest mLocationRequest; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_maps); // 检查 Google Play Services 是否可用 int status = GooglePlayServicesUtil.isGooglePlayServicesAvailable(getApplicationContext()); if (status != ConnectionResult.SUCCESS) { Toast.makeText(getApplicationContext(), "Google Play Services Not Available", Toast.LENGTH_LONG).show(); finish(); } // 创建 GoogleApiClient 实例 mGoogleApiClient = new GoogleApiClient.Builder(this) .addConnectionCallbacks(this) .addOnConnectionFailedListener(this) .addApi(LocationServices.API) .build(); // 创建 LocationRequest 实例 mLocationRequest = new LocationRequest(); mLocationRequest.setInterval(10000); // 定位更新间隔 mLocationRequest.setFastestInterval(5000); mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY); } @Override protected void onStart() { super.onStart(); mGoogleApiClient.connect(); } @Override protected void onStop() { super.onStop(); if (mGoogleApiClient.isConnected()) { mGoogleApiClient.disconnect(); } } @Override public void onConnected(Bundle bundle) { // 连接到 Google Play Services 成功 LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this); } @Override public void onConnectionSuspended(int i) { // 连接中断 } @Override public void onConnectionFailed(ConnectionResult connectionResult) { // 连接失败 } @Override public void onLocationChanged(Location location) { // 收到位置更新 mMap.clear(); LatLng latLng = new LatLng(location.getLatitude(), location.getLongitude()); mMap.addMarker(new MarkerOptions().position(latLng).title("Current Location")); mMap.moveCamera(CameraUpdateFactory.newLatLng(latLng)); mMap.animateCamera(CameraUpdateFactory.zoomTo(15)); } } ``` 注意:在使用此代码之前,需要在项目中添加 Google Play Services SDK 和 Google Maps API

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值