Android运用,Google地图v2版,新版如何生产密钥

概述

创建一个新的使用了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的版本。

?
1
2
3
< 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,打开一个终端窗口并键入下列内容:

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

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
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. 你应当看到与下面内容类似的输出:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
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>之前插入它来实现:

?
1
2
3
< 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层,则可以忽略,

?
1
2
3
4
5
6
7
8
< 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>元素的一个子元素:

?
1
2
3
< 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。将那个文件中所有的内容替换为下面的代码:

?
1
2
3
4
5
6
<? 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中添加如下的代码:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
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抛出来:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
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:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
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:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
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抛出来:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
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.

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 在Android设备上,我们可以使用谷歌地图API来下载离线地图瓦片。离线地图瓦片是将地图切片保存为图像文件,以便在离线状态下进行访问。下面是一些步骤来实现离线地图瓦片的下载: 首先,我们需要获取一个谷歌地图API密钥。可以通过Google Cloud控制台创建一个新的项目,启用地图服务,并生成API密钥。将API密钥应用于Android项目中。 其次,我们需要使用谷歌地图的TileProvider类来获取地图瓦片的URL,并进行下载。TileProvider类提供了诸如MapTile,TileUrlGenerator等方法来获取地图瓦片的信息。 接下来,我们可以使用下载库(例如OkHttp或Volley)来下载地图瓦片。我们需要构建一个HTTP请求,并设置瓦片的URL作为请求的URL。然后,我们可以发送请求并将其保存为图像文件。 最后,我们可以使用下载的地图瓦片来显示地图。我们可以使用谷歌地图的Map类来加载瓦片,并在地图视图上显示它们。 需要注意的是,离线地图瓦片下载可能会占用较大的存储空间,并且需要进行合法的API使用。此外,由于谷歌地图的使用条款可能会有变化,建议在实施之前查阅最新的使用条款和API文档。 总之,通过使用谷歌地图API密钥和TileProvider类,结合下载库来下载和使用离线地图瓦片,我们可以在Android设备上实现离线地图的功能。 ### 回答2: 在Android上使用谷歌离线地图瓦片下载功能,可以让用户在没有网络连接的情况下使用地图。首先,确保你的手机上安装了Google Maps应用程序。 下载地图瓦片的第一步是找到你感兴趣的区域。在Google Maps应用程序中,你可以使用缩放和平移手势来选择你要下载的区域。 一旦你确定了下载区域,接下来点击屏幕下方的搜索栏,并输入“ok maps”。然后,点击搜索结果中的“离线地图”。 系统将弹出一个新的界面,显示你选择的下载区域的预览。如果你对区域满意,点击屏幕下方的“下载”按钮。 接下来,你可以选择下载的地图瓦片的存储位置。你可以选择将地图存储在手机的内部存储器或外部存储器中。 下载过程可能需要一些时间,具体取决于你选择的区域大小和你的网络速度。 一旦下载完成,你就可以在没有网络连接的情况下使用已下载的地图。打开Google Maps应用程序,并点击左上角的菜单图标。 然后,选择“离线地图”,你将看到一个列表,其中包含你已经下载的地图。选择你感兴趣的地图,系统将加载该地图并显示在屏幕上。 你现在就可以在没有网络连接的情况下使用这些地图了。你可以浏览地图,查找地点和导航,而不需要连接互联网。但需要注意的是,有些功能可能仍然需要网络连接,如实时交通信息和搜索功能。 总的来说,通过这种方式,在Android上下载和使用谷歌离线地图瓦片是非常简便和方便的。用户可以提前下载感兴趣的地图,以便在没有网络连接的情况下使用。 ### 回答3: Android谷歌地图应用可以通过离线下载地图瓦片来实现离线地图操作。以下是一种简单的方法: 首先,打开Android谷歌地图应用并进入所需下载地图区域。可以使用双指捏合手势来缩放地图以选择下载区域。 接下来,点击屏幕上的菜单按钮,然后选择"离线地图"选项。在这个页面上,可以查看已经下载的离线地图区域列表。 在离线地图页面中,点击添加(+)按钮,接着选择要下载的区域。可以使用手指通过拖拽来选择下载的地图区域的大小。 一旦选择完下载区域,点击"下载"按钮,并在弹出的对话框中确认下载操作。 下载完成后,可以在离线地图列表中找到刚刚下载的地图区域。可以在该地图上进行平移和放大控制以查看下载的地图瓦片。 值得注意的是,下载的离线地图瓦片只在谷歌地图应用中可用,并不能在其他应用中使用。此外,下载的地图区域会占据一定的存储空间,需根据实际需要进行合理管理和清除。 总之,通过Android谷歌地图应用的离线地图功能,我们可以方便地下载地图瓦片,实现离线地图浏览,并在没有互联网连接的情况下获得导航方向和位置信息。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值