将自定义位置源设置为Google地图会抛出空指针

时间:2015-01-12 11:13:52

标签: java android location

我在谷歌播放中得到了非常奇怪的崩溃报告。测试时我没有任何错误,但我的用户有。将CustomLocationProvider设置为Google Map mMap.setLocationSource(customLocationProvider);时,会抛出NullPointerException。什么可能是错的?

FragmentMap.java:

 @Override
    public void onResume(){
        super.onResume();
        setUpMapIfNeeded();
   }

    @Override
    public void onPause(){
        super.onPause();
        customLocationProvider.deactivate();
    }

    @Override
    public void onDestroy(){
        super.onDestroy();
        customLocationProvider.deactivate();
    }


   /**
     * Set Up map if it was not already created.
     */
    private void setUpMapIfNeeded() {
        if (mMap == null) {
            mMap = ((SupportMapFragment) getChildFragmentManager()
                    .findFragmentById(R.id.map))
                    .getMap();
            if (mMap != null) {
                setUpMap();
            }
        }
        customLocationProvider = new CustomLocationProvider(getActivity());
        mMap.setLocationSource(customLocationProvider);
    }

    /**
     * Set Up map parameters.
     */
    private void setUpMap() {
        mMap.setOnMapClickListener(MapClick.freeModeClick);
        mMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);
        mMap.setOnMarkerClickListener(MapClick.markerClickListener);
        mMap.getUiSettings().setMyLocationButtonEnabled(true);
        mMap.getUiSettings().setZoomControlsEnabled(true);
        mMap.setMyLocationEnabled(true);
    }

CustomLocationProvider.java:

public class CustomLocationProvider implements LocationSource, LocationListener
{
    private OnLocationChangedListener listener;
    private LocationManager locationManager;

    public CustomLocationProvider(Context context){
        locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
    }

    @Override
    public void activate(OnLocationChangedListener listener){
        this.listener = listener;
        LocationProvider gpsProvider = locationManager.getProvider(LocationManager.GPS_PROVIDER);
        if(gpsProvider != null) {
            locationManager.requestLocationUpdates(gpsProvider.getName(), 500, 5, this);
        }

        LocationProvider networkProvider = locationManager.getProvider(LocationManager.NETWORK_PROVIDER);
        if(networkProvider != null) {
            locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 1000 * 60 * 3, 0, this);
        }
    }

    @Override
    public void deactivate(){
        locationManager.removeUpdates(this);
    }

    @Override
    public void onLocationChanged(Location location){
         /* Push location updates to the registered listener..
            (this ensures that my-location layer will set the blue dot at the new/received location) */
        if(listener != null && location != null){
            listener.onLocationChanged(location);

        }
    }

    @Override
    public void onProviderDisabled(String provider)
    {

    }

    @Override
    public void onProviderEnabled(String provider)
    {
    }

    @Override
    public void onStatusChanged(String provider, int status, Bundle extras)
    {
        // TODO Auto-generated method stub

    }


}

崩溃报告:

 ComponentInfo{lt.noframe.fieldsareameasure/lt.noframe.fieldsareameasure.views.ActivityDrawer}: java.lang.NullPointerException
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2382)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2434)
at android.app.ActivityThread.access$600(ActivityThread.java:162)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1364)
at android.os.Handler.dispatchMessage(Handler.java:107)
at android.os.Looper.loop(Looper.java:194)
at android.app.ActivityThread.main(ActivityThread.java:5431)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:525)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:833)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:600)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.NullPointerException
at app.views.FragmentMap.setUpMapIfNeeded(FragmentMap.java:209)
at app.views.FragmentMap.onCreateView(FragmentMap.java:97)
at android.support.v4.app.Fragment.performCreateView(Fragment.java:1786)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:947)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1126)
at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:739)
at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1489)
at android.support.v4.app.FragmentActivity.onStart(FragmentActivity.java:548)
at lt.noframe.fieldsareameasure.views.ActivityDrawer.onStart(ActivityDrawer.java:68)
at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1170)
at android.app.Activity.performStart(Activity.java:5132)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2355)

1 个答案:

答案 0 :(得分:1)

setUpMapIfNeeded()的简单回顾表明,拥有NPE肯定不是不可能的。请参阅我在方法中添加的评论:

private void setUpMapIfNeeded() {
    if (mMap == null) {
        //here if mMap is null, you are trying to get a reference to it
        mMap = ((SupportMapFragment) getChildFragmentManager()
                .findFragmentById(R.id.map))
                .getMap();
        //you are checking if the reference that was returned is null
        //this means (at least to me) that you are suspecting
        //mMap could be null at this point
        if (mMap != null) {
            setUpMap();
        }
    }
    customLocationProvider = new CustomLocationProvider(getActivity());
    //if getMap() returned null, here you will have NPE
    mMap.setLocationSource(customLocationProvider);
}

检查文档here,结果证明此方法可以返回null,甚至已弃用。 解决方案应如文档所述:
“改为使用getMapAsync(OnMapReadyCallback)。回调方法为您提供了一个保证非空并且可以使用的GoogleMap实例。”