最近遇到一个比较棘手的问题:使用GPS定位无法获取当前的地理位置,即getLastKnownLocation方法始终返回null。

 

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

 

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

 

第二:LocationListener 最好在Activity的onCreate()方法中进行实例化

      实现系统的回调方法:

        onLocationChanged(final Location loc)

        onProviderDisabled(final String s)

        onProviderEnabled(final String s)

        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, "Your current 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 { 
  
 
  

                     // 判断Use GPS satellites.是否勾选 
  
 
  

                     boolean isGpsEnabled = MapUtils.isGPSProviderAvaliable(this); 
  
 
  

                     // 判断Use wireless networks 是否勾选 
  
 
  

                     boolean isWIFIEnabled = MapUtils.isWIFIProviderAvaliable(this); 
  
 
  

                     if (!isGpsEnabled && !isWIFIEnabled) { 
  
 
  

                           如果都没有勾选,则弹出对话框,提示用户勾选。 
  
 
  

                    } 
  
 
  

                    else { 
  
 
  

                          Location lastKnownLocation = null; 
  
 
  

                          // 如果只是Use GPS satellites勾选,即指允许使用GPS定位 
  
 
  

                           if (isGpsEnabled && !isWIFIEnabled) {                     lastKnownLocation=mLocationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER); 
  
 
  

                          mProviderName = LocationManager.GPS_PROVIDER; 
  
 
  

      
  
 
  

                          // 如果只是Use wireless networks勾选,即只允许使用网络定位。 
  
 
  

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

                } 
   
 
   

           } 
   
 
  

    }

 

,最好就是使用网络定位和GPS定位....

 

 

注: MapUtils是我自己写的一个工具类

 

源代码 地址: http://url.cn/PU7vxq