Google Maps Android API V2使用及问题解决


  因为Google Maps的API版本更新,之前的一些教程都是关于旧版本V1的,虽然Google说继续提供服务,但是不再提供API Key的申请。

  而新的V2版本貌似改动还挺大。也没搜到国内有什么系统介绍的博客文章之类的(书肯定是来不及那么新了)。

  断断续续折腾了大概半个月,因为对Android也不是特别熟悉,所以碰到这样那样的问题。

  终于在昨天看见模拟器上跑的地图了。太感人了。

  下面就主要说说要成功做成这一件事的流程吧。

 

  一些相关的链接:

  Google Maps Android API V1的介绍:

  https://developers.google.com/maps/documentation/android/v1/mapkey?hl=zh-CN

 

  Google Maps Android API v2的初步介绍:

  https://developers.google.com/maps/documentation/android/

  Introduction

  https://developers.google.com/maps/documentation/android/intro

 

Getting Started

  (本部分参考https://developers.google.com/maps/documentation/android/start

1.首先安装Google Play services SDK

  Google Maps Android API是作为这个SDK的一部分发行的。

  这个安装是通过Android SDK Manager进行,配置好之后的Eclipse上面应该有Android SDK Manager的图标,一般的SDK版本安装和更新都在这里进行。

  安装和更新Extras下的Google Play services即可。

2.获取API key

  获取Maps API key需要两样东西:应用的signing certificate和它的package name

  获取这个key之后,把它加在应用程序的AndroidManifest.xml文件里即可。

  为应用获取一个key还是需要好几个步骤的,下面详细说明:

获取数字证书(digital certificate)信息

  数字证书有Debug和Release两种,下面主要说Debug的。

  要获取一个叫做SHA-1 fingerprint的东西,作为数字证书的一个简短代表。

  这个指纹(fingerprint)是通过一个哈希算法得到的字符串,为了得到你的证书的SHA-1 fingerprint,首先要找到你的debug keystore 文件,文件名叫debug.keystore

  默认情况下它和虚拟机AVD存放在一起,win7下的路径是:C:\Users\your_user_name\.android\,也可以通过Eclipse中的Windows > Prefs > Android > Build来查看这个路径。

  然后,在cmd命令行里运行下列命令:

  keytool -list -v -keystore "C:\Users\your_user_name\.android\debug.keystore" -alias androiddebugkey -storepass android -keypass android

  就显示一大堆东西,其中就有证书指纹:

  

 

  SHA1那一行就包含了证书的SHA-1 fingerprint,是二十段用冒号割开的数字段,每段是两个十六进制的数。

在Google APIs Console上创建API Project

  在Google APIs Console上创建项目,并且注册Maps API。

  首先,去这个网址:https://code.google.com/apis/console/

  用Gmail的账户登录,如果是第一次的话,需要创建项目,默认情况会创建一个叫做API Project的项目。

  点击左边的Services,会在中间看到很多的APIs和Services,找到Google Maps Android API v2,然后把它设置成on,需要接受一些服务条款。

获得API Key

  在左边的导航条中选择API Access。

  在出来的页面中选择Create New Android Key...就可以生成key了:

  

 

    

  然后在对话框中填入:SHA-1 指纹, 分号隔开,然后是应用的 package name.然后就会生成一个Key。

  比如:

  

 

    

3.把API Key加入应用程序

  首先,建立虚拟设备AVD和应用程序。

  关于AVD,官方文档并没详细介绍,我后面会有说明。

  建立好应用程序,注意包名应该和申请key时候的包名一致。

  之后修改AndroidManifest.xml文件:

3.1.在<application>元素中加入子标签

 

<meta-data

    android:name="com.google.android.maps.v2.API_KEY"

    android:value="your_api_key"/>

  其中your_api_key置换成自己申请的API Key

 
3.2.加入一些许可信息

 

  <permission
          android:name="com.example.mapdemo.permission.MAPS_RECEIVE"
          android:protectionLevel="signature"/>
        <uses-permission android:name="com.example.mapdemo.permission.MAPS_RECEIVE"/>

 

  其中com.example.mapdemo换成自己的包名

 

4. AndroidManifest.xml中的其他具体设置

许可设置

  <uses-permission> 作为<manifest> 的子元素,需要加入下列一些:

 

<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>

 

OpenGL ES V2特性支持

    同样也是作为<manifest> 的子元素。

 

<uses-feature 
  android:glEsVersion="0x00020000" 
  android:required="true"/>

 

5.加上地图

首先布局文件:
<?xml version="1.0" encoding="utf-8"?>
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
  android:id="@+id/map"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  class="com.google.android.gms.maps.MapFragment"/>

 

然后在MainActivity.java:
MainActivity.java
复制代码
package com.example.mapdemo; 
 
import android.app.Activity; 
import android.os.Bundle; 
 
public class MainActivity extends Activity { 
 
    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
        super.onCreate(savedInstanceState); 
        setContentView(R.layout.main); 
    } 
}
复制代码

 


