GoogleMap对象的NullPointerException

时间:2014-02-05 06:00:03

标签: android google-maps android-maps android-maps-v2

我的应用程序中不断获得NullPointerException行中定义的GoogleMap对象:

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

我在我的xml文件中定义了map,如下所示:

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

我还拥有AndroidManifest.xml中的所有相应权限以及API。

以下是我的完整源代码:

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;
    }
}

我不确定导致异常的原因。我初始化mMap错了吗?

这里有完整的logcat:

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

4 个答案:

答案 0 :(得分:3)

在我的情况下,谷歌地图对象调用像这些&amp;这样的片段。完美无缺:

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

答案 1 :(得分:2)

你应该替换这个

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

使用

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

试试这个。

答案 2 :(得分:0)

根据Documentation

  

注意:Google Maps Android API需要API等级12或更高版本才能支持 MapFragment 对象。如果您的目标是 API级别12 之前的应用程序,则可以通过 SupportMapFragment 类访问相同的功能。您还必须包含 Android支持库

除了使用MapFragment之外,您还需要使用SupportMapFragment,因为您正在开发API级别11以下的Google地图。

写如下:

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

相反

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

答案 3 :(得分:0)

尝试以下方法,

替换

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

FragmentManager myFM = getActivity().getSupportFragmentManager();
final SupportMapFragment myMAPF = (SupportMapFragment) myFM
                .findFragmentById(R.id.map);