9

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?

Vertexwahn
  • 7,709
  • 6
  • 64
  • 90
Yohanim
  • 3,319
  • 9
  • 52
  • 92
  • 1
    Extends `ActionBarFragmentActivity` instead of `ActionBarActivity` and also change this `mGoogleMap = ((SupportMapFragment)getSupportFragmentManager.findFragmentById(R.id.map)).getMap();` – M D Mar 24 '14 at 12:47

3 Answers3

3

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

Community
  • 1
  • 1
Raghunandan
  • 132,755
  • 26
  • 225
  • 256
  • Hi, thanks for reply. I've tried to change to `mGoogleMap = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map)).getMap();` but still returning null pointer exception. Any idea? – Yohanim Mar 24 '14 at 12:56
  • @CodingHorror do check the link i posted. – Raghunandan Mar 24 '14 at 12:56
  • @CodingHorror that does not solve NPE. But you should use MapView as suggested in the link. – Raghunandan Mar 24 '14 at 12:58
  • Ok, let me try. I will go back to you after a few minutes. – Yohanim Mar 24 '14 at 13:02
  • I just updated my question, I got three errors. (Better than before, many thanks for your link). Please check it. Error happened again in function setUpMapIfNeeded(), so what I should do in function setUpMapIfNeeded(), I really need this function because its called many time from others – Yohanim Mar 24 '14 at 13:50
  • in Java File, and main_fragment.xml, I've written `Updated` in my post. Please check. – Yohanim Mar 24 '14 at 13:54
  • @CodingHorror you need to move this `setUpMapIfNeeded();` to `onCreateView`. Also you only need to check the availability of google play services. – Raghunandan Mar 24 '14 at 13:57
  • I've tried your suggestion, but still got same errors. Feeling hopeless, maybe something that I missed or I didn't get you. :( – Yohanim Mar 24 '14 at 14:21
  • @CodingHorror what is line 104 in `MainActivity.java`? – Raghunandan Mar 24 '14 at 14:25
  • @CodingHorror looks like map object is null. you already have `this.mGoogleMap = mMapView.getMap();` So why is `setUpMapIfNeeded()` needed in the first place? – Raghunandan Mar 24 '14 at 14:28
  • in line 104 `mGoogleMap = mMapView.getMap();` on function setUpMapIfNeeded() and line 98, calling function setUpMapIfNeeded :), I just followed from sample code that given from Google Play Service. (https://developers.google.com/maps/documentation/android/intro#sample_code) – Yohanim Mar 24 '14 at 14:31
  • @CodingHorror remove that function that is no need coz you initialize map object `mGoogleMap` only after checkign the availability of google play services. – Raghunandan Mar 24 '14 at 14:32
  • actually, If I remove that function, Map showing blank map and I didn't get any errors. what I've missed? – Yohanim Mar 24 '14 at 14:47
  • @CodingHorror where did you test it `setUpMapIfNeeded()` deos nothign except initializg map object which is laready done in onCreateView – Raghunandan Mar 24 '14 at 15:37
  • well, after a long time, finally its worked. Thanks for your help. I'm really appreciate it. I'm forgot to call mapView on function onResume(), onDestroy() and onLowMemory(). Many thanks. – Yohanim Mar 24 '14 at 16:38
1

Change this

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

To

mGoogleMap = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map)).getMap();
M D
  • 47,665
  • 9
  • 93
  • 114
1

The problem because in your xml file you have used

android:name="com.google.android.gms.maps.SupportMapFragment"

and in your java class file you have used

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

so you got error. So the answer is change from

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

to

mGoogleMap = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map)).getMap();
Piyush
  • 18,895
  • 5
  • 32
  • 63