Android – getFragmentManager returning null pointer exception

androidgoogle mapsgoogle-maps-android-api-2

My getFragmentManager in the function setUpMapIfNeeded() returning null pointer exception. I put my fragment separately from activity_main.xml, here my code :

activity_main.xml :

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.yai.testmap.MainActivity"
tools:ignore="MergeRootFrame" /> 

Updated

fragment_main.xml :

<?xml version="1.0" encoding="utf-8" ?>

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
 android:layout_width="match_parent"
 android:layout_height="match_parent">

<!--  MapView-->

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

and here my *.java file :

Updated

package com.yai.testmap;

import android.support.v7.app.ActionBarActivity;
import android.support.v4.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;

/* FOR ERROR REPPORT */
import android.util.Log;

/* IMPORT FOR DROPDOWNLIST USED THIS PROJECT */
import android.widget.CheckBox;
import android.widget.Spinner;
import android.widget.Toast;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.AdapterView.OnItemSelectedListener;

import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesNotAvailableException;
import com.google.android.gms.common.GooglePlayServicesUtil;
/* IMPORT FOR GOOGLE MAP */
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.MapFragment;
import com.google.android.gms.maps.MapsInitializer;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.MapView;

/* FOR GOOGLE MAP TYPE */
import static com.google.android.gms.maps.GoogleMap.MAP_TYPE_HYBRID;
import static com.google.android.gms.maps.GoogleMap.MAP_TYPE_NONE;
import static com.google.android.gms.maps.GoogleMap.MAP_TYPE_NORMAL;
import static com.google.android.gms.maps.GoogleMap.MAP_TYPE_SATELLITE;
import static com.google.android.gms.maps.GoogleMap.MAP_TYPE_TERRAIN;

public class MainActivity extends ActionBarActivity implements OnItemSelectedListener {
    private static MapView mMapView;
    private static MapFragment mMapFragment;
    private static GoogleMap mGoogleMap;
    private static CheckBox mTrafficCheckbox, mLocationCheckbox, mBuildingCheckbox, mIndoorCheckbox;

    public static class PlaceholderFragment extends Fragment {

        public PlaceholderFragment() {
        }

        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                Bundle savedInstanceState) {
            View rootView = inflater.inflate(R.layout.fragment_main, container,
                    false);

            Spinner spinner = (Spinner) rootView.findViewById(R.id.spinnerOption);
            ArrayAdapter adapter = ArrayAdapter.createFromResource(getActivity(), R.array.spinner_option_string, android.R.layout.simple_spinner_item);
            adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
            spinner.setAdapter(adapter);
            spinner.setOnItemSelectedListener((OnItemSelectedListener) getActivity());

            mTrafficCheckbox = (CheckBox) rootView.findViewById(R.id.checkbox_traffic);
            mLocationCheckbox = (CheckBox) rootView.findViewById(R.id.checkbox_location);
            mBuildingCheckbox = (CheckBox) rootView.findViewById(R.id.checkbox_building);
            mIndoorCheckbox = (CheckBox) rootView.findViewById(R.id.checkbox_indoor);


            MapsInitializer.initialize(getActivity());

            switch (GooglePlayServicesUtil.isGooglePlayServicesAvailable(getActivity()) )
            {
            case ConnectionResult.SUCCESS :
                mMapView = (MapView) rootView.findViewById(R.id.map);   
                mMapView.onCreate(savedInstanceState);

                if(mMapView != null){
                    mGoogleMap = mMapView.getMap();
                    mGoogleMap.getUiSettings().setMyLocationButtonEnabled(false);
                    mGoogleMap.setMyLocationEnabled(true);
                }
            }   

            return rootView;
        }
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {    
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        if (savedInstanceState == null) {
            getSupportFragmentManager().beginTransaction()
                    .add(R.id.container, new PlaceholderFragment()).commit();
        }       

        setUpMapIfNeeded();         
    }   

    private void setUpMapIfNeeded(){
        if(mGoogleMap == null){     
            //mMapFragment = (MapFragment) getFragmentManager().findFragmentById(R.id.map);
            mGoogleMap = mMapView.getMap();
        }
    }

