在Lollipop系统上,MapFragment或MapView的getMap()方法返回null

19

我长期以来一直在Android 4.x版本上使用谷歌地图API v2,没有问题。现在,我在我的Nexus设备上(5和7)安装了最新的棒棒糖版本,试图实现应用程序的材料化。

我想指出的是,在KitKat上一切正常,我描述的问题只出现在Lollipop上。

在我的XML源代码中,我正在使用MapFragment(Google Play服务库版本6.1.11)。

<fragment android:id="@+id/map"
          android:layout_width="match_parent"
          android:layout_height="match_parent"
          android:name="com.google.android.gms.maps.MapFragment"/>
在Java代码中,我重写了OnPause()方法以达到地图的目的:
GoogleMap map = ((MapFragment) getFragmentManager().findFragmentById(R.id.map)).getMap();
在这一行代码中它抛出了NullPointerException异常。在调试器中,应用程序能够找到片段,但无法返回GoogleMap。我还尝试使用MapView,但它也返回null。 最奇怪的是,地图在应用程序本身中可以正常加载,但在代码中我无法访问它以便进行操作。

我会检查是否存在时间问题(片段尚未创建)。尝试延迟一段时间后再获取片段以进行实验。 - Yaroslav Mytkalyk
这个问题在这个链接中得到了解答:https://dev59.com/HGEh5IYBdhLWcg3wYSrt#22624155希望能对你有所帮助 ;) - Luis Pereira
@DoctororDrive - 尝试了3秒循环,但没有成功。 - mroczis
4个回答

60

我遇到了完全相同的问题,但这是对我有用的解决方法:

将此代码...

GoogleMap map = ((MapFragment) getFragmentManager().findFragmentById(R.id.map)).getMap();

替换为这个...

GoogleMap map = getMapFragment().getMap();

然后试试这个方法...

private MapFragment getMapFragment() {
    FragmentManager fm = null;

    Log.d(TAG, "sdk: " + Build.VERSION.SDK_INT);
    Log.d(TAG, "release: " + Build.VERSION.RELEASE);

    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
        Log.d(TAG, "using getFragmentManager");
        fm = getFragmentManager();
    } else {
        Log.d(TAG, "using getChildFragmentManager");
        fm = getChildFragmentManager();
    }

    return (MapFragment) fm.findFragmentById(R.id.map);
}

1
这在Lollipop上是一个已知的问题吗? - Jay Sidri
@Rhisiart,感谢您的回答。我还想知道一件事情。在使用这段代码后,我们如何在导航抽屉中处理此片段的返回堆栈?因为在使用此代码后,返回堆栈与此片段不起作用。 - Deep Singh
@DeepSingh 如果没有更多细节,我只能告诉你的是,我的片段扩展了com.google.android.gms.maps.MapFragment,并在android.support.v13.app.FragmentTabHost中托管,与另外两个android.widget.TabHost $ TabSpec一起,在针对android:targetSdkVersion="22"的android.app.Activity中进行目标定位。您可以在此应用程序中实际查看它(从导航抽屉中选择“查找自然事件”或“查找事件”)- https://play.google.com/store/apps/details?id=org.wildlifetrusts.naturefinder - Rhisiart
2
我希望我能够在这个答案上点赞多次。 - Shubham Chaudhary
我正在尝试实现这个解决方案,但它提示getChildFragmentManager未定义。我在一个活动中。有人可以帮帮我吗? - Frildoren
显示剩余3条评论

13

谷歌现在提供了一种更方便的获取地图的方法,使用以下方法:

    myMapFragment.getMapAsync(new OnMapReadyCallback) {
         @Override
         public void onMapReady(GoogleMap googleMap) {
             myMap = googleMap;
         }
    });

3
在我的情况下,这是正确的答案。被接受的答案似乎假设MapFragment为null,但根据问题(问题中MapFragment不为null,但getMap()返回值为null)并非如此。 - BoD

3

1

你尝试过使用 isGooglePlayServicesAvailable 检查为什么它返回 null 吗? 在 getmap 中,null 有很多原因,请尝试使用此方法检查为什么它返回 null。


1
是的,我做到了。最终我通过重新实现MapView解决了我的问题。MapFragment似乎根本不起作用。 - mroczis
@mroczis,你能描述一下你是怎么解决它的吗? - itsmewajid
1
我最终使用了MapView,并设置了它的生命周期(在activity的onCreate()方法中调用mMapView.onCreate(),在activity的onPause()方法中调用mMapView.onPause()等),它确实起作用了。 MapFragment似乎无法在Lollipop上附加到FragmentManager。 - mroczis

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