Google Maps Android API v2入门

jopen 10年前

概述

创建一个新的使用了Google Maps Android API v2的Android应用需要许多个步骤。这一节中所概述的其中的许多步骤只是需要必须执行一次而已,但有些信息则是未来应用开发方便的参考。给一个Android应用程序添加一个地图的总体过程如下:

  1. 安装Android SDK.
  2. 下载并配置Google Play services SDK,其中包含了Google Maps Android API。如果你使用了商业Google Maps Mobile SDK,则你必须下载并配置商业Google Maps Mobile SDK静态库
  3. 获取一个API key。为了做到这一点,你需要在Google APIs Console注册一个工程,并为你的app获取一个签名证书。
  4. 在你的应用程序的manifest中添加所需要的设置。
  5. 给你的应用程序添加一个map。
  6. 发布你的应用程序。

你也可能想要通过查看示例代码来开始,示例代码包含在Google Play services SDK中。

安装Android SDK

这是一个先决条件,你需要安装Android SDK。请参考获取Android SDK

安装并配置Google Play services SDK

你将需要为你的app创建一个Android工程,来完成这个小节的那些步骤。如果你还没有创建一个Android应用,你可以按照指南来创建一个"hello world" app。请参考创建一个Android工程

Google Maps Android API v2是作为Google Play services SDK的一部分来分发的。你可以通过Android SDK Manager来下载 Google Play services SDK。

更详细的说明,请参考Google Play services文档。这里是你需要执行的步骤的一个总结:

  • 安装Google Play services SDK。
  • 添加Google Play services作为一个Android library project。
  • 在你app的project中引用Google Play services

添加Google Play services版本到你app的manifest

编辑你的应用程序的AndroidManifest.xml文件,并在<application>元素内添加如下的声明。这会嵌入编译app所使用Google Play services的版本。

<meta-data      android:name="com.google.android.gms.version"      android:value="@integer/google_play_services_version" />

获取一个Android认证证书及Google Maps API key

注意:Google Maps Android API v2使用了一个新的管理key的系统。来自于一个Google Maps Android v1应用程序的现存的key,通常被称为MapView,在使用v2 API时将是无效的。

为了通过Maps API访问Google Maps服务器,你不得不给你的应用程序添加一个Maps API key 。这个key是免费的,你可以在你任何调用了Maps API的应用程序中使用,而且它支持无限多的用户。你可以通过提供你的应用程序的签名证书及它的包名,从Google APIs Console,获取一个Maps API key。通过给你的应用程序的AndroidManifest.xml文件添加一个元素来为你的应用添加key。

理解注册你的应用程序及获取一个key的过程,还需要一些关于Android应用的发布过程和要求的知识。总结一下,所有的Andriod应用都必须通过一个数字证书来签名,而你持有着私有的key。由于数字证书是唯一的,它们提供了一种简单的方式来唯一的识别你的app。这对于在系统中追踪你的应用程序很有用,比如像Google Play Store,对于追踪你的应用程序使用的resource,比如Google Maps服务器,也很有用。

注意:参考Android指南认证你的应用程序来获取更多关于数字认证的信息。

Maps API keys是与特定的 证书/包 对关联的,而不是与用户或应用程序。每个证书你只需要一个key即可,而无论你的一个应用程序有多少用户。使用了相同的证书的应用程序可以使用相同API key。然而,建议的方式是为你的每一个应用程序通过一个不同的证书获取一个不同的key来认证。

为你的应用程序获取一个key需要几个步骤。这些步骤列出如下,并将在接下来的小节中详细描述。

  1. 提取关于你的应用程序的证书的信息。
  2. Google APIs Console中注册一个工程,并为该工程添加Maps API作为一个服务。
  3. 请求一个或多个keys。
  4. 为你的应用程序添加你的key并开始开发。

注意: 商业Google Maps Mobile SDK的用户必须额外的为他们的API工程启用 SDK

显示你的app的证书信息

Maps API key是基于你的应用程序数字证书的一个short form的,被称为它的SHA-1指纹这个指纹是由通用的SHA-1哈希算法产生的一个唯一的文本串。由于这个指纹本身是唯一的,所以Google Maps使用它来作为识别你的应用程序的一种方式。

为了给你的证书显示SHA-1指纹,首先要确保你正在使用正确的证书。你可能有两个证书:

  • Debug证书:当你从命令行执行一个"debug"编译时,或当你在Eclipse中编译并执行一个工程而没有将它导出为一个released应用时,Android SDK工具自动地产生这个证书。只有当你在测试时才让你的app使用这个证书;不要试图发布一个用debug认证签名的app。在Android Developer文档中的Signing in Debug Mode一节中有对于debug证书更详细的描述。
  • Release证书:当你通过ant程序或Eclipse执行一个“release”编译时,Android SDK工具会产生这种证书。你也可以使用keytool程序产生这种证书。当你已经为向全世界发布你的应用程序做好了准备时,使用这种证书。

你可以使用keytool程序加-v参数来显示一个证书的SHA-1指纹。更多关于Keytool的信息,请参考文档http://docs.oracle.com/javase/6/docs/technotes/tools/windows/keytool.html

展开下面的小节,来了解关于如何显示你的debug或release证书的详细的指导。

显示debug证书指纹

  1. 定位你的debug keystore文件。文件名为debug.keystore,在你第一次编译你的工程时创建。默认地,它与你的Android Virtual Device (AVD)文件存储在相同的目录下:

    • OS X and Linux: ~/.android/
    • Windows Vista and Windows 7: C:\Users\your_user_name\.android\

    如果你同时在使用ADT与Eclipse,并且你不确定你的debug keystone位置在哪儿,你可以选择Windows > Prefs > Android > Build来查看完整的路径,你可以把这个路径粘贴到一个文件浏览器来定位包含了keystore的目录。

  2. 列出SHA-1指纹。

    • 对于Linux或OS X,打开一个终端窗口并键入下列内容:

    keytool -list -v -keystore ~/.android/debug.keystore -alias androiddebugkey -storepass android -keypass android
    • 对于Windows Vista和Windows 7,执行:

    keytool -list -v -keystore "%USERPROFILE%\.android\debug.keystore" -alias androiddebugkey -storepass android -keypass android
  3. 你应当看到与下面类似的输出:

 Alias name: androiddebugkey   Creation date: Jan 01, 2013   Entry type: PrivateKeyEntry   Certificate chain length: 1   Certificate[1]:   Owner: CN=Android Debug, O=Android, C=US   Issuer: CN=Android Debug, O=Android, C=US   Serial number: 4aa9b300   Valid from: Mon Jan 01 08:04:04 UTC 2013 until: Mon Jan 01 18:04:04 PST 2033   Certificate fingerprints:        MD5:  AE:9F:95:D0:A6:86:89:BC:A8:70:BA:34:FF:6A:AC:F9        SHA1: BB:0D:AC:74:D3:21:E1:43:07:71:9B:62:90:AF:A1:66:6E:44:5D:75        Signature algorithm name: SHA1withRSA        Version: 3

SHA1开头的那一行包含了证书的SHA-1指纹。指纹是由冒号隔开的20对两位16进制数的序列。

