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


    最近遇到一个比较棘手的问题:使用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);
               }
          }
    }
     
     
    对于定位方式:有些同行,更倾向于使用getBestProvider方法,但是我认为这种方式有他的弊端,不是所有的手机都支持  “使用getBestProvider获取最适合的Location” ,最好就是使用网络定位和GPS定位....
     
     
    注: MapUtils是我自己写的一个工具类
     
    源代码地址:http://url.cn/PU7vxq
  • 相关阅读:
    如何修改容器内的/etc/resolv.conf
    OpenShift DNS的机制
    OpenShift 容器日志和应用日志分离问题
    python办公自动化(一)PPTX
    python装饰器 语法糖
    一步一步FLASK(一)
    linux python 安装 pymssql
    定制flask-admin的主页
    复制pycharm虚拟环境
    离线安装pycharm数据库驱动
  • 原文地址:https://www.cnblogs.com/simadi/p/6782581.html
Copyright © 2020-2023  润新知