Google地图片段在片段内返回空值

所以我有一个包含地图片段的空片段。 每当我尝试激活包含地图的片段,我的应用程序崩溃,并在这一行返回一个空指针错误:

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

完整的错误信息:

 java.lang.NullPointerException: Attempt to invoke virtual method 'com.google.android.gms.maps.GoogleMap com.google.android.gms.maps.MapFragment.getMap()' on a null object reference at com.collusion.serviceassistant.ReturnVisitDetails.onViewCreated(ReturnVisitDetails.java:39) at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:904) at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1062) at android.app.BackStackRecord.run(BackStackRecord.java:684) at android.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1447) at android.app.FragmentManagerImpl$1.run(FragmentManager.java:443) at android.os.Handler.handleCallback(Handler.java:733) at android.os.Handler.dispatchMessage(Handler.java:95) at android.os.Looper.loop(Looper.java:136) at android.app.ActivityThread.main(ActivityThread.java:5001) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601) 

这是我的片段代码:

 import android.app.Activity; import android.app.Dialog; import android.net.Uri; import android.os.Bundle; import android.app.Fragment; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import com.google.android.gms.common.ConnectionResult; import com.google.android.gms.common.GooglePlayServicesUtil; import com.google.android.gms.maps.CameraUpdateFactory; import com.google.android.gms.maps.GoogleMap; import com.google.android.gms.maps.MapFragment; import com.google.android.gms.maps.MapView; import com.google.android.gms.maps.model.BitmapDescriptorFactory; import com.google.android.gms.maps.model.LatLng; import com.google.android.gms.maps.model.Marker; import com.google.android.gms.maps.model.MarkerOptions; public class ReturnVisitDetails extends Fragment { static final LatLng HAMBURG = new LatLng(53.558, 9.927); static final LatLng KIEL = new LatLng(53.551, 9.993); private GoogleMap map; public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View rootView = inflater.inflate(R.layout.fragment_return_visit_add, container, false); return rootView; } public void onViewCreated(View view, Bundle savedInstanceState) { // Get a handle to the Map Fragment map = ((MapFragment) getFragmentManager().findFragmentById(R.id.map)) .getMap(); Marker hamburg = map.addMarker(new MarkerOptions().position(HAMBURG) .title("Hamburg")); Marker kiel = map.addMarker(new MarkerOptions() .position(KIEL) .title("Kiel") .snippet("Kiel is cool") .icon(BitmapDescriptorFactory .fromResource(R.drawable.ic_launcher))); // Move the camera instantly to hamburg with a zoom of 15. map.moveCamera(CameraUpdateFactory.newLatLngZoom(HAMBURG, 15)); // Zoom in, animating the camera. map.animateCamera(CameraUpdateFactory.zoomTo(10), 2000, null); } } 

和我的父级片段XML布局:

 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.collusion.serviceassistant.ReturnVisitDetails" android:background="#009688"> <fragment android:id="@+id/map" android:layout_width="match_parent" android:layout_height="match_parent" class="com.google.android.gms.maps.MapFragment" /> </RelativeLayout> 

任何人都有一个想法,为什么地图片段返回null?

编辑:所以现在我有这个代码来初始化地图:

 MapFragment mapFragment = new MapFragment(); FragmentTransaction transaction = getChildFragmentManager().beginTransaction(); transaction.add(R.id.rl_map_container, mapFragment).commit(); map = mapFragment.getMap(); Marker hamburg = map.addMarker(new MarkerOptions().position(HAMBURG) .title("Hamburg")); Marker kiel = map.addMarker(new MarkerOptions() .position(KIEL) .title("Kiel") .snippet("Kiel is cool") .icon(BitmapDescriptorFactory .fromResource(R.drawable.ic_launcher))); // Move the camera instantly to hamburg with a zoom of 15. map.moveCamera(CameraUpdateFactory.newLatLngZoom(HAMBURG, 15)); // Zoom in, animating the camera. map.animateCamera(CameraUpdateFactory.zoomTo(10), 2000, null); 

它仍然返回一个空指针值

当我尝试将我的Eclipse项目移植到Android Studio项目时,发生了这个问题。

 java.lang.NullPointerException: Attempt to invoke virtual method 'com.google.android.gms.maps.GoogleMap com.google.android.gms.maps.SupportMapFragment.getMap()' on a null object reference 

我用这样的片段活动:

 ((SupportMapFragment) getActivity().getSupportFragmentManager().findFragmentById(R.id.mapToday)).getMap(); 

不过,问题在于,之前我使用的是特定版本的Google Play服务(4.3.23)。

但是Gradle构buildselect了最新的版本( compile 'com.google.android.gms:play-services:+')

我尝试了一些其他特定的版本,如(6.1.71)。 但是还是给了零点例外。

我使用了和以前一样的旧版本,并且工作。

 compile 'com.google.android.gms:play-services:4.3.23' 

这对我来说是一个临时的解决scheme。 但是,当我需要更新到新的播放服务库时,这将是一个问题。

似乎没有具体的地图库,这个版本可用于Gradle构build,当我尝试这样的:

 compile 'com.google.android.gms:play-services-maps:4.3.23' 

我已经解决了这个问题。 这一行当我有一个viewpager:

 mMap = ((SupportMapFragment) MainActivity.fragmentManager .findFragmentById(R.id.mapView)).getMap(); 

你必须改变这个:

  mMap = ((SupportMapFragment) getChildFragmentManager() .findFragmentById(R.id.mapView)).getMap(); 

您的类从Fragment扩展而来,并且您正在使用在布局中声明的Fragment ,但嵌套片段仅在dynamic添加时才起作用。

所以,你有两个select:

1)从FragmentAcivity扩展而不是Fragment并采用适当的方法。

