Android 成功 使用GPS获取当前地理位置(解决getLastKnownLocation 返回 null)

    自本篇博客发布以来,收到了很多同行的邮件,大部分都是给我要MapUtils.java文件,或者要关于定位的Demo。以后也省的大家麻烦了,我直接把Demo挂到我的QQ云盘上去,大家可以去那里下载。(注意该Demo无法直接运行,因为我是从项目中抽出来的,但我能保证,该Demo包含了我所有的定位代码,自己调试吧,你懂的)...
  QQ云盘地址:http://url.cn/PU7vxq


这两天可憋坏我了,一直愁没什么题材可以充实我的博客,正巧最近遇到一个比较棘手的问题:
使用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 void onLocationChanged(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 wireless networks取消勾选,Use GPS  satellites取消勾选时调用。
        public void onProviderDisabled(final String s){
                  LogHelper.i(TAG, "onProviderDisabled. ");
        }
                         
        // 当系统Setting -> Location & Security-> Use wireless networks勾选,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定位 ....


注: MapUtils是我自己写的一个工具类
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值