1

I am trying to create a map in a Fragment but keep getting this error:

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
        at com.new.newapps.activity.MapsFragment.initilizeMap(MapsFragment.java:41)
        at com.new.newapps.activity.MapsFragment.onResume(MapsFragment.java:52)

I am not sure how to fix this. Please have a look at my code below.

MapsFragment class:

public class MapsFragment extends Fragment {

public MapsFragment(){}
GoogleMap googleMap;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {

    View rootView = inflater.inflate(R.layout.fragment_distance, container, false);
    try {
        initilizeMap();
    } catch (Exception e) {
        e.printStackTrace();
    }
    return rootView;
}

private void initilizeMap() {
    if (googleMap == null) {
        googleMap = ((SupportMapFragment) getFragmentManager()
                .findFragmentById(R.id.map))
                .getMap();
        if (googleMap == null) {
            Toast.makeText(getActivity(),
                    "Sorry! unable to create maps", Toast.LENGTH_SHORT)
                    .show();
        }
    }
}
@Override
public void onResume() {
    super.onResume();
    initilizeMap();
    if (googleMap != null) {

    }
    CameraPosition cameraPosition = new CameraPosition.Builder()
            .target(new LatLng(xx.xxxx, xx.xxxx))
            .zoom(10)
            .bearing(0)
            .tilt(80)
            .build();

    googleMap.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));
}
@Override
public void onAttach(Activity activity) {
    super.onAttach(activity);
}

@Override
public void onDetach() {
    super.onDetach();
}
}

Then in my layout file:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
 android:orientation="vertical"
 android:layout_width="fill_parent"
 android:layout_height="fill_parent">

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


</RelativeLayout>

And this is my gradle file:

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

Excuse my bad English :-)

Any help will be appreciated! Thanks

2 Answers2

0

This is an answer an a response to this comment

So basically, folks use SupportMapFragment#getMap() to get the GoogleMap object for quite a long time. And there are too many questions/answers/discussions/work-arounds/tricks to get rid of the NPE it may produce.

And finally, Google made a right step which you can see here: deprecate that getMap() method and add getMapAsync() instead

So your app/fragment which contains a MapView/MapFragment must implement the com.google.android.gms.maps.OnMapReadyCallback interface and override its onMapReady(GoogleMap map) where you get the Map object. The idea is that GoogleMap object needs time to be initialized, so if you call the deprecated getMap() method, what you get may be a NULL object. It causes NPE. So the right way is to get it a-synchronically and setup a callback to retrieve the non-null object.

I created a github repo: Google Map Practice to help you see how you can easily implement that, and go for the better way. I'm really surprised that Android Studio by default create a Google Map Activity (which is DefaultMapsActivity in the repo) with the deprecated getMap() usage. It maybe because they didn't update their legacy template for a long time. But since Google notice you about new API, please take a look. Cheer!

P/S: If you want to try my repo, don't forget to setup your Google Api Key in /app/src/release/res/values/google_maps_api.xml as well as /app/src/debug/res/values/google_maps_api.xml

Community
  • 1
  • 1
Nguyễn Hoài Nam
  • 1,130
  • 1
  • 9
  • 20
-1

You have did small mistake i think, Check out OnResume Method:

@Override
public void onResume() {
    super.onResume();
    initilizeMap();
    if (googleMap != null) {

    }
}

Change this to,

@Override
public void onResume() {
    super.onResume();

    if (googleMap != null) {
        initilizeMap();
    }
}
Shvet
  • 1,159
  • 1
  • 18
  • 30
  • @Wildness Glad to help you. – Shvet Aug 13 '15 at 10:49
  • Why do you need to initialize your map if it is not null. And this answer works because you check the map is null in that method, so the snippet just do nothing. – Nguyễn Hoài Nam Aug 13 '15 at 10:54
  • @NguyễnHoàiNam I just suggested where he did mistake. Please check my answer first and what i have written in it. – Shvet Aug 13 '15 at 10:56
  • @Shvet you check this before calling the method: googleMap != null , but in that method, he checks if that googleMap is null then run the rest. So basically your fix do nothing --> no crash. I will update an answer later, but consider to use latest google play service library, use MapView instead of SupportMapFragment if you are adding a map in a fragment, and use getMapAsync to correctly get the map object. – Nguyễn Hoài Nam Aug 13 '15 at 11:01
  • @NguyễnHoàiNam please check this [URL](http://stackoverflow.com/questions/27504606/how-to-implement-draggable-map-like-uber-android/30346234#30346234). I have implemented that already. – Shvet Aug 13 '15 at 11:07