2)dynamic添加Fragment ,如下所示:

// ReturnVisitDetails

 MapFragment mapFragment = new MapFragment(); FragmentTransaction transaction = getChildFragmentManager().beginTransaction(); transaction.add(R.id.rl_map_container, mapFragment).commit(); 

//布局

 <FrameLayout android:id="@+id/rl_map_container" android:layout_width="match_parent" android:layout_height="match_parent" /> 

– 更新 –

Fragment使用Google地图的完整示例:

// TestFragmentActivity

 public class TestFragmentActivity extends android.support.v4.app.FragmentActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.test_fragment_activity); } } 

// TestFragment

 public class TestFragment extends android.support.v4.app.Fragment { @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View rootView = inflater.inflate(R.layout.test_fragment, container, false); CustomMapFragment mapFragment = new CustomMapFragment(); FragmentTransaction transaction = getChildFragmentManager().beginTransaction(); transaction.add(R.id.map_container, mapFragment).commit(); return rootView; } } 

// CustomMapFragment

 public class CustomMapFragment extends com.google.android.gms.maps.SupportMapFragment { private final LatLng HAMBURG = new LatLng(53.558, 9.927); @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); GoogleMap googleMap = getMap(); googleMap.addMarker(new MarkerOptions().position(HAMBURG).title("Hamburg")); googleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(HAMBURG, 15)); googleMap.animateCamera(CameraUpdateFactory.zoomTo(10), 2000, null); } } 

//test_fragment_activity.xml

 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <fragment android:id="@+id/map" class="your_package.TestFragment" android:layout_width="match_parent" android:layout_height="match_parent" /> </RelativeLayout> 

//test_fragment.xml

 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <FrameLayout android:id="@+id/map_container" android:layout_width="match_parent" android:layout_height="match_parent"/> </RelativeLayout> 

我search了很多的线程,因为我在旧的谷歌播放服务有同样的问题。 正如维克多说,你的类从片段扩展,它必须使用布局中定义的另一个片段,所以最好的办法是使用getChildFragmentManager()而不是getSupportFragmentManager()

另外getMap() method is deprecated现在已经getMap() method is deprecated了,正如google文档中提到的那样。 请参阅以下内容: – https://developers.google.com/android/reference/com/google/android/gms/maps/MapFragment.html#getMap();