显示release证书指纹

  1. 定位你的release证书keystore文件。对于release keystore则没有默认的位置或名字。如果你不在为你的应用程序编译release版时指定一个,则编译出来的.apk将是未签名的,并且你将不得不在你可以发布它之前签名。对于release证书,为keystore和证书,你也需要证书的别名和密码。你可以通过输入下面内容来列出keystore中所有的keys的别名:

    keytool -list -keystoreyour_keystore_name

    your_keystore_name用完整的路径和keystore的名字来替换,包含.keystore扩展名。你将会看到keystore的密码的提示。你但你键入了它,keytool将显示出keystore中所有的别名。

  2. 在一个终端或命令提示符中键入下面内容:

    keytool -list -v -keystoreyour_keystore_name-aliasyour_alias_name

    your_keystore_name 用完整的路径和keystore的名字来替换,包含.keystore扩展名。将your_alias_name用创建它时分配给证书的别名来替换。

    注意:为了保护你的keystore和key,不要在命令行键入storepass或keypass参数,除非你对你的电脑的安全性非常自信。比如,在一台公共的电脑上,某些人可能会看到你的终端窗口的历史,或列出正在运行的进程,获取密码,然后具有对你的签名证书的写权限。这将允许那些人修改或用他们自己的应用来替换你的应用。

  3. 你应当看到与下面内容类似的输出:

 Alias name: <alias_name>   Creation date: Feb 02, 2013   Entry type: PrivateKeyEntry   Certificate chain length: 1   Certificate[1]:   Owner: CN=Android Debug, O=Android, C=US   Issuer: CN=Android Debug, O=Android, C=US   Serial number: 4cc9b300   Valid from: Mon Feb 02 08:01:04 UTC 2013 until: Mon Feb 02 18:05:04 PST 2033   Certificate fingerprints:        MD5:  AE:9F:95:D0:A6:86:89:BC:A8:70:BA:34:FF:6B:AC:F9        SHA1: BB:0D:AC:74:D3:21:E1:43:67:71:9B:62:90:AF:A1:66:6E:44:5D:75        Signature algorithm name: SHA1withRSA        Version: 3
SHA1开头的那一行包含了证书的 SHA-1指纹。指纹 是由冒号隔开的20对两位16进制数的序列。

在Google APIs Console中创建一个API工程

遵循如下的步骤,在Google APIs Console中为你的应用程序创建或修改一个工程,并为Maps API执行注册。

  1. 在一个浏览器中,导航到Google APIs Console
    • 如果你之前没有使用过Google APIs Console,你会得到提示,来创建一个工程,用于追踪你对于Google Maps Android API的使用。点击Create Project;Console创建一个称为API Project的新工程。在下一页,这个名字显示在左上角。要重命名或管理该工程,则点击它的名字。
    • 如果你已经在使用Google APIs Console了,你将立即看到一个你的已有工程和可用服务的列表。为Google Maps Android API使用一个新的工程仍然是一个好主意,因而选择左上角的工程名并点击Create
  2. 你应该在主窗口看到一个APIs和服务的列表。如果没有,则在左边的导航栏选择Services
  3. 页面中间所显示的服务的列表中,向下滚动直到看见Google Maps Android API v2。这一项的右边点击开关指示符来使它为on
  4. 这显示了Google Maps Android API Terms of Service。如果你同意服务条款,则点击服务条款下方的checkbox,然后点击Accept。这将使你返回到APIs和服务的列表。

获取一个Google Maps API key

如果你的应用程序已经完成了对Google Maps Android API v2服务的注册,则你可以请求一个API key了。每个工程注册多于一个的key也是可能的。

  1. Google APIs Console中导航到你的工程。
  2. 在左边的导航条中,点击API Access
  3. 在结果页中,点击Create New Android Key...
  4. 在结果对话框中,键入SHA-1指纹,然后是一个分号,然后是你的应用程序的包名。比如:

    BB:0D:AC:74:D3:21:E1:43:67:71:9B:62:91:AF:A1:66:6E:44:5D:75;com.example.android.mapexample 
  5. Google APIs Console通过显示Key for Android apps (with certificates),并后跟一个四十字符的API key来作出反应,比如:

    AIzaSyBdVl-cTICSwYKrZ95SuvNw7dbMuDt1KG0 

给你的应用程序添加API key

遵循下面的步骤来在你的应用程序的manifest中包含API key,包含在AndroidManifest.xml文件中。Maps API从这儿读取key值并将它传给Google Maps服务器,以确认你具有对Google Maps数据的访问权限。

1. 在AndroidManifest.xml中,添加下面的元素作为<application>元素的一个子元素,通过在闭合标签</application>之前插入它来实现:

<meta-data      android:name="com.google.android.maps.v2.API_KEY"      android:value="API_KEY"/>

用你的API key来替换API_KEY。这个元素将键 com.google.android.maps.v2.API_KEY的值设为API_KEY并使得API key对于你的应用程序中的任何MapFragment都是可见的。

2. 保存AndroidManifest.xml,然后重新编译你的应用程序

在应用的manifest中指定app设置

一个使用了Google Maps Android API的android应用程序应该在它的manifest文件中指定如下的设置,AndroidManifest.xml:

  • 一个对Google Play服务版本的引用。如果你遵从了本页上面的步骤而到了这个位置,你已经向你的应用程序的manifest添加了所需要的声明。
  • 应用程序的Maps API key。这个key确认你已经通过Google APIs Console注册了Google Maps服务。如果你遵从了本页上面的步骤而到了这个位置,你已经向你的应用程序的manifest添加了API key。
  • 赋予应用程序对Android系统功能及对Google Maps服务器访问权限的Permissions。参考下面的指导来添加这些设置。
  • (建议)应用程序请求OpenGL ES版本2的通知。外部服务可以探测到这个通知,并据此行动。比如,Google Play Store将不会在那些没有OpenGL ES版本2的设备上显示你的应用程序。参考下面的指导来添加这项设置。

指定permissions

指定你的应用程序需要的permissions,通过添加<uses-permission>元素作为<manifest>元素的子元素来实现。语法为:

<uses-permission android:name="permission_name"/> 

比如,请求Internet permission,添加:

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

除了你的应用程序其他部分需要的权限,你必须添加如下的权限以使用Google Maps Android API:

下面的permissions是建议添加的,但如果你的应用程序不访问用户的当前位置,以编程的方式,或启用My Location层,则可以忽略,

<uses-permission android:name="android.permission.INTERNET"/>  <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>  <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>  <uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES"/>  <!-- The following two permissions are not required to use       Google Maps Android API v2, but are recommended. -->  <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>  <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>

指定对OpenGL ES版本2的请求

Google Maps Android API使用OpenGL ES版本2来渲染地图。如果没有安装OpenGL ES版本2,你的地图将不会出现。我们建议你在AndroidManifest.xml中添加如下的<uses-feature>元素,作为<manifest>元素的一个子元素:

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

这个元素通知需要的外部服务。特别地,它具有阻止Google Play Store将你的应用程序显示在不支持OpenGL ES版本2的设备上的效果。

添加一个地图

测试你的应用程序是否被正确配置的最简单的方式是添加一个简单的地图。你将不得不修改两个文件:定义了app的layout的XML文件,及main activity Java文件。

请注意下面的代码只在测试目标平台为Android API 12或更新的应用程序的设置时有用。这段代码不应该被用于一个产品应用程序中。如何添加更健壮的代码的例子将贯穿于这份指南,并出现在示例代码中。

