zoukankan      html  css  js  c++  java
  • MAP getLastKnownLocation()返回null的解决

    原文:http://blog.sina.com.cn/s/blog_74c22b210100sfix.html
    这两天可憋坏我了,一直愁没什么题材可以充实我的博客,正巧最近遇到一个比较棘手的问题:
    使用GPS定位无法获取当前的地理位置,即getLastKnownLocation方法始终返回null。

    后来一篇博文 getLastKnownLocation()返回null的解决 帮了我大忙,在此对该博客作者表示感谢,但是有几点需要注意的,我觉得有必要补充一下,否则看了这篇博文也还是得不到当前的地理位置。

    第一:当使用GPS定位时,最好不要使用getLastKnownLocation方法获得当前位置对象Location,因为该对象可以在onLocationChanged的参数中由系统给予(根据文档,getLastKnownLocation有2方面功能:1. 获取当前地理位置2.如果当前位置定位不成功,则可以用此方法获取缓存中的上一次打开地图时定位的地理位置)。这样就避免了空指针异常。而且更重要的是GPS定位不是一下子就能定位成功的,在90%以上的情况下,getLastKnownLocation返回null

    第二:LocationListener最好在Activity的onCreate()方法中进行实例化
    实现系统的回调方法:
    onLocationChanged(finalLocation loc)
    onProviderDisabled(final Strings)
    onProviderEnabled(final Strings)
    onStatusChanged(final String s,final int i, final Bundle b)

    第三:requestLocationUpdates必须要在onResume()中进行注册监听. 且在onPause()中进行反注 册。

    第四:测试GPS是否定位成功,去一个空旷的地方去,不要有遮挡。这点非常重要,不然,你永远也不知道自己GPS定位是否成功。

    以下是我用GPS成功获取当前地理位置的例子。希望能够帮助大家摆脱GPS定位的阴霾。

    @Override
    public void onCreate(final Bundle icicle) {
    super.onCreate(icicle);
    this.setContentView(R.layout.activity_mapview);

     mBtnDone =(Button) findViewById(R.id.btn_done);
     mBtnDone.setOnClickListener(this);
    
     mapView = (MapView) findViewById(R.id.map_view);
     mapView.setBuiltInZoomControls(true);
     mapController = mapView.getController();
     mLocationManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
    
    mDefaultMarker =getResources().getDrawable(R.drawable.map_redpin);
    mDefaultMarker.setBounds(0, 0,mDefaultMarker.getIntrinsicWidth(),
    mDefaultMarker.getIntrinsicHeight());
    
     mBuoyOverlay = new BuoyItemizedOverlay(mDefaultMarker, this);
     initDensityDpi();
     mZoomLevel = mapView.getMaxZoomLevel() - 1;
    

    // LocationListener最好在Activity的onCreate()方法中进行实例化,当GPS获得Location时,会自 动调用onLocationChanged方法.

     mLocationListener = new LocationListener() {
         @Override
         public voidonLocationChanged(final Location loc) {
         LogHelper.i(TAG,"onLocationChanged. loc: " + loc);
         if (loc != null) {
                LogHelper.i(TAG, "onLocationChanged. latitude:"
                        + loc.getLatitude() + " ,longtitude: ".getLongitude());
                GeoPoint geoPoint =MapUtils.getGeoPoint(loc);
                mapController.animateTo(geoPoint);
                initBuoyOverlayItems(loc);
        } else {
           Toast( MapViewActivity.this, "Yourcurrent location is temporarily unavailable.",
              Toast.LENGTH_SHORT).show();
        }
     }
    
      // 当系统Setting -> Location& Security -> Use wirelessnetworks取消勾选,Use GPS                 satellites取消勾选时调用
      public void onProviderDisabled(final String s){
              LogHelper.i(TAG, "onProviderDisabled. ");
      }
    
       // 当系统Setting -> Location& Security -> Use wirelessnetworks勾选,Use GPS satellites勾         选时调用
       public void onProviderEnabled(final String s){
            LogHelper.i(TAG, "onProviderEnabled. ");
       }
    
       public void onStatusChanged(final String s,final int i, final Bundle b) {
            LogHelper.i(TAG, "onStatusChanged. ");
       }
      };
    }
    
      @Override
      public void onStart() {
         super.onStart();
    
          mapController.setZoom(mZoomLevel);
           if(!DoSomeGoodUtils.isNetworkAvailable(this)) {
              mBtnDone.setEnabled(false);
              showDialog(DIALOG_NO_NETWORK);
          } else{
               // 判断UseGPS satellites.是否勾选
               booleanisGpsEnabled = MapUtils.isGPSProviderAvaliable(this);
               // 判断Usewireless networks 是否勾选
               booleanisWIFIEnabled = MapUtils.isWIFIProviderAvaliable(this);
               if(!isGpsEnabled && !isWIFIEnabled){
                   如果都没有勾选,则弹出对话框,提示用户勾选。
              }
              else {
                   Location lastKnownLocation =null;
                   // 如果只是Use GPSsatellites勾选,即指允许使用GPS定位
                    if(isGpsEnabled && !isWIFIEnabled){                 lastKnownLocation=mLocationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
                   mProviderName =LocationManager.GPS_PROVIDER;
    
                   // 如果只是Use wirelessnetworks勾选,即只允许使用网络定位。
                  } else if(!isGpsEnabled&& isWIFIEnabled){
                   lastKnownLocation =   mLocationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
                   mProviderName =LocationManager.NETWORK_PROVIDER;
    
                    //如果二者都勾选,优先使用GPS,因为GPS定位更精确。
                 } else if (isGpsEnabled&& isWIFIEnabled){           lastKnownLocation=mLocationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
                mProviderName =LocationManager.GPS_PROVIDER;
                if (lastKnownLocation == null) {
          lastKnownLocation=mLocationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
             mProviderName =LocationManager.NETWORK_PROVIDER;
                }
       }
         if(!TextUtils.isEmpty(mProviderName)) {
             mLocationManager.requestLocationUpdates(
                  mProviderName, 1000, 1,mLocationListener);
           }
    
         //如果一下子就能定位成功,则执行以下代码,当用网络定位时,大都能一次性定位成功,当用GPS时,该代码不会起太大作用。
        if (lastKnownLocation != null){
            mBtnDone.setEnabled(true);
            // 获取当前地理位置
           GeoPoint lastKnownPoint =getLastKnownPoint(lastKnownLocation);
            // 以动画方式移动到该地理位置
            mapController.animateTo(lastKnownPoint);
            // 更新浮标。该方法在这里就不公开了。知道它的含义就行
            initBuoyOverlayItems(lastKnownLocation);
        }
      }
     }
    }
    
    @Override
     protected void onResume() {
          super.onResume();
          LogHelper.i(TAG, "onResume. Provider Name: " +mProviderName);
         if(!TextUtils.isEmpty(mProviderName)) {
          //当GPS定位时,在这里注册requestLocationUpdates监听就非常重要而且必要。
    

    没有这句话,定位不能成功。
    mLocationManager.requestLocationUpdates(mProviderName,1000, 1,
    mLocationListener);
    }
    }

        @Override
        protected void onPause(){
         super.onPause();
          //取消注册监听
          if(mLocationManager != null) {
            mLocationManager.removeUpdates(mLocationListener);
          }
     }
    

    }

    对于定位方式:有些同行,更倾向于使用getBestProvider方法,但是我认为这种方式有他的弊端,不是所有的手机都支持 “使用getBestProvider获取最适合的Location” ,最好就是使用网络定位和GPS定位….

  • 相关阅读:
    结对第一次—原型设计(文献摘要热词统计)
    第一次作业-准备篇
    201771010135杨蓉庆《面向对象程序设计(java)》第二周学习总结
    杨蓉庆201771010135《面向对象程序设计(java)》第一周学习总结
    2019 SDN阅读作业
    第01组 Alpha冲刺 (2/4)
    2019 SDN上机第3次作业
    第01组 ALPHA冲刺(1/4)
    2019SDN上机第二次作业
    2019 SDN上机第1次作业
  • 原文地址:https://www.cnblogs.com/Wu-Shi/p/5410058.html
Copyright © 2011-2022 走看看