Search code examples
androidgoogle-mapsandroid-fragmentsgoogle-maps-api-2android-tabs

getting google maps in a tabbed android app


I have spent a while trying to get this to work and I keep getting stuck somewhere at every tutorial. In short I am trying to make a tabbed app where one of the tabs it a google maps.

I have fixed all of the usual mistakes:

I have downloaded everything relevant through SDK. I have an API key in place. I have added compile com.google.android.gms:play-services:7.5.0 to my dependencies.

I am trying to follow this code, but it wasn't fully working for me, so I have changed it a bit, but I am still running into a wall.

My current error is java.lang.NullPointerException: IBitmapDescriptorFactory is not initialized. I figured this would have been initialized in getMapAsync.

Here is my java code:

public class MapFragment extends Fragment{

    MapView mMapView;
    private GoogleMap googleMap;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // inflat and return the layout
        View v = inflater.inflate(R.layout.fragment_location_info, container,
                false);

        mMapView = (MapView) v.findViewById(R.id.mapView);
        mMapView.onCreate(savedInstanceState);

        mMapView.onResume();// needed to get the map to display immediately

        mMapView.getMapAsync(new OnMapReadyCallback() {
            @Override
            public void onMapReady(GoogleMap googleMap) {
                MapsInitializer.initialize(getApplicationContext());
                // latitude and longitude
                double latitude = 17.385044;
                double longitude = 78.486671;


                // create marker
                MarkerOptions marker = new MarkerOptions().position(new LatLng(latitude, longitude)).title("Hello Maps");

                // Changing marker icon
                marker.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_ROSE));
            }
        });

        //MapsInitializer.initialize(getApplicationContext());

        googleMap = mMapView.getMap();
        // latitude and longitude
        double latitude = 17.385044;
        double longitude = 78.486671;


        // create marker
        MarkerOptions marker = new MarkerOptions().position(new LatLng(latitude, longitude)).title("Hello Maps");

        // Changing marker icon
        marker.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_ROSE));

        // adding marker
        googleMap.addMarker(marker);

        CameraPosition cameraPosition = new CameraPosition.Builder().target(new LatLng(17.385044, 78.486671)).zoom(12).build();

        googleMap.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));

        // Perform any camera updates here
        return v;
    }

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

    @Override
    public void onPause() {
        super.onPause();
        mMapView.onPause();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        mMapView.onDestroy();
    }

    @Override
    public void onLowMemory() {
        super.onLowMemory();
        mMapView.onLowMemory();
    }
}

Solution

  • It looks like your code is in the middle of a transformation. You're calling both getMapAsync() AND getMap().

    Just use getMapAsync(), and don't do anything with the map until you get the onMapReady() callback.

    Also, you don't need MapsInitializer. From the documentation:

    Use this class to initialize the Google Maps Android API if features need to be used before obtaining a map. It must be called because some classes such as BitmapDescriptorFactory and CameraUpdateFactory need to be initialized.

    If you are using MapFragment or MapView and have already obtained a (non-null) GoogleMap by calling getMap() on either of these classes, then you do not need to worry about this class. See the sample application for some examples.

    Here is your code fixed up a bit:

    public class MapFragment extends Fragment implements OnMapReadyCallback {
    
            MapView mMapView;
            private GoogleMap googleMap;
    
            @Override
            public View onCreateView(LayoutInflater inflater, ViewGroup container,
                                     Bundle savedInstanceState) {
                // inflate and return the layout
                View v = inflater.inflate(R.layout.fragment_location_info, container,
                        false);
    
                mMapView = (MapView) v.findViewById(R.id.mapView);
                mMapView.onCreate(savedInstanceState);
    
                //mMapView.onResume(); // should not be needed
    
                mMapView.getMapAsync(this);
    
                //MapsInitializer.initialize(getApplicationContext());
    
                // Perform any camera updates here
                return v;
            }
    
            @Override
            public void onMapReady(GoogleMap gMap) {
    
                googleMap = gMap;
    
                mMapView.onResume(); //call this here if you really need to
    
                //MapsInitializer.initialize(getApplicationContext());
                // latitude and longitude
                double latitude = 17.385044;
                double longitude = 78.486671;
    
                // create marker
                MarkerOptions marker = new MarkerOptions().position(new LatLng(latitude, longitude)).title("Hello Maps");
    
                // Changing marker icon
                marker.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_ROSE));
    
                // adding marker
                googleMap.addMarker(marker);
    
                CameraPosition cameraPosition = new CameraPosition.Builder().target(new LatLng(17.385044, 78.486671)).zoom(12).build();
    
                googleMap.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));
    
            }
       //.........................