Mazharul Islam
Mazharul Islam

Reputation: 70

Unable to get the GoogleMap object

I have created a MapFragment class. Here I have created GoogleMap object by googleMap = mMapView.getMap() I have have a method ParserTask If I call ParserTask from onCreate of this method then ParserTask works succesfully and googleMap.addPolyline(lineOptions)works. But If I call method ParserTask from another Activity then googleMap.addPolyline(lineOptions) does not work, it shows null pointer exception. I think here googleMap does not get the instance of MapView. Now can anyone please give me a suggestion so that I can get the instance of googleMap in ParserTask If it is called from another activity. I have attached my code below:

public class MapFragment extends Fragment implements
        GoogleMap.OnInfoWindowClickListener{

    MapView mMapView;

    private static final int MAP_ZOOM_AMOUNT=17;
    private TextView locName;
    private TextView mapIndicator;
    private GoogleMap googleMap=null;
    private String locationName;
    private String mapIndicatorText;
    private int categoryId;
    private int locationNameId;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.fragment_map, container,
                false);
        mMapView = (MapView) rootView.findViewById(R.id.mapView);
        locName = (TextView) rootView.findViewById(R.id.tv_location_name);
        mapIndicator = (TextView) rootView.findViewById(R.id.tv_map_indicator);
        locName.setText(locationName);
        mapIndicator.setText(Html.fromHtml("সব " + mapIndicatorText + " এর স্থান ম্যাপ এ দেখানো হয়েছে"));
        mMapView.onCreate(savedInstanceState);
        mMapView.onResume();

        try {
            MapsInitializer.initialize(getActivity().getApplicationContext());
        } catch (Exception e) {
            e.printStackTrace();
        }

        googleMap = mMapView.getMap();
        googleMap.setOnInfoWindowClickListener(this);

        return rootView;
    }
    @Override
    public void onInfoWindowClick(Marker marker) {
        LatLng loc = marker.getPosition();

    }


    private class ParserTask extends AsyncTask<String, Integer, List<List<HashMap<String,String>>> >{

        // Parsing the data in non-ui thread
        @Override
        protected List<List<HashMap<String, String>>> doInBackground(String... jsonData) {

            JSONObject jObject;
            List<List<HashMap<String, String>>> routes = null;

            try{
                jObject = new JSONObject(jsonData[0]);
                RouteActivity parser = new RouteActivity();

                // Starts parsing data
                routes = parser.parse(jObject);
            }catch(Exception e){
                e.printStackTrace();
            }
            return routes;
        }

        // Executes in UI thread, after the parsing process
        @Override
        protected void onPostExecute(List<List<HashMap<String, String>>> result) {

            ArrayList<LatLng> points = null;
            PolylineOptions lineOptions = null;

            // Traversing through all the routes
            for(int i=0;i<result.size();i++){
                points = new ArrayList<LatLng>();
                lineOptions = new PolylineOptions();

                // Fetching i-th route
                List<HashMap<String, String>> path = result.get(i);

                // Fetching all the points in i-th route
                for(int j=0;j<path.size();j++){
                    HashMap<String,String> point = path.get(j);

                    double lat = Double.parseDouble(point.get("lat"));
                    double lng = Double.parseDouble(point.get("lng"));
                    LatLng position = new LatLng(lat, lng);

                    points.add(position);
                }

                // Adding all the points in the route to LineOptions
                lineOptions.addAll(points);
                lineOptions.width(2);
                lineOptions.color(Color.RED);
            }
            //setUpMapIfNeeded();
            // Drawing polyline in the Google Map for the i-th route
            ***googleMap.addPolyline(lineOptions);***

        }
    }



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

}

Upvotes: 1

Views: 106

Answers (2)

Octavian Ionel
Octavian Ionel

Reputation: 423

I didn't use AsyncTask. Instead I used a handler and a thread.

You can remove the part of the AsyncTask and try my code.

    Handler mainHandler = new Handler(Looper.getMainLooper());

    Runnable myRunnable = new Runnable() {
        @Override
        public void run() {
            mapView.getMapAsync(new OnMapReadyCallback() {
                @Override
                public void onMapReady(GoogleMap googleMap) {
                    googleMap.addMarker(marker1);
                    googleMap.addMarker(marker2);
                    googleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(latLng1, zoom));
                    googleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(latLng2, zoom));
                    polylineOptions.addAll(points);
                    polylineOptions.width(10);
                    polylineOptions.color(Color.BLUE);
                    googleMap.addPolyline(polylineOptions);

                    //disable the rotation, scroll of the map
                    googleMap.getUiSettings().setAllGesturesEnabled(false);

                }
            });
        }
    };

    mainHandler.post(myRunnable);

Upvotes: 1

RogueBaneling
RogueBaneling

Reputation: 4471

You said in the comments that you are running the ParserTask as follows:

MapFragment mapFragment = new MapFragment();
mapFragment.parserTask(result);

The issue with this is that the MapView is initialized when the MapFragment's onCreateView is run, which is called when the Fragment comes into view. So the MapView hasn't been initialized when you try to run the ParserTask. Your options here are to reogranize your class structure (probably the better solution but also more work), or you could try this:

First make a class-level PolylineOptions polylineOptions; variable. Within your onPostExecute(), replace googleMap.addPolyline(lineOptions); with

if (googleMap != null) {
    googleMap.addPolyline(lineOptions);
} else {
    polylineOptions = lineOptions;
}

and in your onCreateView, you could write:

if (polylineOptions != null) {
    googleMap.addPolyline(polylineOptions);
}

The idea is that if the async task completes before the view is rendered, you save the data for when the view renders, and if the view renders before the async task completes, you immediately apply the effect.

Upvotes: 1

Related Questions