无法实例化android.gms.maps.MapFragment

83

我尝试使用谷歌地图Android V2制作一个非常简单的演示活动,只需从Google页面复制代码:

https://developers.google.com/maps/documentation/android/start#adding_the_api_key_to_your_application

活动如下:

package com.example.mapdemo;

import android.app.Activity;
import android.os.Bundle;

public class MainActivity extends Activity {

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

用于布局:

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

我已根据页面申请了 API 密钥,并修改了我的 androidmanifest.xml 文件,就像这样:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.wenhai.driverschool"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="15" />

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

    <!-- add for map2 -->
    <permission
        android:name="com.example.mapdemo.permission.MAPS_RECEIVE"
        android:protectionLevel="signature" />

    <uses-permission android:name="com.example.mapdemo.permission.MAPS_RECEIVE" />
    <uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES" />
    <!-- External storage for caching. -->
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

    <!-- Maps API needs OpenGL ES 2.0. -->
    <uses-feature
        android:glEsVersion="0x00020000"
        android:required="true" />

    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <meta-data
            android:name="com.google.android.maps.v2.API_KEY"
            android:value="AIzaSyDVAF4WaVSVRDKJx87It8OSFP5txQcPabc" />

        <activity
            android:name=".MainActivity"
            android:label="@string/title_activity_main" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>
我还将我的应用程序引用到了eclipse中的Google Play服务库。但是每次都会在logcat中报告以下错误:
2-05 16:22:53.609: E/AndroidRuntime(21623): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.wenhai.driverschool/com.wenhai.driverschool.MainActivity}: android.view.InflateException: Binary XML file line #2: Error inflating class fragment
12-05 16:22:53.609: E/AndroidRuntime(21623):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1967)
12-05 16:22:53.609: E/AndroidRuntime(21623):    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1992)
12-05 16:22:53.609: E/AndroidRuntime(21623):    at android.app.ActivityThread.access$600(ActivityThread.java:127)
12-05 16:22:53.609: E/AndroidRuntime(21623):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1158)
12-05 16:22:53.609: E/AndroidRuntime(21623):    at android.os.Handler.dispatchMessage(Handler.java:99)
12-05 16:22:53.609: E/AndroidRuntime(21623):    at android.os.Looper.loop(Looper.java:137)
12-05 16:22:53.609: E/AndroidRuntime(21623):    at android.app.ActivityThread.main(ActivityThread.java:4441)
12-05 16:22:53.609: E/AndroidRuntime(21623):    at java.lang.reflect.Method.invokeNative(Native Method)
12-05 16:22:53.609: E/AndroidRuntime(21623):    at java.lang.reflect.Method.invoke(Method.java:511)
12-05 16:22:53.609: E/AndroidRuntime(21623):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:823)
12-05 16:22:53.609: E/AndroidRuntime(21623):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:590)
12-05 16:22:53.609: E/AndroidRuntime(21623):    at dalvik.system.NativeStart.main(Native Method)
12-05 16:22:53.609: E/AndroidRuntime(21623): Caused by: android.view.InflateException: Binary XML file line #2: Error inflating class fragment
12-05 16:22:53.609: E/AndroidRuntime(21623):    at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:697)
12-05 16:22:53.609: E/AndroidRuntime(21623):    at android.view.LayoutInflater.inflate(LayoutInflater.java:466)
12-05 16:22:53.609: E/AndroidRuntime(21623):    at android.view.LayoutInflater.inflate(LayoutInflater.java:396)
12-05 16:22:53.609: E/AndroidRuntime(21623):    at android.view.LayoutInflater.inflate(LayoutInflater.java:352)
12-05 16:22:53.609: E/AndroidRuntime(21623):    at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:255)
12-05 16:22:53.609: E/AndroidRuntime(21623):    at android.app.Activity.setContentView(Activity.java:1835)
12-05 16:22:53.609: E/AndroidRuntime(21623):    at com.wenhai.driverschool.MainActivity.onCreate(MainActivity.java:11)
12-05 16:22:53.609: E/AndroidRuntime(21623):    at android.app.Activity.performCreate(Activity.java:4465)
12-05 16:22:53.609: E/AndroidRuntime(21623):    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1049)
12-05 16:22:53.609: E/AndroidRuntime(21623):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1931)
12-05 16:22:53.609: E/AndroidRuntime(21623):    ... 11 more
12-05 16:22:53.609: E/AndroidRuntime(21623): 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
12-05 16:22:53.609: E/AndroidRuntime(21623):    at android.app.Fragment.instantiate(Fragment.java:581)
12-05 16:22:53.609: E/AndroidRuntime(21623):    at android.app.Fragment.instantiate(Fragment.java:549)
12-05 16:22:53.609: E/AndroidRuntime(21623):    at android.app.Activity.onCreateView(Activity.java:4235)
12-05 16:22:53.609: E/AndroidRuntime(21623):    at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:673)
12-05 16:22:53.609: E/AndroidRuntime(21623):    ... 20 more
12-05 16:22:53.609: E/AndroidRuntime(21623): Caused by: java.lang.ClassNotFoundException: com.google.android.gms.maps.MapFragment
12-05 16:22:53.609: E/AndroidRuntime(21623):    at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:61)
12-05 16:22:53.609: E/AndroidRuntime(21623):    at java.lang.ClassLoader.loadClass(ClassLoader.java:501)
12-05 16:22:53.609: E/AndroidRuntime(21623):    at java.lang.ClassLoader.loadClass(ClassLoader.java:461)
12-05 16:22:53.609: E/AndroidRuntime(21623):    at android.app.Fragment.instantiate(Fragment.java:571)
12-05 16:22:53.609: E/AndroidRuntime(21623):    ... 23 more