1. 在app的layout XML文件中添加如下的fragment。如果你使用Eclipse中的Android Developer Tools (ADT)包创建了一个‘hello world’ app,则这个文件为res/layout/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"            android:name="com.google.android.gms.maps.MapFragment"/>
2. 在 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.activity_main);      }  }

3. 编译并运行你的应用程序。你应该能看到一个地图。如果你没有看到一个地图,请确认你已经完成了本页中所描述的所有的步骤。

实践

1. 首先,用eclipse,以默认的方式创建一个hello world app,并将它的main layout文件的内容替换为前述只有一个MapFragment的layout,然后便执行应用程序。不出所料,这个app是无法运行起来的,会有如下的一个exception抛出来:

11-30 16:31:59.341: D/dalvikvm(6202): Late-enabling CheckJNI  11-30 16:31:59.491: E/ActivityThread(6202): Failed to inflate  11-30 16:31:59.491: E/ActivityThread(6202): android.view.InflateException: Binary XML file line #2: Error inflating class fragment  11-30 16:31:59.491: E/ActivityThread(6202):  at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:713)  11-30 16:31:59.491: E/ActivityThread(6202):  at android.view.LayoutInflater.inflate(LayoutInflater.java:469)  11-30 16:31:59.491: E/ActivityThread(6202):  at android.view.LayoutInflater.inflate(LayoutInflater.java:397)  11-30 16:31:59.491: E/ActivityThread(6202):  at android.view.LayoutInflater.inflate(LayoutInflater.java:353)  11-30 16:31:59.491: E/ActivityThread(6202):  at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:320)  11-30 16:31:59.491: E/ActivityThread(6202):  at android.app.Activity.setContentView(Activity.java:1895)  11-30 16:31:59.491: E/ActivityThread(6202):  at com.hanpfei.mymapexample.MainActivity.onCreate(MainActivity.java:12)  11-30 16:31:59.491: E/ActivityThread(6202):  at android.app.Activity.performCreate(Activity.java:5133)  11-30 16:31:59.491: E/ActivityThread(6202):  at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)  11-30 16:31:59.491: E/ActivityThread(6202):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2293)  11-30 16:31:59.491: E/ActivityThread(6202):  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2389)  11-30 16:31:59.491: E/ActivityThread(6202):  at android.app.ActivityThread.access$600(ActivityThread.java:153)  11-30 16:31:59.491: E/ActivityThread(6202):  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1269)  11-30 16:31:59.491: E/ActivityThread(6202):  at android.os.Handler.dispatchMessage(Handler.java:99)  11-30 16:31:59.491: E/ActivityThread(6202):  at android.os.Looper.loop(Looper.java:137)  11-30 16:31:59.491: E/ActivityThread(6202):  at android.app.ActivityThread.main(ActivityThread.java:5289)  11-30 16:31:59.491: E/ActivityThread(6202):  at java.lang.reflect.Method.invokeNative(Native Method)  11-30 16:31:59.491: E/ActivityThread(6202):  at java.lang.reflect.Method.invoke(Method.java:525)  11-30 16:31:59.491: E/ActivityThread(6202):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:739)  11-30 16:31:59.491: E/ActivityThread(6202):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:555)  11-30 16:31:59.491: E/ActivityThread(6202):  at dalvik.system.NativeStart.main(Native Method)  11-30 16:31:59.491: E/ActivityThread(6202): Caused by: android.app.Fragment$InstantiationException: Unable to instantiate fragment com.google.android.gms.maps.MapFragment: make sure class name exists, is public, and has an empty constructor that is public  11-30 16:31:59.491: E/ActivityThread(6202):  at android.app.Fragment.instantiate(Fragment.java:592)  11-30 16:31:59.491: E/ActivityThread(6202):  at android.app.Fragment.instantiate(Fragment.java:560)  11-30 16:31:59.491: E/ActivityThread(6202):  at android.app.Activity.onCreateView(Activity.java:4738)  11-30 16:31:59.491: E/ActivityThread(6202):  at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:689)  11-30 16:31:59.491: E/ActivityThread(6202):  ... 20 more  11-30 16:31:59.491: E/ActivityThread(6202): Caused by: java.lang.ClassNotFoundException: Didn't find class "com.google.android.gms.maps.MapFragment" on path: DexPathList[[zip file "/data/app/com.hanpfei.mymapexample-1.apk"],nativeLibraryDirectories=[/data/app-lib/com.hanpfei.mymapexample-1, /vendor/lib, /system/lib]]  11-30 16:31:59.491: E/ActivityThread(6202):  at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:53)  11-30 16:31:59.491: E/ActivityThread(6202):  at java.lang.ClassLoader.loadClass(ClassLoader.java:501)  11-30 16:31:59.491: E/ActivityThread(6202):  at java.lang.ClassLoader.loadClass(ClassLoader.java:461)  11-30 16:31:59.491: E/ActivityThread(6202):  at android.app.Fragment.instantiate(Fragment.java:582)  11-30 16:31:59.491: E/ActivityThread(6202):  ... 23 more  11-30 16:31:59.491: D/AndroidRuntime(6202): Shutting down VM  11-30 16:31:59.491: W/dalvikvm(6202): threadid=1: thread exiting with uncaught exception (group=0x415367c0)  11-30 16:31:59.491: E/AndroidRuntime(6202): FATAL EXCEPTION: main  11-30 16:31:59.491: E/AndroidRuntime(6202): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.hanpfei.mymapexample/com.hanpfei.mymapexample.MainActivity}: android.view.InflateException: Binary XML file line #2: Error inflating class fragment  11-30 16:31:59.491: E/AndroidRuntime(6202):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2339)  11-30 16:31:59.491: E/AndroidRuntime(6202):  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2389)  11-30 16:31:59.491: E/AndroidRuntime(6202):  at android.app.ActivityThread.access$600(ActivityThread.java:153)  11-30 16:31:59.491: E/AndroidRuntime(6202):  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1269)  11-30 16:31:59.491: E/AndroidRuntime(6202):  at android.os.Handler.dispatchMessage(Handler.java:99)  11-30 16:31:59.491: E/AndroidRuntime(6202):  at android.os.Looper.loop(Looper.java:137)  11-30 16:31:59.491: E/AndroidRuntime(6202):  at android.app.ActivityThread.main(ActivityThread.java:5289)  11-30 16:31:59.491: E/AndroidRuntime(6202):  at java.lang.reflect.Method.invokeNative(Native Method)  11-30 16:31:59.491: E/AndroidRuntime(6202):  at java.lang.reflect.Method.invoke(Method.java:525)  11-30 16:31:59.491: E/AndroidRuntime(6202):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:739)  11-30 16:31:59.491: E/AndroidRuntime(6202):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:555)  11-30 16:31:59.491: E/AndroidRuntime(6202):  at dalvik.system.NativeStart.main(Native Method)  11-30 16:31:59.491: E/AndroidRuntime(6202): Caused by: android.view.InflateException: Binary XML file line #2: Error inflating class fragment  11-30 16:31:59.491: E/AndroidRuntime(6202):  at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:713)  11-30 16:31:59.491: E/AndroidRuntime(6202):  at android.view.LayoutInflater.inflate(LayoutInflater.java:469)  11-30 16:31:59.491: E/AndroidRuntime(6202):  at android.view.LayoutInflater.inflate(LayoutInflater.java:397)  11-30 16:31:59.491: E/AndroidRuntime(6202):  at android.view.LayoutInflater.inflate(LayoutInflater.java:353)  11-30 16:31:59.491: E/AndroidRuntime(6202):  at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:320)  11-30 16:31:59.491: E/AndroidRuntime(6202):  at android.app.Activity.setContentView(Activity.java:1895)  11-30 16:31:59.491: E/AndroidRuntime(6202):  at com.hanpfei.mymapexample.MainActivity.onCreate(MainActivity.java:12)  11-30 16:31:59.491: E/AndroidRuntime(6202):  at android.app.Activity.performCreate(Activity.java:5133)  11-30 16:31:59.491: E/AndroidRuntime(6202):  at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)  11-30 16:31:59.491: E/AndroidRuntime(6202):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2293)  11-30 16:31:59.491: E/AndroidRuntime(6202):  ... 11 more  11-30 16:31:59.491: E/AndroidRuntime(6202): Caused by: android.app.Fragment$InstantiationException: Unable to instantiate fragment com.google.android.gms.maps.MapFragment: make sure class name exists, is public, and has an empty constructor that is public  11-30 16:31:59.491: E/AndroidRuntime(6202):  at android.app.Fragment.instantiate(Fragment.java:592)  11-30 16:31:59.491: E/AndroidRuntime(6202):  at android.app.Fragment.instantiate(Fragment.java:560)  11-30 16:31:59.491: E/AndroidRuntime(6202):  at android.app.Activity.onCreateView(Activity.java:4738)  11-30 16:31:59.491: E/AndroidRuntime(6202):  at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:689)  11-30 16:31:59.491: E/AndroidRuntime(6202):  ... 20 more  11-30 16:31:59.491: E/AndroidRuntime(6202): Caused by: java.lang.ClassNotFoundException: Didn't find class "com.google.android.gms.maps.MapFragment" on path: DexPathList[[zip file "/data/app/com.hanpfei.mymapexample-1.apk"],nativeLibraryDirectories=[/data/app-lib/com.hanpfei.mymapexample-1, /vendor/lib, /system/lib]]  11-30 16:31:59.491: E/AndroidRuntime(6202):  at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:53)  11-30 16:31:59.491: E/AndroidRuntime(6202):  at java.lang.ClassLoader.loadClass(ClassLoader.java:501)  11-30 16:31:59.491: E/AndroidRuntime(6202):  at java.lang.ClassLoader.loadClass(ClassLoader.java:461)  11-30 16:31:59.491: E/AndroidRuntime(6202):  at android.app.Fragment.instantiate(Fragment.java:582)  11-30 16:31:59.491: E/AndroidRuntime(6202):  ... 23 more

