문제

I keep getting a NullPointerException in my application for the GoogleMap object defined in the line:

mMap = ((MapFragment) getFragmentManager().findFragmentById(R.id.map)).getMap();

I have map defined in my xml file like so:

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

I also have all of the appropriate permissions as well as the API in my AndroidManifest.xml.

Here is my entire source code:

import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesClient;
import com.google.android.gms.common.GooglePlayServicesUtil;
import com.google.android.gms.location.LocationClient;
import com.google.android.gms.location.LocationListener;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.maps.CameraUpdate;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;
import com.google.android.gms.maps.MapFragment;
import android.location.Location;
import android.location.LocationManager;
import android.os.Bundle;
import android.provider.Settings;
import android.app.Activity;
import android.app.Dialog;
import android.content.Intent;
import android.support.v4.app.FragmentActivity;
import android.util.Log;
import android.widget.Toast;

public class PlaceMarker extends FragmentActivity 
    implements GooglePlayServicesClient.ConnectionCallbacks,
    GooglePlayServicesClient.OnConnectionFailedListener,
    LocationListener {
    private final static int CONNECTION_FAILURE_RESOLUTION_REQUEST = 9000;
    private LocationClient mLocationClient = null;
    private LocationRequest mLocationRequest = null;
    private GoogleMap mMap;
    private static final int UPDATE_INTERVAL_IN_SECONDS = 5;
    private static final int MILLISECONDS_PER_SECOND = 1000;
    private static final long UPDATE_INTERVAL = MILLISECONDS_PER_SECOND * UPDATE_INTERVAL_IN_SECONDS;
    private static final int FASTEST_INTERVAL_IN_SECONDS = 1;
    private static final long FASTEST_INTERVAL = MILLISECONDS_PER_SECOND * FASTEST_INTERVAL_IN_SECONDS;
    private LocationManager locationManager;
    private Location location = null;

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

//      mCurrentLocation = mLocationClient.getLastLocation();
//      Double myLatitude = mCurrentLocation.getLatitude();
//      Double myLongitude = mCurrentLocation.getLongitude();   

        mMap = ((MapFragment) getFragmentManager().findFragmentById(R.id.map)).getMap();
        mMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
        mMap.setMyLocationEnabled(true);
//      mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(myLatitude, myLongitude), 16));

        mLocationClient = new LocationClient(this, this, this);
        if (servicesConnected()) {
            mLocationRequest = LocationRequest.create();
            mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
            mLocationRequest.setInterval(UPDATE_INTERVAL);
            mLocationRequest.setFastestInterval(FASTEST_INTERVAL);
        }
        else {
            Toast.makeText(this, "Position unavailable", Toast.LENGTH_SHORT).show();
        }

//      Marker marker = mMap.addMarker(new MarkerOptions()
//          .position(new LatLng(myLatitude, myLongitude))
//          .title("San Francisco")
//          .snippet("Population: 776733"));        
    }

    @Override
    protected void onStart() {
        super.onStart();
        mLocationClient.connect();
    }

    @Override
    protected void onStop() {
        if (mLocationClient.isConnected()) {
            mLocationClient.removeLocationUpdates(this);
        }
        mLocationClient.disconnect();
        super.onStop();
    }

    private Location getCurrentLocation() {
        Location location = mLocationClient.getLastLocation();

        if (location != null) {
            return location;
        }
        else {
            Toast.makeText(this, "Current Location Unavailable", Toast.LENGTH_SHORT).show();
            checkforGPSAndPromptOpen();
            return null;
        }
    }

    private void checkforGPSAndPromptOpen() {
        boolean enabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);

        if (!enabled) {
            Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
            startActivity(intent);
        }
    }

    // Handle results returned to the FragmentActivity by Google Play services
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        // Decide what to do based on the original request code
        switch (requestCode) {
            case CONNECTION_FAILURE_RESOLUTION_REQUEST : 
            // If the result code is Activity.RESULT_OK, try to connect again
                switch (resultCode) {
                    case Activity.RESULT_OK :
                    // Try the request again
                    break;
                }
            }
     }

    private boolean servicesConnected() {
        // Check that Google Play services is available
        int resultCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);

        // If Google Play services is available
        if (ConnectionResult.SUCCESS == resultCode) {
            // In debug mode, log the status
            Log.d("Location Updates", "Google Play services is available.");
            // Continue
            return true;
        // Google Play services was not available for some reason
        } else {
            // Get the error code
            // Get the error dialog from Google Play services
            Dialog errorDialog = GooglePlayServicesUtil.getErrorDialog(resultCode, this, CONNECTION_FAILURE_RESOLUTION_REQUEST);

            // If Google Play services can provide an error dialog
            if (errorDialog != null) {
                errorDialog.show();
            }
            return false;
        }
    }

    /*
     * Called by Location Services when the request to connect the client finishes successfully.
     * At this point, you can request the current location or start periodic updates
     */
    @Override
    public void onConnected(Bundle dataBundle) {
        // Display the connection status
        Toast.makeText(this, "Connected", Toast.LENGTH_SHORT).show();
        mLocationClient.requestLocationUpdates(mLocationRequest, this);
        location = getCurrentLocation();
        takeToLocation(convertLocationtoLatLong(location));
    }

    /*
     * Called by Location Services if the connection to the location client drops because of an error.
     */
    @Override
    public void onDisconnected() {
        // Display the connection status
        Toast.makeText(this, "Disconnected. Please re-connect.", Toast.LENGTH_SHORT).show();
    }

    public void onLocationChanged(Location location) {
        // Report to the UI that the location was updated
        String msg = "Updated location: " + Double.toString(location.getLatitude()) + "," + Double.toString(location.getLongitude());
        Toast.makeText(this, msg, Toast.LENGTH_SHORT).show();
    }

    /*
     * Called by Location Services if the attempt to Location Services fails.
     */
    @Override
    public void onConnectionFailed(ConnectionResult connectionResult) {

    }

    private void takeToLocation(LatLng newLocation) {
        if (newLocation != null) {
            CameraUpdate update = CameraUpdateFactory.newLatLngZoom(newLocation, 16);
            mMap.animateCamera(update);
        }
        else {
            Toast.makeText(this, "Position unavailable", Toast.LENGTH_SHORT).show();
        }
    }
    private LatLng convertLocationtoLatLong(Location location) {
        LatLng currentLatLong = new LatLng(location.getLatitude(), location.getLongitude());
        return currentLatLong;
    }
}

