Search code examples
androidgoogle-mapsandroid-fragmentsnullpointerexceptionsupportmapfragment

Getting java.lang.NullPointerException in MapFragment


I am using GoogleMaps in my application. For that purpose, I have implemented SupportMapFragment Map-v2 in my custom Fragment class. But unfortunately I am getting NullPointerException for no reasons in the lines

SupportMapFragment fm = ((SupportMapFragment) getActivity ().getSupportFragmentManager ().findFragmentById (R.id.map));
            googleMap = fm.getMap();

I really dont know what to do and I am completely helpless. I even referred few similar questions from link 1, link 2 and link 3. But nothing seems to work out. Kindly help me with this. Please find my logcat error and complete code as follows.

MapFragment.java

public class MapFragment extends Fragment implements GoogleMap.OnMarkerClickListener {

    GoogleMap googleMap;    
    private Map<Marker, Integer> markerPosition = new HashMap ();
    private ImageView imgUser;
    private TextView txtName, txtLocation,txtCount;
    private ArrayList<Info> mList;

    public static MapFragment newInstance() {
        MapFragment fragment = new MapFragment();
        return fragment;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

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

        View view = inflater.inflate(R.layout.fragment_map, container, false);
        findViews (view);
        googleMapsData ();
        return view;
    }



    @Override
    public void onViewCreated (View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated (view, savedInstanceState);
        mList = getHelper ().getList ();
        counts ();
    }

    private void googleMapsData () {
        int status = GooglePlayServicesUtil.isGooglePlayServicesAvailable (getActivity ());
        if(status!= ConnectionResult.SUCCESS){ 

            int requestCode = 10;
            Dialog dialog = GooglePlayServicesUtil.getErrorDialog(status, getActivity (), requestCode);
            dialog.show();

        }else { 

            SupportMapFragment fm = ((SupportMapFragment) getActivity ().getSupportFragmentManager ().findFragmentById (R.id.map)); //This is the line getting error
            googleMap = fm.getMap(); //This is the line getting error
            googleMap.setMapType (GoogleMap.MAP_TYPE_NORMAL);
            googleMap.setOnMarkerClickListener(this);
            googleMap.setMyLocationEnabled(true);

                for(int i=0;i<mList.size ();i++){
                    drawMarker (new LatLng (Double.parseDouble (mList.get (i).getLatitude ()), Double.parseDouble (mList.get (i).getLongitude ())),i);
                }

            CameraPosition cameraPosition = new CameraPosition.Builder()
                    .target (new LatLng (Double.parseDouble ("13.0900"), Double.parseDouble ("80.2700")))
                    .zoom (7)                              
                    .build ();                   


            googleMap.animateCamera(CameraUpdateFactory.newCameraPosition (cameraPosition), new GoogleMap.CancelableCallback () {

                @Override
                public void onFinish() {
                    CameraUpdate cu_scroll = CameraUpdateFactory.scrollBy(-300, 70);
                    googleMap.animateCamera(cu_scroll);
                }

                @Override
                public void onCancel() {
                }
            });
        }

        googleMap.setOnMapClickListener(new OnMapClickListener () {
            @Override
            public void onMapClick(LatLng point) {
            }
        });


        googleMap.setOnMapLongClickListener(new OnMapLongClickListener () {
            @Override
            public void onMapLongClick(LatLng point) {
            }
        });
    }


    public void details(Info Info){
        cardBottomdetails.setVisibility (View.VISIBLE);
        txtName.setText (Info.getHotelName ());
        txtLocation.setText (Info.getCity ());
        Glide.with (getActivity ())
                .load(Constant.BASE_IP+Info.getImage ())
                .centerCrop()
                .placeholder(getResources ().getDrawable (R.drawable.img))
                .crossFade()
                .into(imgUser);

    }

    public void counts(){
        txtCount.setText (""+mList.size ());
        if(Build.VERSION.SDK_INT >= 16) {
            txtCount.setBackground (Util.drawCircle (getActivity (), 25, 25, getResources ().getColor (R.color.yellow)));
        }else{
            txtCount.setBackgroundDrawable (Util.drawCircle (getActivity (), 25, 25, getResources ().getColor (R.color.yellow)));
        }
    }

    private void drawMarker(LatLng point , int index){
        MarkerOptions markerOptions = new MarkerOptions();
        markerOptions.position (point);
        Marker marker = googleMap.addMarker(markerOptions);
        markerPosition.put (marker,index);
    }

    public void findViews(View view){
        imgUser = (ImageView)view.findViewById (R.id.img_user);
        txtName = (TextView)view.findViewById (R.id.txt_name);
        txtLocation = (TextView)view.findViewById (R.id.txt_location);
        txtCount = (TextView)view.findViewById (R.id.txt_count);
    }


    @Override
    public boolean onMarkerClick (Marker marker) {
        int index = markerPosition.get (marker);
        details (mList.get (index));
        return false;
    }

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

fragment_map.xml

 <FrameLayout 
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

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

</FrameLayout>

Logcat Error:

java.lang.NullPointerException
            at com.example.map.fragment.MapFragment.googleMapsData(MapFragment.java:105)
            at com.example.map.fragment.MapFragment.onCreateView(MapFragment.java:68)
            at android.support.v4.app.Fragment.performCreateView(Fragment.java:1789)
            at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:955)
            at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1138)
            at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:740)
            at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1501)
            at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:458)
            at android.os.Handler.handleCallback(Handler.java:733)
            at android.os.Handler.dispatchMessage(Handler.java:95)
            at android.os.Looper.loop(Looper.java:146)
            at android.app.ActivityThread.main(ActivityThread.java:5602)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:515)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1283)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1099)
            at dalvik.system.NativeStart.main(Native Method)

Note :

1) I have imported import android.support.v4.app.Fragment; in my code.

2) The code was working fine when I used this in Activity. The problem occurs only when I switch from Activity to Fragment.

Thanks in advance. All of your solutions would be more useful and valuable to resolve my issue.


Solution

  • I got the same issue long back when I was newly working with maps. The issue is because it takes time for google map to load ( if you're using inside a fragment, you can expect this load time to be huge) and when you try to access map before it is being loaded, you'll get NullPointerException saying map reference went null. You should wait for the map to load first and then you should access the map views. You have pre-defined callback for that and here is how you should use it.

    supportMapFragment.getMapAsync(new OnMapReadyCallback() {
    
            @Override
            public void onMapReady(GoogleMap map) {
    
                googleMap = map; 
            googleMap.setMapType (GoogleMap.MAP_TYPE_NORMAL);
            googleMap.setOnMarkerClickListener(this);
            googleMap.setMyLocationEnabled(true);
    
                for(int i=0;i<mList.size ();i++){
                    drawMarker (new LatLng (Double.parseDouble (mList.get (i).getLatitude ()), Double.parseDouble (mList.get (i).getLongitude ())),i);
                }
    
            CameraPosition cameraPosition = new CameraPosition.Builder()
                    .target (new LatLng (Double.parseDouble ("13.0900"), Double.parseDouble ("80.2700")))
                    .zoom (7)                              
                    .build ();                   
    
    
            googleMap.animateCamera(CameraUpdateFactory.newCameraPosition (cameraPosition), new GoogleMap.CancelableCallback () {
    
                @Override
                public void onFinish() {
                    CameraUpdate cu_scroll = CameraUpdateFactory.scrollBy(-300, 70);
                    googleMap.animateCamera(cu_scroll);
                }
    
                @Override
                public void onCancel() {
                }
            });
            }
        });