创建一个新的使用了Google Maps Android API v2的Android应用需要许多个步骤。这一节中所概述的其中的许多步骤只是需要必须执行一次而已,但有些信息则是未来应用开发方便的参考。给一个Android应用程序添加一个地图的总体过程如下:
你也可能想要通过查看示例代码来开始,示例代码包含在Google Play services SDK中。
这是一个先决条件,你需要安装Android SDK。请参考获取Android 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文档。这里是你需要执行的步骤的一个总结:
编辑你的应用程序的AndroidManifest.xml文件,并在<application>元素内添加如下的声明。这会嵌入编译app所使用的Google Play services的版本。
<meta-data android:name="com.google.android.gms.version" android:value="@integer/google_play_services_version" />
注意: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需要几个步骤。这些步骤列出如下,并将在接下来的小节中详细描述。
注意: 商业Google Maps Mobile SDK的用户必须额外的为他们的API工程启用 SDK。
Maps API key是基于你的应用程序数字证书的一个short form的,被称为它的SHA-1指纹。这个指纹是由通用的SHA-1哈希算法产生的一个唯一的文本串。由于这个指纹本身是唯一的,所以Google Maps使用它来作为识别你的应用程序的一种方式。
为了给你的证书显示SHA-1指纹,首先要确保你正在使用正确的证书。你可能有两个证书:
你可以使用keytool程序加-v参数来显示一个证书的SHA-1指纹。更多关于Keytool的信息,请参考文档http://docs.oracle.com/javase/6/docs/technotes/tools/windows/keytool.html。
展开下面的小节,来了解关于如何显示你的debug或release证书的详细的指导。
定位你的debug keystore文件。文件名为debug.keystore,在你第一次编译你的工程时创建。默认地,它与你的Android Virtual Device (AVD)文件存储在相同的目录下:
如果你同时在使用ADT与Eclipse,并且你不确定你的debug keystone位置在哪儿,你可以选择Windows > Prefs > Android > Build来查看完整的路径,你可以把这个路径粘贴到一个文件浏览器来定位包含了keystore的目录。
列出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
你应当看到与下面类似的输出:
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证书keystore文件。对于release keystore则没有默认的位置或名字。如果你不在为你的应用程序编译release版时指定一个,则编译出来的.apk将是未签名的,并且你将不得不在你可以发布它之前签名。对于release证书,为keystore和证书,你也需要证书的别名和密码。你可以通过输入下面内容来列出keystore中所有的keys的别名:
keytool -list -keystoreyour_keystore_name
将your_keystore_name用完整的路径和keystore的名字来替换,包含.keystore扩展名。你将会看到keystore的密码的提示。你但你键入了它,keytool将显示出keystore中所有的别名。
在一个终端或命令提示符中键入下面内容:
keytool -list -v -keystoreyour_keystore_name-aliasyour_alias_name
将your_keystore_name 用完整的路径和keystore的名字来替换,包含.keystore扩展名。将your_alias_name用创建它时分配给证书的别名来替换。
注意:为了保护你的keystore和key,不要在命令行键入storepass或keypass参数,除非你对你的电脑的安全性非常自信。比如,在一台公共的电脑上,某些人可能会看到你的终端窗口的历史,或列出正在运行的进程,获取密码,然后具有对你的签名证书的写权限。这将允许那些人修改或用他们自己的应用来替换你的应用。
你应当看到与下面内容类似的输出:
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中为你的应用程序创建或修改一个工程,并为Maps API执行注册。
如果你的应用程序已经完成了对Google Maps Android API v2服务的注册,则你可以请求一个API key了。每个工程注册多于一个的key也是可能的。
在结果对话框中,键入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
Google APIs Console通过显示Key for Android apps (with certificates),并后跟一个四十字符的API key来作出反应,比如:
AIzaSyBdVl-cTICSwYKrZ95SuvNw7dbMuDt1KG0
遵循下面的步骤来在你的应用程序的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,然后重新编译你的应用程序
一个使用了Google Maps Android API的android应用程序应该在它的manifest文件中指定如下的设置,AndroidManifest.xml:
指定你的应用程序需要的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层,则可以忽略,
android.permission.ACCESS_FINE_LOCATION 允许API使用全球定位系统(GPS)来在一个非常小的区域内决定设备的位置。
<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"/>
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那一行。再次编译并执行。
哎,我们终于看到了期待已久的地图了。
Done.