2. 总之意思就是说,找不到com.google.android.gms.maps.MapFragment这个类。解决这个问题,需要把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。(如果没有这个库,请在Android SDK Manager更新,在底端的Extras里面更新Google Play services即可)。

然后是添加对这个库的引用:

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

3. 这个时候,应用程序是连编译都编译不过。解决方法就是要先把上一步创建出来的那个google-play-services_lib的project编译一下。OK,可以编译了,那就再一次编译执行。这次又遇到了另外的一个exception:

11-30 17:02:56.262: E/ActivityThread(9967): Failed to inflate  11-30 17:02:56.262: E/ActivityThread(9967): android.view.InflateException: Binary XML file line #2: Error inflating class fragment  11-30 17:02:56.262: E/ActivityThread(9967):  at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:713)  11-30 17:02:56.262: E/ActivityThread(9967):  at android.view.LayoutInflater.inflate(LayoutInflater.java:469)  11-30 17:02:56.262: E/ActivityThread(9967):  at android.view.LayoutInflater.inflate(LayoutInflater.java:397)  11-30 17:02:56.262: E/ActivityThread(9967):  at android.view.LayoutInflater.inflate(LayoutInflater.java:353)  11-30 17:02:56.262: E/ActivityThread(9967):  at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:320)  11-30 17:02:56.262: E/ActivityThread(9967):  at android.app.Activity.setContentView(Activity.java:1895)  11-30 17:02:56.262: E/ActivityThread(9967):  at com.hanpfei.mymapexample.MainActivity.onCreate(MainActivity.java:12)  11-30 17:02:56.262: E/ActivityThread(9967):  at android.app.Activity.performCreate(Activity.java:5133)  11-30 17:02:56.262: E/ActivityThread(9967):  at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)  11-30 17:02:56.262: E/ActivityThread(9967):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2293)  11-30 17:02:56.262: E/ActivityThread(9967):  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2389)  11-30 17:02:56.262: E/ActivityThread(9967):  at android.app.ActivityThread.access$600(ActivityThread.java:153)  11-30 17:02:56.262: E/ActivityThread(9967):  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1269)  11-30 17:02:56.262: E/ActivityThread(9967):  at android.os.Handler.dispatchMessage(Handler.java:99)  11-30 17:02:56.262: E/ActivityThread(9967):  at android.os.Looper.loop(Looper.java:137)  11-30 17:02:56.262: E/ActivityThread(9967):  at android.app.ActivityThread.main(ActivityThread.java:5289)  11-30 17:02:56.262: E/ActivityThread(9967):  at java.lang.reflect.Method.invokeNative(Native Method)  11-30 17:02:56.262: E/ActivityThread(9967):  at java.lang.reflect.Method.invoke(Method.java:525)  11-30 17:02:56.262: E/ActivityThread(9967):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:739)  11-30 17:02:56.262: E/ActivityThread(9967):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:555)  11-30 17:02:56.262: E/ActivityThread(9967):  at dalvik.system.NativeStart.main(Native Method)  11-30 17:02:56.262: E/ActivityThread(9967): Caused by: java.lang.IllegalStateException: A required meta-data tag in your app's AndroidManifest.xml does not exist.  You must have the following declaration within the <application> element:     <meta-data android:name="com.google.android.gms.version" android:value="@integer/google_play_services_version" />  11-30 17:02:56.262: E/ActivityThread(9967):  at com.google.android.gms.common.GooglePlayServicesUtil.n(Unknown Source)  11-30 17:02:56.262: E/ActivityThread(9967):  at com.google.android.gms.common.GooglePlayServicesUtil.isGooglePlayServicesAvailable(Unknown Source)  11-30 17:02:56.262: E/ActivityThread(9967):  at com.google.android.gms.maps.internal.q.v(Unknown Source)  11-30 17:02:56.262: E/ActivityThread(9967):  at com.google.android.gms.maps.internal.q.u(Unknown Source)  11-30 17:02:56.262: E/ActivityThread(9967):  at com.google.android.gms.maps.MapsInitializer.initialize(Unknown Source)  11-30 17:02:56.262: E/ActivityThread(9967):  at com.google.android.gms.maps.MapFragment$b.cE(Unknown Source)  11-30 17:02:56.262: E/ActivityThread(9967):  at com.google.android.gms.maps.MapFragment$b.a(Unknown Source)  11-30 17:02:56.262: E/ActivityThread(9967):  at com.google.android.gms.dynamic.a.a(Unknown Source)  11-30 17:02:56.262: E/ActivityThread(9967):  at com.google.android.gms.dynamic.a.onInflate(Unknown Source)  11-30 17:02:56.262: E/ActivityThread(9967):  at com.google.android.gms.maps.MapFragment.onInflate(Unknown Source)  11-30 17:02:56.262: E/ActivityThread(9967):  at android.app.Activity.onCreateView(Activity.java:4745)  11-30 17:02:56.262: E/ActivityThread(9967):  at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:689)  11-30 17:02:56.262: E/ActivityThread(9967):  ... 20 more  11-30 17:02:56.262: D/AndroidRuntime(9967): Shutting down VM  11-30 17:02:56.262: W/dalvikvm(9967): threadid=1: thread exiting with uncaught exception (group=0x415367c0)  11-30 17:02:56.262: E/AndroidRuntime(9967): FATAL EXCEPTION: main  11-30 17:02:56.262: E/AndroidRuntime(9967): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.hanpfei.mymapexample/com.hanpfei.mymapexample.MainActivity}: android.view.InflateException: Binary XML file line #2: Error inflating class fragment  11-30 17:02:56.262: E/AndroidRuntime(9967):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2339)  11-30 17:02:56.262: E/AndroidRuntime(9967):  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2389)  11-30 17:02:56.262: E/AndroidRuntime(9967):  at android.app.ActivityThread.access$600(ActivityThread.java:153)  11-30 17:02:56.262: E/AndroidRuntime(9967):  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1269)  11-30 17:02:56.262: E/AndroidRuntime(9967):  at android.os.Handler.dispatchMessage(Handler.java:99)  11-30 17:02:56.262: E/AndroidRuntime(9967):  at android.os.Looper.loop(Looper.java:137)  11-30 17:02:56.262: E/AndroidRuntime(9967):  at android.app.ActivityThread.main(ActivityThread.java:5289)  11-30 17:02:56.262: E/AndroidRuntime(9967):  at java.lang.reflect.Method.invokeNative(Native Method)  11-30 17:02:56.262: E/AndroidRuntime(9967):  at java.lang.reflect.Method.invoke(Method.java:525)  11-30 17:02:56.262: E/AndroidRuntime(9967):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:739)  11-30 17:02:56.262: E/AndroidRuntime(9967):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:555)  11-30 17:02:56.262: E/AndroidRuntime(9967):  at dalvik.system.NativeStart.main(Native Method)  11-30 17:02:56.262: E/AndroidRuntime(9967): Caused by: android.view.InflateException: Binary XML file line #2: Error inflating class fragment  11-30 17:02:56.262: E/AndroidRuntime(9967):  at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:713)  11-30 17:02:56.262: E/AndroidRuntime(9967):  at android.view.LayoutInflater.inflate(LayoutInflater.java:469)  11-30 17:02:56.262: E/AndroidRuntime(9967):  at android.view.LayoutInflater.inflate(LayoutInflater.java:397)  11-30 17:02:56.262: E/AndroidRuntime(9967):  at android.view.LayoutInflater.inflate(LayoutInflater.java:353)  11-30 17:02:56.262: E/AndroidRuntime(9967):  at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:320)  11-30 17:02:56.262: E/AndroidRuntime(9967):  at android.app.Activity.setContentView(Activity.java:1895)  11-30 17:02:56.262: E/AndroidRuntime(9967):  at com.hanpfei.mymapexample.MainActivity.onCreate(MainActivity.java:12)  11-30 17:02:56.262: E/AndroidRuntime(9967):  at android.app.Activity.performCreate(Activity.java:5133)  11-30 17:02:56.262: E/AndroidRuntime(9967):  at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)  11-30 17:02:56.262: E/AndroidRuntime(9967):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2293)  11-30 17:02:56.262: E/AndroidRuntime(9967):  ... 11 more  11-30 17:02:56.262: E/AndroidRuntime(9967): Caused by: java.lang.IllegalStateException: A required meta-data tag in your app's AndroidManifest.xml does not exist.  You must have the following declaration within the <application> element:     <meta-data android:name="com.google.android.gms.version" android:value="@integer/google_play_services_version" />  11-30 17:02:56.262: E/AndroidRuntime(9967):  at com.google.android.gms.common.GooglePlayServicesUtil.n(Unknown Source)  11-30 17:02:56.262: E/AndroidRuntime(9967):  at com.google.android.gms.common.GooglePlayServicesUtil.isGooglePlayServicesAvailable(Unknown Source)  11-30 17:02:56.262: E/AndroidRuntime(9967):  at com.google.android.gms.maps.internal.q.v(Unknown Source)  11-30 17:02:56.262: E/AndroidRuntime(9967):  at com.google.android.gms.maps.internal.q.u(Unknown Source)  11-30 17:02:56.262: E/AndroidRuntime(9967):  at com.google.android.gms.maps.MapsInitializer.initialize(Unknown Source)  11-30 17:02:56.262: E/AndroidRuntime(9967):  at com.google.android.gms.maps.MapFragment$b.cE(Unknown Source)  11-30 17:02:56.262: E/AndroidRuntime(9967):  at com.google.android.gms.maps.MapFragment$b.a(Unknown Source)  11-30 17:02:56.262: E/AndroidRuntime(9967):  at com.google.android.gms.dynamic.a.a(Unknown Source)  11-30 17:02:56.262: E/AndroidRuntime(9967):  at com.google.android.gms.dynamic.a.onInflate(Unknown Source)  11-30 17:02:56.262: E/AndroidRuntime(9967):  at com.google.android.gms.maps.MapFragment.onInflate(Unknown Source)  11-30 17:02:56.262: E/AndroidRuntime(9967):  at android.app.Activity.onCreateView(Activity.java:4745)  11-30 17:02:56.262: E/AndroidRuntime(9967):  at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:689)  11-30 17:02:56.262: E/AndroidRuntime(9967):  ... 20 more