我不知道原因。

如果将google-play-services.jar添加到我的项目中,它会报告另一个错误:

12-05 16:34:23.269: E/AndroidRuntime(22638): FATAL EXCEPTION: main
12-05 16:34:23.269: E/AndroidRuntime(22638): java.lang.NoClassDefFoundError: com.google.android.gms.R$styleable
12-05 16:34:23.269: E/AndroidRuntime(22638):    at com.google.android.gms.maps.GoogleMapOptions.createFromAttributes(Unknown Source)
12-05 16:34:23.269: E/AndroidRuntime(22638):    at com.google.android.gms.maps.MapFragment.onInflate(Unknown Source)
12-05 16:34:23.269: E/AndroidRuntime(22638):    at android.app.Activity.onCreateView(Activity.java:4242)
12-05 16:34:23.269: E/AndroidRuntime(22638):    at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:673)
12-05 16:34:23.269: E/AndroidRuntime(22638):    at android.view.LayoutInflater.inflate(LayoutInflater.java:466)
12-05 16:34:23.269: E/AndroidRuntime(22638):    at android.view.LayoutInflater.inflate(LayoutInflater.java:396)
12-05 16:34:23.269: E/AndroidRuntime(22638):    at android.view.LayoutInflater.inflate(LayoutInflater.java:352)
12-05 16:34:23.269: E/AndroidRuntime(22638):    at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:255)
12-05 16:34:23.269: E/AndroidRuntime(22638):    at android.app.Activity.setContentView(Activity.java:1835)
12-05 16:34:23.269: E/AndroidRuntime(22638):    at com.wenhai.driverschool.MainActivity.onCreate(MainActivity.java:11)
12-05 16:34:23.269: E/AndroidRuntime(22638):    at android.app.Activity.performCreate(Activity.java:4465)
12-05 16:34:23.269: E/AndroidRuntime(22638):    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1049)
12-05 16:34:23.269: E/AndroidRuntime(22638):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1931)
12-05 16:34:23.269: E/AndroidRuntime(22638):    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1992)
12-05 16:34:23.269: E/AndroidRuntime(22638):    at android.app.ActivityThread.access$600(ActivityThread.java:127)
12-05 16:34:23.269: E/AndroidRuntime(22638):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1158)
12-05 16:34:23.269: E/AndroidRuntime(22638):    at android.os.Handler.dispatchMessage(Handler.java:99)
12-05 16:34:23.269: E/AndroidRuntime(22638):    at android.os.Looper.loop(Looper.java:137)
12-05 16:34:23.269: E/AndroidRuntime(22638):    at android.app.ActivityThread.main(ActivityThread.java:4441)
12-05 16:34:23.269: E/AndroidRuntime(22638):    at java.lang.reflect.Method.invokeNative(Native Method)
12-05 16:34:23.269: E/AndroidRuntime(22638):    at java.lang.reflect.Method.invoke(Method.java:511)
12-05 16:34:23.269: E/AndroidRuntime(22638):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:823)
12-05 16:34:23.269: E/AndroidRuntime(22638):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:590)
12-05 16:34:23.269: E/AndroidRuntime(22638):    at dalvik.system.NativeStart.main(Native Method)

