Google Maps Fragment returning null inside a fragment

匿名 (未验证) 提交于 2019-12-03 01:25:01

问题:

So I have an empty fragment that contains a map fragment. Whenever I try to activate the fragment containing the map, my app crashes and returns a null pointer error on this line:

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

Full Error message:

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) 

Here is my fragment code:

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);     } } 

And my parent fragment XML layout:

Anyone have an idea why the map fragment is returning null?

EDIT: So now I have this code to initialize the map:

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); 

And it still returns a null pointer value

回答1:

This issue happened to me when I tried to port my Eclipse project to Android Studio project.

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 

I used it with a Fragment Activity like this:

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

However, the problem was, earlier I was using a specific version of Google Play Services (4.3.23).

But the Gradle build select the most recent version (compile 'com.google.android.gms:play-services:+')

I tried some other specific version like (6.1.71). But still gave null point exception.

I used the same old version as I used before and it worked.

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

This works for me as a temporary solution. However, this will be a problem when I need to update to a new play services library.

It seems that there is no specific map library with this version available for Gradle build when I try like this:

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


回答2:

I have solved the issue. this line when I have a viewpager:

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

you have to change to this:

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


回答3:

Your class extends from Fragment, and you are using a Fragment declared in the layout, but nested fragment only work when they are added dynamically.

So, you have two options:

1) Extending from FragmentAcivity instead of Fragment and applying the proper methods.

2) Add the Fragment dynamically, as follow:

//ReturnVisitDetails

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

//Layout

--UPDATED--

A complete example to use Google Maps inside a Fragment:

//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

//test_fragment.xml



回答4:

I searched for a lot of threads on this as I was having the same issue with older google play services. As Victor said that your class extends from fragment and it has to use another fragment defined in the layout, So best approach will be to use getChildFragmentManager() instead of getSupportFragmentManager().

Also getMap() method is deprecated now as mentioned in google docs. Please refer this for more:- https://developers.google.com/android/reference/com/google/android/gms/maps/MapFragment.html#getMap()

Below is the working code I have tested on various devices of older play services. This will generate the default message in case of device having older google play services and in case object of GoogleMap returns 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;     }  } 

See this thread for more info.



回答5:

Could this be an issue of migrating to a target sdk version of 21? If so, the following solution may be of interest to you:

MapFragment or MapView getMap() returns null on Lollipop



回答6:

Try using SupportMapFragment instead of MapFragment. This code works for me for a Fragment, just tried it:

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; } } 

and your layout:



回答7:

The problem may be related to the fact that your targetSdkVersion is higher than the version of Android Support Library used.

That was my case, in one of the projects we've been working on targetSdkVersion was 21, while Support Library version was 19.0.0. Changing targetSdkVersion to 19 fixed the problem.



回答8:

I can face same problem but finally i can solve that error.Now Map is Properly showing...

=> Call initilizeMap() Method in Fragment within a onCreateView() method...

=> Declare Global Variable like ,

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());     }  } 


标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!