4. 这个exception呢,大体意思就是说,在app的AndroidManifest.xml文件中少加入了一个<meta-data android:name="com.google.android.gms.version" android:value="@integer/google_play_services_version" />标签。OK,我们遵照前面文档的说明,把这个元素加入到AndroidManifest.xml文件就是了,可以参考文档前面的添加Google Play services版本到你app的manifest部分,把那两行code直接复制粘贴即可。不过我们却又遭遇了另一个exception:

11-30 17:09:34.261: E/ActivityThread(10763): Failed to inflate  11-30 17:09:34.261: E/ActivityThread(10763): android.view.InflateException: Binary XML file line #2: Error inflating class fragment  11-30 17:09:34.261: E/ActivityThread(10763):  at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:713)  11-30 17:09:34.261: E/ActivityThread(10763):  at android.view.LayoutInflater.inflate(LayoutInflater.java:469)  11-30 17:09:34.261: E/ActivityThread(10763):  at android.view.LayoutInflater.inflate(LayoutInflater.java:397)  11-30 17:09:34.261: E/ActivityThread(10763):  at android.view.LayoutInflater.inflate(LayoutInflater.java:353)  11-30 17:09:34.261: E/ActivityThread(10763):  at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:320)  11-30 17:09:34.261: E/ActivityThread(10763):  at android.app.Activity.setContentView(Activity.java:1895)  11-30 17:09:34.261: E/ActivityThread(10763):  at com.hanpfei.mymapexample.MainActivity.onCreate(MainActivity.java:12)  11-30 17:09:34.261: E/ActivityThread(10763):  at android.app.Activity.performCreate(Activity.java:5133)  11-30 17:09:34.261: E/ActivityThread(10763):  at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)  11-30 17:09:34.261: E/ActivityThread(10763):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2293)  11-30 17:09:34.261: E/ActivityThread(10763):  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2389)  11-30 17:09:34.261: E/ActivityThread(10763):  at android.app.ActivityThread.access$600(ActivityThread.java:153)  11-30 17:09:34.261: E/ActivityThread(10763):  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1269)  11-30 17:09:34.261: E/ActivityThread(10763):  at android.os.Handler.dispatchMessage(Handler.java:99)  11-30 17:09:34.261: E/ActivityThread(10763):  at android.os.Looper.loop(Looper.java:137)  11-30 17:09:34.261: E/ActivityThread(10763):  at android.app.ActivityThread.main(ActivityThread.java:5289)  11-30 17:09:34.261: E/ActivityThread(10763):  at java.lang.reflect.Method.invokeNative(Native Method)  11-30 17:09:34.261: E/ActivityThread(10763):  at java.lang.reflect.Method.invoke(Method.java:525)  11-30 17:09:34.261: E/ActivityThread(10763):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:739)  11-30 17:09:34.261: E/ActivityThread(10763):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:555)  11-30 17:09:34.261: E/ActivityThread(10763):  at dalvik.system.NativeStart.main(Native Method)  11-30 17:09:34.261: E/ActivityThread(10763): Caused by: java.lang.SecurityException: The Maps API requires the additional following permissions to be set in the AndroidManifest.xml to ensure a correct behavior:  11-30 17:09:34.261: E/ActivityThread(10763): <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>  11-30 17:09:34.261: E/ActivityThread(10763): <uses-permission android:name="android.permission.INTERNET"/>  11-30 17:09:34.261: E/ActivityThread(10763): <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>  11-30 17:09:34.261: E/ActivityThread(10763): <uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES"/>  11-30 17:09:34.261: E/ActivityThread(10763):  at maps.af.cf.a(Unknown Source)  11-30 17:09:34.261: E/ActivityThread(10763):  at maps.af.ay.a(Unknown Source)  11-30 17:09:34.261: E/ActivityThread(10763):  at maps.af.al.a(Unknown Source)  11-30 17:09:34.261: E/ActivityThread(10763):  at maps.af.be.a(Unknown Source)  11-30 17:09:34.261: E/ActivityThread(10763):  at maps.af.bd.a(Unknown Source)  11-30 17:09:34.261: E/ActivityThread(10763):  at cmj.onTransact(SourceFile:107)  11-30 17:09:34.261: E/ActivityThread(10763):  at android.os.Binder.transact(Binder.java:347)  11-30 17:09:34.261: E/ActivityThread(10763):  at com.google.android.gms.maps.internal.IMapFragmentDelegate$a$a.onCreateView(Unknown Source)  11-30 17:09:34.261: E/ActivityThread(10763):  at com.google.android.gms.maps.MapFragment$a.onCreateView(Unknown Source)  11-30 17:09:34.261: E/ActivityThread(10763):  at com.google.android.gms.dynamic.a$4.b(Unknown Source)  11-30 17:09:34.261: E/ActivityThread(10763):  at com.google.android.gms.dynamic.a.a(Unknown Source)  11-30 17:09:34.261: E/ActivityThread(10763):  at com.google.android.gms.dynamic.a.onCreateView(Unknown Source)  11-30 17:09:34.261: E/ActivityThread(10763):  at com.google.android.gms.maps.MapFragment.onCreateView(Unknown Source)  11-30 17:09:34.261: E/ActivityThread(10763):  at android.app.Fragment.performCreateView(Fragment.java:1695)  11-30 17:09:34.261: E/ActivityThread(10763):  at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:861)  11-30 17:09:34.261: E/ActivityThread(10763):  at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1035)  11-30 17:09:34.261: E/ActivityThread(10763):  at android.app.FragmentManagerImpl.addFragment(FragmentManager.java:1137)  11-30 17:09:34.261: E/ActivityThread(10763):  at android.app.Activity.onCreateView(Activity.java:4746)  11-30 17:09:34.261: E/ActivityThread(10763):  at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:689)  11-30 17:09:34.261: E/ActivityThread(10763):  ... 20 more  11-30 17:09:34.261: D/AndroidRuntime(10763): Shutting down VM  11-30 17:09:34.261: W/dalvikvm(10763): threadid=1: thread exiting with uncaught exception (group=0x415367c0)  11-30 17:09:34.261: E/AndroidRuntime(10763): FATAL EXCEPTION: main  11-30 17:09:34.261: E/AndroidRuntime(10763): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.hanpfei.mymapexample/com.hanpfei.mymapexample.MainActivity}: android.view.InflateException: Binary XML file line #2: Error inflating class fragment  11-30 17:09:34.261: E/AndroidRuntime(10763):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2339)  11-30 17:09:34.261: E/AndroidRuntime(10763):  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2389)  11-30 17:09:34.261: E/AndroidRuntime(10763):  at android.app.ActivityThread.access$600(ActivityThread.java:153)  11-30 17:09:34.261: E/AndroidRuntime(10763):  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1269)  11-30 17:09:34.261: E/AndroidRuntime(10763):  at android.os.Handler.dispatchMessage(Handler.java:99)  11-30 17:09:34.261: E/AndroidRuntime(10763):  at android.os.Looper.loop(Looper.java:137)  11-30 17:09:34.261: E/AndroidRuntime(10763):  at android.app.ActivityThread.main(ActivityThread.java:5289)  11-30 17:09:34.261: E/AndroidRuntime(10763):  at java.lang.reflect.Method.invokeNative(Native Method)  11-30 17:09:34.261: E/AndroidRuntime(10763):  at java.lang.reflect.Method.invoke(Method.java:525)  11-30 17:09:34.261: E/AndroidRuntime(10763):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:739)  11-30 17:09:34.261: E/AndroidRuntime(10763):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:555)  11-30 17:09:34.261: E/AndroidRuntime(10763):  at dalvik.system.NativeStart.main(Native Method)  11-30 17:09:34.261: E/AndroidRuntime(10763): Caused by: android.view.InflateException: Binary XML file line #2: Error inflating class fragment  11-30 17:09:34.261: E/AndroidRuntime(10763):  at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:713)  11-30 17:09:34.261: E/AndroidRuntime(10763):  at android.view.LayoutInflater.inflate(LayoutInflater.java:469)  11-30 17:09:34.261: E/AndroidRuntime(10763):  at android.view.LayoutInflater.inflate(LayoutInflater.java:397)  11-30 17:09:34.261: E/AndroidRuntime(10763):  at android.view.LayoutInflater.inflate(LayoutInflater.java:353)  11-30 17:09:34.261: E/AndroidRuntime(10763):  at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:320)  11-30 17:09:34.261: E/AndroidRuntime(10763):  at android.app.Activity.setContentView(Activity.java:1895)  11-30 17:09:34.261: E/AndroidRuntime(10763):  at com.hanpfei.mymapexample.MainActivity.onCreate(MainActivity.java:12)  11-30 17:09:34.261: E/AndroidRuntime(10763):  at android.app.Activity.performCreate(Activity.java:5133)  11-30 17:09:34.261: E/AndroidRuntime(10763):  at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)  11-30 17:09:34.261: E/AndroidRuntime(10763):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2293)  11-30 17:09:34.261: E/AndroidRuntime(10763):  ... 11 more  11-30 17:09:34.261: E/AndroidRuntime(10763): Caused by: java.lang.SecurityException: The Maps API requires the additional following permissions to be set in the AndroidManifest.xml to ensure a correct behavior:  11-30 17:09:34.261: E/AndroidRuntime(10763): <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>  11-30 17:09:34.261: E/AndroidRuntime(10763): <uses-permission android:name="android.permission.INTERNET"/>  11-30 17:09:34.261: E/AndroidRuntime(10763): <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>  11-30 17:09:34.261: E/AndroidRuntime(10763): <uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES"/>  11-30 17:09:34.261: E/AndroidRuntime(10763):  at maps.af.cf.a(Unknown Source)  11-30 17:09:34.261: E/AndroidRuntime(10763):  at maps.af.ay.a(Unknown Source)  11-30 17:09:34.261: E/AndroidRuntime(10763):  at maps.af.al.a(Unknown Source)  11-30 17:09:34.261: E/AndroidRuntime(10763):  at maps.af.be.a(Unknown Source)  11-30 17:09:34.261: E/AndroidRuntime(10763):  at maps.af.bd.a(Unknown Source)  11-30 17:09:34.261: E/AndroidRuntime(10763):  at cmj.onTransact(SourceFile:107)  11-30 17:09:34.261: E/AndroidRuntime(10763):  at android.os.Binder.transact(Binder.java:347)  11-30 17:09:34.261: E/AndroidRuntime(10763):  at com.google.android.gms.maps.internal.IMapFragmentDelegate$a$a.onCreateView(Unknown Source)  11-30 17:09:34.261: E/AndroidRuntime(10763):  at com.google.android.gms.maps.MapFragment$a.onCreateView(Unknown Source)  11-30 17:09:34.261: E/AndroidRuntime(10763):  at com.google.android.gms.dynamic.a$4.b(Unknown Source)  11-30 17:09:34.261: E/AndroidRuntime(10763):  at com.google.android.gms.dynamic.a.a(Unknown Source)  11-30 17:09:34.261: E/AndroidRuntime(10763):  at com.google.android.gms.dynamic.a.onCreateView(Unknown Source)  11-30 17:09:34.261: E/AndroidRuntime(10763):  at com.google.android.gms.maps.MapFragment.onCreateView(Unknown Source)  11-30 17:09:34.261: E/AndroidRuntime(10763):  at android.app.Fragment.performCreateView(Fragment.java:1695)  11-30 17:09:34.261: E/AndroidRuntime(10763):  at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:861)  11-30 17:09:34.261: E/AndroidRuntime(10763):  at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1035)  11-30 17:09:34.261: E/AndroidRuntime(10763):  at android.app.FragmentManagerImpl.addFragment(FragmentManager.java:1137)  11-30 17:09:34.261: E/AndroidRuntime(10763):  at android.app.Activity.onCreateView(Activity.java:4746)  11-30 17:09:34.261: E/AndroidRuntime(10763):  at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:689)  11-30 17:09:34.261: E/AndroidRuntime(10763):  ... 20 more