有人能帮我解决这个问题吗?


2
我在使用MapView时遇到了相同的错误。我按照此页面https://developers.google.com/maps/documentation/android/start上描述的步骤添加了库,但所有这些对我来说都是无用的。 - jumper0k
1
相同的错误.. 有任何解决方法吗... - nilkash
1
我遇到了相同的错误,但是还没有找到好的解决方案 :( - rikas
由于我猜这个问题还没有解决,因此请查看以下步骤:http://techhomeblog.wordpress.com/2013/02/23/mapfragmentmapsupportfragment/ - Tofeeq Ahmad
尝试在Eclipse中右键单击您的项目,选择Android工具>添加支持库。在我的情况下,它是从ActionBarSherlock获取的旧版本。 - IgorGanapolsky
Ramz的答案说得很全面。这对我解决了问题! - user821863
30个回答

86
在 IntelliJ IDEA (更新至 IntelliJ 12)中:
  1. 创建一个文件 ~/android-sdk/extras/google/google_play_services/libproject/google-play-services_lib/src/dummy.java,其中包含 class dummy {}
  2. 文件->导入模块-> ~/android-sdk/extras/google/google_play_services/libproject/google-play-services_lib
  3. 从现有源创建模块
  4. 下一步->下一步->下一步->完成
  5. 文件->项目结构->模块->YourApp
  6. +->模块依赖项->Google-play-services_lib(+按钮位于对话框的右上角。)
  7. +->Jars 或目录->~/android-sdk/extras/google/google_play_services/libproject/google-play-services_lib/libs/google-play-services.jar
  8. 使用 向上/向下 箭头将 <Module source> 移动到列表底部。

如果需要,您可以删除 dummy.java

编辑:使用一段时间后,我发现这里有一个小缺陷/bug。IDEA有时会抱怨无法在 google-play-services_lib 目录中打开 .iml 项目文件,尽管您从未告诉它那里有个项目。如果发生这种情况,重建项目可以解决问题,至少在它再次出现之前是这样。


3
你好,我在我的Eclipse IDE中找不到“文件>导入模块”选项。请帮助我... - Rahmathullah M
这是针对卓越的IDE“IntelliJ IDEA”的。 - Timmmm
2
谢谢你的回答!但是我只需要在项目中添加模块和jar依赖,一切都正常工作了! - lomza
3
由于Google Play服务库已经更新,增加虚拟文件(Dummy file)的步骤不再必要。他们新增了一个“官方虚拟文件”以支持“一些IDE”(即他们修复了IntelliJ和Android Studio的问题)。请注意,此翻译仅供参考,不得用于任何正式场合。 - AfroRick
这解决了我的问题。将google-play-services_lib文件夹复制到我的项目父文件夹中,然后按照指示设置模块依赖关系。谢谢。这个过程真的非常不直观。在使用Eclipse之前,我差不多已经掌握了它。 - speedynomads
显示剩余4条评论

33

更新

请按照Commonsware MapV2代码片段进行操作,以获得更好的理解。

(它在Omnibus版本中存在)

https://github.com/commonsguy/cw-omnibus/tree/master/MapsV2

以下代码片段在我的机器上运行良好。我选择使用SupportMapFragment

不要忘记将 google-play-services.jar 添加到您的项目中。

MainActivity.java

package com.example.newmapview;

import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import com.google.android.gms.maps.SupportMapFragment;

public class MainActivity extends FragmentActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        SupportMapFragment fragment = new SupportMapFragment();
        getSupportFragmentManager().beginTransaction()
                .add(android.R.id.content, fragment).commit();
    }
}