遇到的问题和解决的方法

程序编译错误,显示找不到一些类

  如图:

解决这个问题,首先需要把Google Play services的类库加载进来:

  在Eclipse里面选择:File > Import > Android > Existing Android Code Into Workspace然后点击Next.

  之后Browse..., 找到路径下的<android-sdk-folder>/extras/google/google_play_services/libproject/google-play-services_lib, 然后选择Finish。

第二步是添加对这个库的引用:

  在自己的项目上右键,选Properties,左边选Android,然后在下面的Library里面Add刚才的google-play-services_lib。

  

  之后程序就应该能运行了。

  接着你可能会碰到下面的问题:

这里导入的 google-play-services_lib可能不成功

导入

    安装完以后你就能用的吗?不行。你必须导入“Google Play services”库到在你的工作文件夹。点击菜单“File -> import...”,在import对话框中选择“Existing Android Code Into Workspace”,在下一步指定已安装“Google Play services”库的路径(在Android SDK安装目录下\android-sdk\extras\google\google_play_services\libproject\google-play-services_lib)于是你就看到下面的界面状态。记得必须选中”Copy projects into workspace“,否则在以后的开发中会遇到问题。

     然后,你可以将“Google Play services”库加入你需要的工程中。打开工程的属性对话框

    

    在左侧选择“Android”属性,点击右下方“Add”按钮,可以选择添加在当前工作区目录中所有有效的库项目。完成上述步骤,你就可以选择添加“goole-play-services_lib”了。

    


可用性检查

    如同  Google Play 服务简介中说的,Google Play 通过Google Play 商店应用为Android2.2以上的用户提供服务更新。但更新可能无法立即满足所有用户,要列出所有Android设备厂商的名字会越来越难:-)。

重点: 由于难于预料每个设备的状况,在访问Google Play服务特性以前,你必须在应用中检测一个兼容的Google Play服务APK是否有效。对大部分应用,最好的时机是在主活动(MainActivity)的onResume() 函数。

    在用户设备上的Google Play服务APK一般有四种状况。

  1. Google Play Store 应用的当前版本已经安装, 最近的 Google Play 服务APK 也已经被下载。
  2. Google Play Store 应用的当前版本已经安装, 但最近的 Google Play 服务APK还没有被下载。
  3. 有一个旧的 Google Play Store应用, 它不会主动下载Google Play 服务更新。
  4. Google Play 服务APK无效或者处于关闭状态,一般这是由于用户过去卸载或关闭了它。.

     第一种情况是成功状态,一般都是这种情况。但另外三种情况仍然会出现在某些用户的设备上。Google Play 服务客户端库有工具函数来判断当前的 Google Play 服务 APK 是否足以支持你正使用的客户库版本。如果不支持,客户库将让用户去 Google Play Store 来下载Google Play 服务APK.的当前版本。

注意: 搜索Google Play Store是找不到Google Play 服务 APK的。客户库发现设备没有Google Play 服务 APK或其不兼容时,将提供一个Google Play Store的深度链接。

     它依赖于你在应用中选择的合适位置。例如,如果是你的应用需要 Google Play 服务,你可能需要在程序第一次启动时做这件事。另一方面,要是Google Play服务对你的应用知识一个可选部分,你可以在用户进入相关功能前进行检查。

  1. 用 isGooglePlayServicesAvailable() 函数可以查询设备上Google Play 服务APK的状态,它返回结果码。
  2. 如果结果码是SUCCESS, 那Google Play 服务APK是新的,你需要的功能可以正常进行。
  3. 如果结果码是SERVICE_MISSINGSERVICE_VERSION_UPDATE_REQUIREDSERVICE_DISABLED,那调用getErrorDialog() 以向用户显示错误消息,它将允许用户从Google Play Store下载APK或在系统设置界面打开相应功能。
    代码片段可能如下。