5. 这次是关于权限的。那我们就将前文中提到的要添加的那些权限都加进去。必须要的4种,可选的两种。真是让人无奈,编译执行之后,还是有exception抛出来:

11-30 17:14:36.155: I/Process(11373): Sending signal. PID: 11373 SIG: 9  11-30 17:14:41.851: E/ActivityThread(11619): Failed to inflate  11-30 17:14:41.851: E/ActivityThread(11619): android.view.InflateException: Binary XML file line #2: Error inflating class fragment  11-30 17:14:41.851: E/ActivityThread(11619):  at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:713)  11-30 17:14:41.851: E/ActivityThread(11619):  at android.view.LayoutInflater.inflate(LayoutInflater.java:469)  11-30 17:14:41.851: E/ActivityThread(11619):  at android.view.LayoutInflater.inflate(LayoutInflater.java:397)  11-30 17:14:41.851: E/ActivityThread(11619):  at android.view.LayoutInflater.inflate(LayoutInflater.java:353)  11-30 17:14:41.851: E/ActivityThread(11619):  at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:320)  11-30 17:14:41.851: E/ActivityThread(11619):  at android.app.Activity.setContentView(Activity.java:1895)  11-30 17:14:41.851: E/ActivityThread(11619):  at com.hanpfei.mymapexample.MainActivity.onCreate(MainActivity.java:12)  11-30 17:14:41.851: E/ActivityThread(11619):  at android.app.Activity.performCreate(Activity.java:5133)  11-30 17:14:41.851: E/ActivityThread(11619):  at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)  11-30 17:14:41.851: E/ActivityThread(11619):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2293)  11-30 17:14:41.851: E/ActivityThread(11619):  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2389)  11-30 17:14:41.851: E/ActivityThread(11619):  at android.app.ActivityThread.access$600(ActivityThread.java:153)  11-30 17:14:41.851: E/ActivityThread(11619):  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1269)  11-30 17:14:41.851: E/ActivityThread(11619):  at android.os.Handler.dispatchMessage(Handler.java:99)  11-30 17:14:41.851: E/ActivityThread(11619):  at android.os.Looper.loop(Looper.java:137)  11-30 17:14:41.851: E/ActivityThread(11619):  at android.app.ActivityThread.main(ActivityThread.java:5289)  11-30 17:14:41.851: E/ActivityThread(11619):  at java.lang.reflect.Method.invokeNative(Native Method)  11-30 17:14:41.851: E/ActivityThread(11619):  at java.lang.reflect.Method.invoke(Method.java:525)  11-30 17:14:41.851: E/ActivityThread(11619):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:739)  11-30 17:14:41.851: E/ActivityThread(11619):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:555)  11-30 17:14:41.851: E/ActivityThread(11619):  at dalvik.system.NativeStart.main(Native Method)  11-30 17:14:41.851: E/ActivityThread(11619): Caused by: java.lang.RuntimeException: API key not found.  Check that <meta-data android:name="com.google.android.maps.v2.API_KEY" android:value="your API key"/> is in the <application> element of AndroidManifest.xml  11-30 17:14:41.851: E/ActivityThread(11619):  at maps.af.ay.a(Unknown Source)  11-30 17:14:41.851: E/ActivityThread(11619):  at maps.af.ay.a(Unknown Source)  11-30 17:14:41.851: E/ActivityThread(11619):  at maps.af.al.a(Unknown Source)  11-30 17:14:41.851: E/ActivityThread(11619):  at maps.af.be.a(Unknown Source)  11-30 17:14:41.851: E/ActivityThread(11619):  at maps.af.bd.a(Unknown Source)  11-30 17:14:41.851: E/ActivityThread(11619):  at cmj.onTransact(SourceFile:107)  11-30 17:14:41.851: E/ActivityThread(11619):  at android.os.Binder.transact(Binder.java:347)  11-30 17:14:41.851: E/ActivityThread(11619):  at com.google.android.gms.maps.internal.IMapFragmentDelegate$a$a.onCreateView(Unknown Source)  11-30 17:14:41.851: E/ActivityThread(11619):  at com.google.android.gms.maps.MapFragment$a.onCreateView(Unknown Source)  11-30 17:14:41.851: E/ActivityThread(11619):  at com.google.android.gms.dynamic.a$4.b(Unknown Source)  11-30 17:14:41.851: E/ActivityThread(11619):  at com.google.android.gms.dynamic.a.a(Unknown Source)  11-30 17:14:41.851: E/ActivityThread(11619):  at com.google.android.gms.dynamic.a.onCreateView(Unknown Source)  11-30 17:14:41.851: E/ActivityThread(11619):  at com.google.android.gms.maps.MapFragment.onCreateView(Unknown Source)  11-30 17:14:41.851: E/ActivityThread(11619):  at android.app.Fragment.performCreateView(Fragment.java:1695)  11-30 17:14:41.851: E/ActivityThread(11619):  at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:861)  11-30 17:14:41.851: E/ActivityThread(11619):  at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1035)  11-30 17:14:41.851: E/ActivityThread(11619):  at android.app.FragmentManagerImpl.addFragment(FragmentManager.java:1137)  11-30 17:14:41.851: E/ActivityThread(11619):  at android.app.Activity.onCreateView(Activity.java:4746)  11-30 17:14:41.851: E/ActivityThread(11619):  at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:689)  11-30 17:14:41.851: E/ActivityThread(11619):  ... 20 more  11-30 17:14:41.861: D/AndroidRuntime(11619): Shutting down VM  11-30 17:14:41.861: W/dalvikvm(11619): threadid=1: thread exiting with uncaught exception (group=0x415367c0)  11-30 17:14:41.861: E/AndroidRuntime(11619): FATAL EXCEPTION: main  11-30 17:14:41.861: E/AndroidRuntime(11619): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.hanpfei.mymapexample/com.hanpfei.mymapexample.MainActivity}: android.view.InflateException: Binary XML file line #2: Error inflating class fragment  11-30 17:14:41.861: E/AndroidRuntime(11619):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2339)  11-30 17:14:41.861: E/AndroidRuntime(11619):  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2389)  11-30 17:14:41.861: E/AndroidRuntime(11619):  at android.app.ActivityThread.access$600(ActivityThread.java:153)  11-30 17:14:41.861: E/AndroidRuntime(11619):  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1269)  11-30 17:14:41.861: E/AndroidRuntime(11619):  at android.os.Handler.dispatchMessage(Handler.java:99)  11-30 17:14:41.861: E/AndroidRuntime(11619):  at android.os.Looper.loop(Looper.java:137)  11-30 17:14:41.861: E/AndroidRuntime(11619):  at android.app.ActivityThread.main(ActivityThread.java:5289)  11-30 17:14:41.861: E/AndroidRuntime(11619):  at java.lang.reflect.Method.invokeNative(Native Method)  11-30 17:14:41.861: E/AndroidRuntime(11619):  at java.lang.reflect.Method.invoke(Method.java:525)  11-30 17:14:41.861: E/AndroidRuntime(11619):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:739)  11-30 17:14:41.861: E/AndroidRuntime(11619):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:555)  11-30 17:14:41.861: E/AndroidRuntime(11619):  at dalvik.system.NativeStart.main(Native Method)  11-30 17:14:41.861: E/AndroidRuntime(11619): Caused by: android.view.InflateException: Binary XML file line #2: Error inflating class fragment  11-30 17:14:41.861: E/AndroidRuntime(11619):  at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:713)  11-30 17:14:41.861: E/AndroidRuntime(11619):  at android.view.LayoutInflater.inflate(LayoutInflater.java:469)  11-30 17:14:41.861: E/AndroidRuntime(11619):  at android.view.LayoutInflater.inflate(LayoutInflater.java:397)  11-30 17:14:41.861: E/AndroidRuntime(11619):  at android.view.LayoutInflater.inflate(LayoutInflater.java:353)  11-30 17:14:41.861: E/AndroidRuntime(11619):  at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:320)  11-30 17:14:41.861: E/AndroidRuntime(11619):  at android.app.Activity.setContentView(Activity.java:1895)  11-30 17:14:41.861: E/AndroidRuntime(11619):  at com.hanpfei.mymapexample.MainActivity.onCreate(MainActivity.java:12)  11-30 17:14:41.861: E/AndroidRuntime(11619):  at android.app.Activity.performCreate(Activity.java:5133)  11-30 17:14:41.861: E/AndroidRuntime(11619):  at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)  11-30 17:14:41.861: E/AndroidRuntime(11619):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2293)  11-30 17:14:41.861: E/AndroidRuntime(11619):  ... 11 more  11-30 17:14:41.861: E/AndroidRuntime(11619): Caused by: java.lang.RuntimeException: API key not found.  Check that <meta-data android:name="com.google.android.maps.v2.API_KEY" android:value="your API key"/> is in the <application> element of AndroidManifest.xml  11-30 17:14:41.861: E/AndroidRuntime(11619):  at maps.af.ay.a(Unknown Source)  11-30 17:14:41.861: E/AndroidRuntime(11619):  at maps.af.ay.a(Unknown Source)  11-30 17:14:41.861: E/AndroidRuntime(11619):  at maps.af.al.a(Unknown Source)  11-30 17:14:41.861: E/AndroidRuntime(11619):  at maps.af.be.a(Unknown Source)  11-30 17:14:41.861: E/AndroidRuntime(11619):  at maps.af.bd.a(Unknown Source)  11-30 17:14:41.861: E/AndroidRuntime(11619):  at cmj.onTransact(SourceFile:107)  11-30 17:14:41.861: E/AndroidRuntime(11619):  at android.os.Binder.transact(Binder.java:347)  11-30 17:14:41.861: E/AndroidRuntime(11619):  at com.google.android.gms.maps.internal.IMapFragmentDelegate$a$a.onCreateView(Unknown Source)  11-30 17:14:41.861: E/AndroidRuntime(11619):  at com.google.android.gms.maps.MapFragment$a.onCreateView(Unknown Source)  11-30 17:14:41.861: E/AndroidRuntime(11619):  at com.google.android.gms.dynamic.a$4.b(Unknown Source)  11-30 17:14:41.861: E/AndroidRuntime(11619):  at com.google.android.gms.dynamic.a.a(Unknown Source)  11-30 17:14:41.861: E/AndroidRuntime(11619):  at com.google.android.gms.dynamic.a.onCreateView(Unknown Source)  11-30 17:14:41.861: E/AndroidRuntime(11619):  at com.google.android.gms.maps.MapFragment.onCreateView(Unknown Source)  11-30 17:14:41.861: E/AndroidRuntime(11619):  at android.app.Fragment.performCreateView(Fragment.java:1695)  11-30 17:14:41.861: E/AndroidRuntime(11619):  at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:861)  11-30 17:14:41.861: E/AndroidRuntime(11619):  at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1035)  11-30 17:14:41.861: E/AndroidRuntime(11619):  at android.app.FragmentManagerImpl.addFragment(FragmentManager.java:1137)  11-30 17:14:41.861: E/AndroidRuntime(11619):  at android.app.Activity.onCreateView(Activity.java:4746)  11-30 17:14:41.861: E/AndroidRuntime(11619):  at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:689)  11-30 17:14:41.861: E/AndroidRuntime(11619):  ... 20 more

6. 这次是关于API key的。OK,那我们就再遵照前文的说明,在Google APIs Console中产生一个API key加进来。这个地方多说一点,其实我们通过eclipse已经是可以看到debug证书的SHA-1指纹了,而不需要再去执行什么keytool。方法为,选择Window->Preferences->Android->Build,在SHA-1 fingerprint那一行。再次编译并执行。

哎,我们终于看到了期待已久的地图了。

Google Maps Android API v2入门

Done.

来自:http://my.oschina.net/wolfcs/blog/180390