manifest.xml

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

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="16" />

    <permission
        android:name="com.example.newmapview.permission.MAPS_RECEIVE"
        android:protectionLevel="signature" />

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

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

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

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

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

</manifest>

以下是结果

enter image description here 希望这能有所帮助。


嗨,Vipul Shah,谢谢。我在控制台上发现了以下消息:[2012-12-06 10:20:26 - google-play-services_lib] Could not find google-play-services_lib.apk! 我不知道这个apk是否缺失导致了我的错误。你能告诉我如何引用google-play-services.jar吗?是像下面的链接一样添加它:http://developer.android.com/intl/zh-CN/tools/projects/projects-eclipse.html#ReferencingLibraryProject,还是在eclipse中添加它,像下面这样:Propertyes->java Build Path->Projects,添加google-play-services_lib项目。你们那边是哪一个呢?谢谢。 - mmm2006
@mmm2006 我担心你可能在 Android 模拟器上运行此应用程序。我不确定,但你可能会遇到这个错误,因为模拟器上没有 Play Store 应用程序。请在实际设备上尝试。 - Vipul
事实上,我在我的手机上运行它。一部索尼手机。 - mmm2006
嗨Vipul,你能告诉我如何使用MapFragment在地图上显示我的标记吗?我有一组纬度和经度列表,我想在地图上显示它们,我尝试了MapView但对我没有用,所以我不能使用ItemizedOverlay,MapFragment可以工作,那么如何在MapFragment上显示多个标记。如果可能的话,请提供一个具有可行代码的链接。 - Shrikant Ballal
@VipulShah:你太棒了。能告诉我为什么会出现这个错误吗?因为之前有一段时间它是可以工作的,我开发了一些教程--->http://dj-android.blogspot.in/2013/02/android-google-map-v2-part-1.html 现在同样的代码却不能工作了。 - Dhaval Parmar
@Vipul Shah:"别忘了将google-play-services.jar添加到你的项目中。" <--- 这救了我,晚上11:58,我差点把这个问题带到第二天,谢谢! - user3560827

24

只需尝试将您的布局替换为:

<?xml version="1.0" encoding="utf-8"?>
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
      android:id="@+id/map"
       android:name="com.google.android.gms.maps.SupportMapFragment"
       android:layout_width="wrap_content"
       android:layout_height="match_parent" />

对于 API 版本低于 11,您需要使用 SupportMapFragment!

Aurel