    private boolean checkReady(){
        if(mGoogleMap == null){
            Toast.makeText(this, R.string.map_not_ready, Toast.LENGTH_SHORT).show();
            return false;
        }
        return true;
    }

    private void updateTraffic(){
        if(!checkReady()){
            return;
        }
        mGoogleMap.setTrafficEnabled(mTrafficCheckbox.isChecked());
    }

    public void onTrafficToggled(View view){
        updateTraffic();
    }

    private void updateLocation(){
        if(!checkReady()){
            return;
        }
        mGoogleMap.setMyLocationEnabled(mLocationCheckbox.isChecked());
    }

    public void onLocationToggled(View view){
        updateLocation();
    }

    private void updateBuilding(){
        if(!checkReady()){
            return;
        }
        mGoogleMap.setBuildingsEnabled(mBuildingCheckbox.isChecked());
    }

    public void onBuildingToggled(View view){
        updateBuilding();
    }

    private void updateIndoor(){
        if(!checkReady()){
            return;
        }
        mGoogleMap.setIndoorEnabled(mIndoorCheckbox.isChecked());
    }

    public void onIndoorToggled(View view){
        updateIndoor();
    }

    @Override
    public void onItemSelected(AdapterView parent, View view, int position, long id){
         setLayer((String) parent.getItemAtPosition(position));
    }

    private void setLayer(String layerName){
        if(!checkReady()){
            return;
        }

        if(layerName.equals(getString(R.string.normal))){
            mGoogleMap.setMapType(MAP_TYPE_NORMAL);
        }
        else if(layerName.equals(getString(R.string.hybrid))){
            mGoogleMap.setMapType(MAP_TYPE_HYBRID);
        }
        else if(layerName.equals(getString(R.string.satellite))){
            mGoogleMap.setMapType(MAP_TYPE_SATELLITE);
        }
        else if(layerName.equals(getString(R.string.terrain))){
            mGoogleMap.setMapType(MAP_TYPE_TERRAIN);
        }
        else if(layerName.equals(getString(R.string.none_map))){
            mGoogleMap.setMapType(MAP_TYPE_NONE);
        }
        else{
            Log.i("LDA", "Error setting layer with name " + layerName);
        }
    }

    @Override
    public void onNothingSelected(AdapterView parent){

    }

    @Override
    protected void onResume() {
        super.onResume();
        setUpMapIfNeeded();
        if (mGoogleMap != null) {
            updateTraffic();
            updateLocation();
            updateBuilding();
            updateIndoor();
        }
    }   

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {

        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();
        if (id == R.id.action_settings) {
            return true;
        }
        return super.onOptionsItemSelected(item);
    }
}

I've tried to use getSupportFramentManager with android.support.v4.app.DialogFragment support library :

mGoogleMap = ((MapFragment) getSupportFragmentManager().findFragmentById(R.id.map)).getMap();

but still doesn't works. I got this error from eclipse Cannot cast from Fragment to MapFragment.
I've tried to extend to FragmentActivity and still returning null pointer. But when I'm tried to comment getSupportFragmentManager in function setUpMapIfNeeded(), the error was gone.

Here is my LogCat :

Updated

03-24 20:43:36.124: E/AndroidRuntime(27152): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.yai.testmap/com.yai.testmap.MainActivity}: java.lang.NullPointerException
03-24 20:43:36.124: E/AndroidRuntime(27152):    at com.yai.testmap.MainActivity.setUpMapIfNeeded(MainActivity.java:104)
03-24 20:43:36.124: E/AndroidRuntime(27152):    at com.yai.testmap.MainActivity.onCreate(MainActivity.java:98)

Any idea?

Best Answer

The casting problem can be solved by

mGoogleMap = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map)).getMap();

If you want map inside a fragment you need to use MapView or you need to extend SupportMapFragment.

You can refer the below

Android - android.view.InflateException: Binary XML file line #8: Error inflating class fragment

Related Topic