MapFragment causing NullPointerException at getMapAsync(this) method

11,743

Solution 1

I finally solved this issue for myself by observing the given answers in SO. I compared my code and the code in the answers. It seems to me that there is some confusion about this API and Google's implementation is very broad. I got this exception thrown repeatedly:

Attempt to invoke interface method 'void com.google.maps.api.android.lib6.e.fl.o()' on a null object reference

I still have no idea whats wrong with some of these implementations in SO questions that are getting the same exception, but this worked for me and it might work for someone else.

These are the the things you need to check:

  1. Make sure you have both of these (I had only the api key meta-data)

        <meta-data
            android:name="com.google.android.geo.API_KEY"
            android:value="@string/google_maps_key" />
        <meta-data
            android:name="com.google.android.gms.version"
            android:value="@integer/google_play_services_version" />
    
  2. You have a fragment in xml like this with the class attribute being correct as below

       <fragment
        android:id="@+id/google_map_fragment"
        class="com.google.android.gms.maps.SupportMapFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>
    

In my case the map fragment is a child, inside another fragment.

This parent fragment apparently should not be a MapFragment or a SupportMapFragment. After changing it from SupportMapFragment to Fragment the map showed perfectly fine.

public class ParentFragment extends Fragment {

I left everything else as it was before but instead of getting the map in onCreateView I got it in onViewCreated like this:

@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);

    mapFragment = (SupportMapFragment) getChildFragmentManager().findFragmentById(R.id.rewards_google_map_area);
    if (mapFragment != null) {
        LocationManager locationManager = (LocationManager) getActivity().getSystemService(Context.LOCATION_SERVICE);
        if (locationManager != null && mapFragment.getMap() != null) {
            googleMap=mapFragment.getMap();
            //after this you do whatever you want with the map
        }
    }

}

I changed nothing else and I did not mess with the rootView or parentView. As you would see in the the answer from @Konstantin Loginov

Try it out and let me know.

Solution 2

In my case I use raw MapView statically in a Fragment's xml. The problem was that I had to move the call forwarding mMapView.onCreate(...) to onViewCreated(...) because in onCreate() mMapView is not yet inflated. If you don't use MapView then you should double-check in which moment you call getMap(). I must be after the internal MapView is inflated.

Solution 3

If you use mapView just ensure that you called mapView.onCreate() before mapView.getMapAsync(). If you are using fragment and view still not initialized you are also able to call mapView.onCreate() in onViewCreated() method.

Solution 4

I've been struggling with similar issue a while ago. The key was to getMap() in a proper moment, in onViewCreated() of the Fragment:

public class LocationFragment extends Fragment {

    private SupportMapFragment locationMap;
    private View rootView;

    protected View getFragmentView() {
        View view = getView();
        if (view == null) {
            view = rootView;
        }
        return view;
    }

    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View rootView = getFragmentView();
        if (rootView != null) {
            ViewGroup parent = (ViewGroup) rootView.getParent();
            if (parent != null) {
                parent.removeView(rootView);
            }
        }

        try {
            rootView = inflater.inflate(R.layout.fragment_signup_specify_location, container, false);
        } catch (InflateException ex) {
            Log.e(LOG_TAG, "Inflate Exception in onCreateView; Caused by map fragment", ex);
        }
        ......
        return getFragmentView();
    }

    @Override
    public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        locationMap = (SupportMapFragment) getChildFragmentManager().findFragmentById(R.id.locationMap);
        if (locationMap != null) {
            LocationManager locationManager = (LocationManager) getActivity().getSystemService(Context.LOCATION_SERVICE);
            if (locationManager != null && locationMap.getMap() != null) {
                locationMap.getMap().setMyLocationEnabled(true);
            }
        }
    }
}

And the XML for it looks like yours:

<FrameLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <fragment
        android:id="@+id/locationMap"
        android:layout_above="@+id/locationLabelTextView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:name="com.google.android.gms.maps.SupportMapFragment" />