3
很抱歉,但这在我的地方也无法工作。这次出错的报告是:由于android.app.Fragment$InstantiationException造成:无法实例化com.google.android.gms.maps.SupportMapFragment片段:请确保类名存在,是公共的,并具有一个公共的空构造函数。我可以在jar文件中找到SupportMapFragment,但它不能正常工作。 我不知道原因。 - mmm2006
嗯,看起来你需要做以下事情:1. 在Android SDK Manager上下载Google Play Services SDK。2. 在Eclipse中导入项目库。3. 将库添加到你的项目中。4. 确保在你的项目中有android-support-v4.jar(也可在Android SDK Manager中获取)。5. 创建一个片段并添加名称(对于SDK >= 11,使用'class="com.google.android.gms.maps.MapFragment"/>',对于SDK < 11,使用'class="com.google.android.gms.maps.MapFragment"/>)。6. 别忘了在设备上尝试示例代码(你的应用需要Google Play!) - Aurel
好的。我发现我必须遵循这个指南来引用Google Play服务。http://developer.android.com/intl/zh-CN/tools/projects/projects-eclipse.html#ReferencingLibraryProject。但是,谷歌提供的示例到目前为止还不能工作。:( - mmm2006
你有没有任何想法,View的等价物是什么?可以将它放在片段的XML文件中吗? - Harsha M V
1
@mmm2006:你需要扩展“FragmentActivity”,而不是“Activity”,然后它应该可以工作,也不会抛出异常。 - Veer
@Aurel,我有没有办法给你的答案点赞?这正是我在寻找的! - Paschalis

17
我也遇到了同样的问题,花了两天时间才找到了适合我的解决方案:
  1. 删除项目 google-play-services_lib(右键单击该项目并删除)
  2. 如果有包含Google地图演示的项目(在我的情况下是MainActivity),请将其删除
  3. 将项目google-play-services_lib (extras\google\google_play_services\libproject\google-play-services_lib)复制到您的工作区,然后将其导入为通用项目(文件->导入->现有项目到工作区)
  4. 右键单击要加载地图的项目(即您的项目)-> Android -> 添加(在库下)google-play-services_lib
您应该会看到类似于这样的东西:

notice the

注意:您不应该有类似这样的情况(项目应该从您的工作区引用):

enter image description here

我认为问题在于两个项目引用了同一个库。

我正在将Google Play服务添加为Java构建路径库,但需要将其添加到Android / Library下。 - marimaf

10

2
这对我来说是至关重要的修复,上面的其他答案都没有帮助。这里的区别实际上相当微妙 - 我是通过“Java Build Path”将其添加为依赖项目,而实际上我应该通过“Android”菜单来完成。我已经将该信息添加到我的另一个答案中:https://dev59.com/bWYr5IYBdhLWcg3wXJEK#13734564 - Dan J

8
  1. 目前,演示可以按照此链接工作:
  2. 例如演示,它也可以工作:

在您的项目中的libs目录中添加两个jar。请按照以下信息操作。特别是,我认为您需要:

  • 导入“google-play-services_lib”项目的实际源代码,并将其链接为Android库。
    • 通过Project -> Properties -> Android -> Library,Add -> google-play-services_lib进行操作(您可以右键单击您的项目,然后选择Properties,然后选择Android)。
    • 不要通过项目的“Java Build Path”将其添加为依赖项目,因为这对我没有起作用。
  • 将google-play-services.jar和android-support-v4.jar添加到示例项目的“libs”文件夹中,并将它们作为“Build Path -> Configure Build Path -> Libraries”中的“External External JARs”添加。

我发现当我尝试使用示例代码时,第二步是必要的,因为我遇到了与您完全相同的com.google.android.gms.R$styleable中的NoClassDefFoundError错误。第一步是为了避免我的真实项目中出现NoClassDefFoundError错误。

在示例代码起作用之前,我还需要进行清理构建并从设备中卸载应用程序(来自早期的测试尝试)。

非常感谢您的帮助。


3

可能你需要注意这个:

注意:Android模拟器不支持Google Play服务,为了使用API,需要提供一个开发设备,例如Android手机或平板电脑。

http://developer.android.com/google/play-services/setup.html

你必须提供一个物理的开发设备来运行和调试你的应用程序。请勿使用模拟器,否则将无法正常工作。


3
我的天!为什么这个提示在主页上如此微小,并且不是每个页面上都是大红色的?我几乎整天都试图让它运行了!请帮我将其翻译成中文。 - shmoula
现在,运行Android v4.2.2或更高版本的模拟器上可以使用Play服务。 - Brian White

2

现在Google地图被包含在Fragments中,所以您需要将活动从Activity扩展为FragmetActivity,并确保如果您使用“supporrtMapFragment”,则只从support包导入Fragment。


Google 应该真正修复基本示例,以使用 SupportMapFragment。没有它就无法工作... - Muzikant

2

在你的MainActivity(或者你想要放置v2地图的每个活动中),你必须扩展FragmentActivityActivity,不管你想使用SupportMapFragment还是MapFragment。只有当你的目标API为12及以上时,才使用MapFragment类,否则请使用SupportMapFragment。这是一个微妙的区别,但它会导致错误。


1
与此建议相关:https://stackoverflow.com/a/20215481/3080835 同时我不得不将这个添加到清单文件的Application元素中:
<meta-data 
           android:name="com.google.android.gms.version" 
           android:value="@integer/google_play_services_version" />

而且它完美地运行了。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接