I'm not sure what is causing the Exception. Am I initializing mMap wrong?

Full logcat here:

02-05 01:08:49.122: E/AndroidRuntime(14029): FATAL EXCEPTION: main
02-05 01:08:49.122: E/AndroidRuntime(14029): Process: com.example.MyApp, PID: 14029
02-05 01:08:49.122: E/AndroidRuntime(14029): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.p1/com.example.p1.PlaceMarker}: java.lang.NullPointerException
02-05 01:08:49.122: E/AndroidRuntime(14029):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2215)
02-05 01:08:49.122: E/AndroidRuntime(14029):    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2265)
02-05 01:08:49.122: E/AndroidRuntime(14029):    at android.app.ActivityThread.access$800(ActivityThread.java:145)
02-05 01:08:49.122: E/AndroidRuntime(14029):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1206)
02-05 01:08:49.122: E/AndroidRuntime(14029):    at android.os.Handler.dispatchMessage(Handler.java:102)
02-05 01:08:49.122: E/AndroidRuntime(14029):    at android.os.Looper.loop(Looper.java:136)
02-05 01:08:49.122: E/AndroidRuntime(14029):    at android.app.ActivityThread.main(ActivityThread.java:5081)
02-05 01:08:49.122: E/AndroidRuntime(14029):    at java.lang.reflect.Method.invokeNative(Native Method)
02-05 01:08:49.122: E/AndroidRuntime(14029):    at java.lang.reflect.Method.invoke(Method.java:515)
02-05 01:08:49.122: E/AndroidRuntime(14029):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:781)
02-05 01:08:49.122: E/AndroidRuntime(14029):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
02-05 01:08:49.122: E/AndroidRuntime(14029):    at de.robv.android.xposed.XposedBridge.main(XposedBridge.java:126)
02-05 01:08:49.122: E/AndroidRuntime(14029):    at dalvik.system.NativeStart.main(Native Method)
02-05 01:08:49.122: E/AndroidRuntime(14029): Caused by: java.lang.NullPointerException
02-05 01:08:49.122: E/AndroidRuntime(14029):    at com.example.MyApp.PlaceMarker.onCreate(PlaceMarker.java:52)
02-05 01:08:49.122: E/AndroidRuntime(14029):    at android.app.Activity.performCreate(Activity.java:5231)
02-05 01:08:49.122: E/AndroidRuntime(14029):    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
02-05 01:08:49.122: E/AndroidRuntime(14029):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2169)
02-05 01:08:49.122: E/AndroidRuntime(14029):    ... 12 more
도움이 되었습니까?

해결책 2

You should replace this

 mMap=((MapFragment)getFragmentManager().findFragmentById(R.id.map)).getMap();

With

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

Try this.

다른 팁

In my case google map object invoke inside fragment like these & works perfect:

private GoogleMap mGoogleMap = null;


int sdk = Build.VERSION.SDK_INT;
                if(sdk >= Build.VERSION_CODES.LOLLIPOP) {
                    mGoogleMap = ((MapFragment) getChildFragmentManager().findFragmentById(R.id.map)).getMap();
                }
                else {
                    mGoogleMap = ((MapFragment) getFragmentManager().findFragmentById(R.id.map)).getMap();
                }

As per Documentation

Note: The Google Maps Android API requires API level 12 or higher for the support of MapFragment objects. If you are targeting an application earlier than API level 12, you can access the same functionality through the SupportMapFragment class. You will also have to include the Android Support Library.

Besides using MapFragment you need to use SupportMapFragment as you are developing google map below the API level 11.

Write as below:

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

Instead

 mMap=((MapFragment)getFragmentManager().findFragmentById(R.id.map)).getMap();

Try the following,

Replace

mMap = ((MapFragment) getFragmentManager().findFragmentById(R.id.map)).getMap();

with

FragmentManager myFM = getActivity().getSupportFragmentManager();
final SupportMapFragment myMAPF = (SupportMapFragment) myFM
                .findFragmentById(R.id.map);
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top