java - 将自定义位置源设置为 Google map 会引发空指针

标签 java android location

我在 Google Play 中收到非常奇怪的崩溃报告。我在测试时没有任何错误,但我的用户有。将 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)

最佳答案

简单回顾一下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)。回调方法为您提供一个保证为非 null 且可供使用的 GoogleMap 实例。”

关于java - 将自定义位置源设置为 Google map 会引发空指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27900694/

相关文章:

c# - 在 C# ASP.NET 中,Java 中的同步块(synchronized block)等效于什么?

java - 为什么 Google fit API 不断返回空数据集?

Java Jetty WebSocket 服务器 : Handle broadcasts with asynchronously disconnecting clients

android - 从Spanned接口(interface)解释这些标志(SPAN_COMPOSING、SPAN_USER等)的定义

禁用设备位置时 navigator.getCurrentPosition 的 javascript 问题 - 无回调

java - 在 googleMap (android) 中更新位置

java - Java 支持多少种 DBMS,哪一种最适合存储 XML?

javascript - Phonegap 应用程序文本出现后立即消失。我该如何调试?

android - 缩小 Webview 内容宽度以适合屏幕

android - Activity 暂停时启动服务