以下是我在老玩法服务的各种设备上testing的工作代码。 如果设备有较旧的Google Play服务,并且GoogleMap对象返回null,则会生成默认消息:

 class MyFragment extends Fragment { SupportMapFragment myMapFragment; GoogleMap myMap; View convertView; FragmentManager fm; public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { convertView=inflater.inflate(R.layout.mymap,null); fm=getChildFragmentManager(); myMapFragment=(SupportMapFragment) fm.findFragmentById(R.id.myMapId); // here instead of using getMap(), we are using getMapAsync() which returns a callback and shows map only when it gets ready. //it automatically checks for null pointer or older play services version, getMap() is deprecated as mentioned in google docs. myMapFragment.getMapAsync(new OnMapReadyCallback() { @Override public void onMapReady(GoogleMap googlemap) { // TODO Auto-generated method stub myMap=googlemap; startMap(); } }); return convertView; } } 

看到这个线程的更多信息。

这可能是一个迁移到21的目标sdk版本的问题? 如果是这样,下面的解决scheme可能是你感兴趣的:

MapFragment或MapView getMap()在棒棒糖上返回null

尝试使用SupportMapFragment而不是MapFragment。 这段代码适用于我的片段,只是试过了:

 import android.os.Bundle; import android.support.v4.app.Fragment; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import com.google.android.gms.maps.CameraUpdateFactory; import com.google.android.gms.maps.GoogleMap; import com.google.android.gms.maps.SupportMapFragment; import com.google.android.gms.maps.model.BitmapDescriptorFactory; import com.google.android.gms.maps.model.LatLng; import com.google.android.gms.maps.model.Marker; import com.google.android.gms.maps.model.MarkerOptions; public class MapFragment extends Fragment { private GoogleMap map; static final LatLng HAMBURG = new LatLng(53.558, 9.927); static final LatLng KIEL = new LatLng(53.551, 9.993); @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View rootView = inflater.inflate(R.layout.fragment_map, container, false); // Get a handle to the Map Fragment map = ((SupportMapFragment) getFragmentManager().findFragmentById( R.id.map)).getMap(); Marker hamburg = map.addMarker(new MarkerOptions().position(HAMBURG) .title("Hamburg")); Marker kiel = map.addMarker(new MarkerOptions() .position(KIEL) .title("Kiel") .snippet("Kiel is cool") .icon(BitmapDescriptorFactory .fromResource(R.drawable.ic_launcher))); // Move the camera instantly to hamburg with a zoom of 15. map.moveCamera(CameraUpdateFactory.newLatLngZoom(HAMBURG, 15)); // Zoom in, animating the camera. map.animateCamera(CameraUpdateFactory.zoomTo(10), 2000, null); return rootView; } } 

和你的布局:

 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity" > <fragment android:id="@+id/map" android:name="com.example.test.MapFragment" android:layout_width="match_parent" android:layout_height="match_parent" class="com.google.android.gms.maps.SupportMapFragment" /> </RelativeLayout> 

问题可能与您的targetSdkVersion高于Android支持库使用的版本有关。

那是我的情况,在我们一直在研究targetSdkVersion的项目targetSdkVersion是21,而Support Library版本是19.0.0。 改变targetSdkVersion为19固定的问题。

我可以面对同样的问题,但最终我可以解决这个错误。现在地图正确地显示…

=>在onCreateView()方法内的Fragment中调用initilizeMap()方法…

=>声明全局variables像,

 private GoogleMap googleMap; private void initilizeMap() { try { // Changing marker icon // marker.icon(BitmapDescriptorFactory.fromResource(R.drawable.my_marker_icon))); // adding marker if (googleMap == null) { googleMap = ((MapFragment)getActivity().getFragmentManager() .findFragmentById(R.id.map)).getMap(); // create marker MarkerOptions marker = new MarkerOptions().position( new LatLng(latitude, longitude)).title( "YourCare"); // Changing marker icon MarkerOptions icon = marker.icon(BitmapDescriptorFactory .defaultMarker(BitmapDescriptorFactory.HUE_ROSE)); // adding marker LatLng latLng = new LatLng(latitude, longitude); CameraUpdate cameraUpdate = CameraUpdateFactory.newLatLngZoom( latLng, 15); googleMap.animateCamera(cameraUpdate); // locationManager.removeUpdates(this); googleMap.addMarker(marker); googleMap.setMyLocationEnabled(true); // check if map is created successfully or not if (googleMap == null) { Toast.makeText(getActivity(), "Sorry! unable to create maps", Toast.LENGTH_SHORT) .show(); } } } catch (Exception e) { System.out.print("Error :" + e.getMessage()); } }