</FrameLayout>

Then, in onViewCreated() you can notify Activity, that your map-fragment is ready to use.

I hope, it helps

Solution 5

UPDATE 2019

If you're still having this problems, try this :

Don't extend SupportMapFrangemt !

public class MyFragment extends Fragment {

private SupportMapFragment fragment;
private GoogleMap map;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    return inflater.inflate(R.layout.layout_with_map, container, false);
}

@Override
public void onActivityCreated(Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);
    FragmentManager fm = getChildFragmentManager();
    fragment = (SupportMapFragment) fm.findFragmentById(R.id.map_container);
    if (fragment == null) {
        fragment = SupportMapFragment.newInstance();
        fm.beginTransaction().replace(R.id.map_container, fragment).commit();
    }
}

}

Share:
11,743
Kavin Prabhu
Author by

Kavin Prabhu

Android by Passion. Design by Interest. Lover of Kotlin. Affair with Java. Balancing the Rest.

Updated on June 09, 2022

Comments

  • Kavin Prabhu
    Kavin Prabhu almost 2 years

    I have implemented an activity which adds MapFragment at run time. The MapFragment xml has static fragment and I'm trying to get add at run time. Also I found there are some issues in Lollipop adding the map fragment at runtime. Kindly check Issue raised and temporary solution

    I have also given my codes below,

    fragment_map.xml

    <FrameLayout 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=".fragment.MapsFragment">
    
    <fragment
        android:id="@+id/map"
        android:name="com.google.android.gms.maps.SupportMapFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context="appCreators.bloodfinder.activity.MapsActivity"/>
    
    <include
        android:id="@+id/layout"
        layout="@layout/template_custom_spinner"/>
    
    </FrameLayout>
    

    MapsFragment.java

    Implements onMapReadyCallback

    public class MapsFragment extends SupportMapFragment implements OnMapReadyCallback
    

    In onResume callback

    @Override
    public void onResume() {
        super.onResume();
        ((SupportMapFragment) getChildFragmentManager().findFragmentById(R.id.map)).getMapAsync(this);
    }
    

    this always return me null and I have also tried,

    ((SupportMapFragment) getActivity().getSupportFragmentManager().findFragmentById(R.id.map)).getMapAsync(this);
    

    this also return NullPointerException

    MapsActivity.java

    getSupportFragmentManager().beginTransaction().add(R.id.fragmentContainer, MapsFragment.newInstance()).commit();
    

    I add this at onCreate method of Activity callback.

    I'm not able to figure out why I'm still getting NullPointerException!

    Some times I get Attempt to invoke interface method 'void com.google.maps.api.android.lib6.e.fl.o()' on a null object reference

    Help will be appreciated!

    UPDATE: Still not fixed I'm getting the following error. I looked into logs but no clue why this is happening.

    Unable to resume activity {MapsActivity}: java.lang.NullPointerException: Attempt to invoke interface method 'void com.google.maps.api.android.lib6.e.fl.o()' on a null object reference
    
  • Kavin Prabhu
    Kavin Prabhu over 8 years
    I'll check this and let you know!
  • Kavin Prabhu
    Kavin Prabhu over 8 years
    Hey I tried, But I'm getting this error Unable to resume activity {MapsActivity}: java.lang.NullPointerException: Attempt to invoke interface method 'void com.google.maps.api.android.lib6.e.fl.o()' on a null object reference. I think there is something else which is causing this problem! And it's not giving me the exact line or the cause of the problem. I googled enough but ended up nothing!
  • Arnold Balliu
    Arnold Balliu over 8 years
    Tried this. Same issue. That exception is still there.
  • Kavin Prabhu
    Kavin Prabhu over 8 years
    It looks promising. I'll try and let you know
  • Kavin Prabhu
    Kavin Prabhu over 8 years
    Worked link charm! The mistake which I did is extending SupportMapFragment instead of Fragment. Changing to Fragment worked. Other scenario's were perfect in my case. Thanks a lot.