[java]  view plain copy
  1. int errorCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this.getActivity()); //  因为我的代码在Fragment里,所以用getActivity(),要是你的代码在 Activiy中,用this就好  
  2. if( ConnectionResult.SUCCESS != errorCode )  
  3. {  
  4.     GooglePlayServicesUtil.getErrorDialog(errorCode, this.getActivity(), 0).show();  
  5. }  

署名要求

    如果您使用谷歌地图的Android API,在应用程序中,你必须将谷歌Play服务署名文本作为你应用的“法律声明”内容的一部分。

谷歌服务署名文本可以通过调用  GooglePlayServicesUtil.getOpenSourceSoftwareLicenseInfo 获得。

例程代码

    例程代码和谷歌服务SDK捆绑在一起。首先你必须按前面步骤添加库项目google-play-services_lib。然后你通过类似过程将例程代码加入你的工作目录。

  1. 选择 File > Import > Android > Existing Android Code Into Workspace 并点击 Next
  2. 选择Browse...,输入 <android-sdk-folder>/extras/google/google_play_services/samples/maps, 点击Finish
  3. 选择Project > Properties,选择 Java Build Path, 找到 Libraries
  4. 选择Add External Jars包含以下 jar文件,点击OK
    • <android-sdk-folder>/extras/android/compatibility/v4/android-support-v4.jar
  5. 添加自己的 Google Maps Android API 密钥
  6. 选择 Run > Run 来测试例程。



程序运行成功,但是显示This app won't run unless you update Google Play services.

  如图:

  

  有传言说V2不能在AVD上运行,可能Google还会对此问题进行更新。

  经过搜索,这个问题已经在Stackoverflow上被讨论过了,链接:http://stackoverflow.com/questions/13691943/this-app-wont-run-unless-you-update-google-play-services-via-bazaar

  所以看来在AVD上运行的问题已经被解决了

  

  解决的方法就是在AVD上安装两个包(Google Play Store和Google Play services):vending.apk和gms.apk,(给一个网盘链接:http://pan.baidu.com/share/link?shareid=190602&uk=2701745266

  并且AVD就选择普通的API 16就行,不需要是Google APIs。我选的是Android4.1 API16.

  安装时把那两个包放在当前目录,用命令行安装:

  

  

  之后运行程序,就出地图了:

  

 

补充说明

  因为MapFragment只在API 12及之后的版本才有,所以对于之前的版本需要使用Support Library来进行辅助。

  如果minSdkVersion设置为12以前的,就需要使用Support Library

  需要更改的地方是:布局文件中,把MapFragment改为SupportMapFragment。

  MainActivity继承自FragmentActivity而不是Activity。(需要import android.support.v4.app.FragmentActivity;)

 

附上完整代码  

AndroidManifest.xml
复制代码
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.maptest"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="15" />
    
    <uses-feature
          android:glEsVersion="0x00020000"
          android:required="true"/>
    
    <permission
          android:name="com.example.maptest.permission.MAPS_RECEIVE"
          android:protectionLevel="signature"/>
     
    <uses-permission android:name="com.example.maptest.permission.MAPS_RECEIVE"/>
    
    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES"/>
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>

    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name=".MainActivity"
            android:label="@string/title_activity_main" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        
        <meta-data
            android:name="com.google.android.maps.v2.API_KEY"
            android:value="AIzaSyAJRV7Rd_dlxnr8FYhQN3pEBUYFkhZWWpI"/>
        
    </application>

</manifest>
复制代码
MainActivity.java
复制代码
package com.example.maptest;

import android.os.Bundle;
import android.support.v4.app.FragmentActivity;


public class MainActivity extends FragmentActivity 
{

    @Override
    public void onCreate(Bundle savedInstanceState) 
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

    
}
复制代码

布局文件:

activity_main.xml
复制代码
<?xml version="1.0" encoding="utf-8"?>

<fragment xmlns:android="http://schemas.android.com/apk/res/android"
  android:id="@+id/map"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  class="com.google.android.gms.maps.SupportMapFragment"/>
复制代码

  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值