最近遇到一个比较棘手的问题:使用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

Android 成功 使用GPS获取当前地理位置(解决getLastKnownLocation 返回 null)的更多相关文章

  1. 自动化测试用例getText()获取某一个元素的值返回null或空

    问题描述 页面上一个元素无法获取它的值. 用getText() 获取该元素的值返回null或空. 根本原因 ? 需要更多了解dom结构 解决办法 用getAttribute("value&q ...

  2. Android开发之旅-获取地理位置的经度和纬度

    在Android应用程序中,可以使用LocationManager来获取移动设备所在的地理位置信息.看如下实例:新建android应用程序TestLocation. 1.activity_main.x ...

  3. android通过BitmapFactory.decodeFile获取图片bitmap报内存溢出的解决办法

    android通过BitmapFactory.decodeFile获取图片bitmap报内存溢出的解决办法 原方法: public static Bitmap getSmallBitmap(Strin ...

  4. Android GPS获取当前经纬度坐标

    APP中可能会遇到一种需求,就是将当前所在位置的坐标传到server上,今天我提供三种途径去获取经纬度坐标信息,第一种是通过Android API来实现,另外一种通过百度地图API来实现,第三种通过天 ...

  5. android SDK manager 无法获取更新版本的解决办法

    http://mirrors.neusoft.edu.cn/eclipse/releases/luna/打开这个网址就可以看到adt的详细信息:  http://developer.android.c ...

  6. Android中通过GPS或NetWork获取当前位置的经纬度

    今天在Android项目中要实现一个通过GPS或NetWork来获取当前移动终端设备的经纬度功能.要实现该功能要用到Android Framework 中的 LocationManager 类.下面我 ...

  7. [转] Android SDK manager 无法获取更新版本列表

      打开这个网址(LINK)就可以看到adt的详细信息. 或者直接在你的eclipse的Help > Install New Software里面add,地址直接输入 https://dl-ss ...

  8. Android如何实现定位获取

    一:GPS定位: (1).要实用Adnroid平台的GPS设备,首先需要添加上权限,所以需要添加如下权限: uses-permission android:name= android.permissi ...

  9. Xamarin.Android 使用百度地图获取定位信息

    最近做一个项目,web端使用百度地图,PDA使用手持机自带的GPS定位系统获取经纬度,然后再百度地图上显示该经纬度会有一定距离的差异,这里就像可乐的瓶子拧上雪碧的盖子,能拧的上却不美观.所以为了数据的 ...

随机推荐

  1. TCP/IP各层协议数据格式

    ISO规范里定义了7层网络模型,实际常用的仍为TCPIP四层网络模型. 注:本文章插图均来自<图解TCP/IP>. 数据链路层帧格式 经常说的帧格式为以太网帧格式,由于类型和帧长度字段不重 ...

  2. maven项目编译:程序包com.sun.image.codec.jpeg不存在 这个类文件的位置在jre/lib/rt.jar

    转载:http://superich2008.iteye.com/blog/2047830 失败提示信息为:程序包com.sun.image.codec.jpeg不存在 这个类文件的位置在jre/li ...

  3. CI框架整合微信公共平台接口

    #CI框架控制器 <?php if ( ! defined('BASEPATH')) exit('No direct script access allowed'); /*** CI框架整合微信 ...

  4. 使用jmeter实现对jar包的调用

    一.前言 在我们测试接口的过程中,可能有时需要用到第三方jar包来生成一些测试数据(如有时需要对参数的输入值使用第三方jar包进行加密操作),涉及到这种的情况,普遍做法是:手动调用jar包获得需要的值 ...

  5. 第二百四十三节,Bootstrap模态框插件

    Bootstrap模态框插件 学习要点: 1.基本使用 2.用法说明 本节课我们主要学习一下 Bootstrap 中的模态框插件,这是一款交互式网站非常常见的 弹窗功能插件. 一.基本使用 使用模态框 ...

  6. Servlet Servlet是Java平台上的CGI技术

    Servlet Servlet是Java平台上的CGI技术.Servlet在服务器端运行,动态地生成Web页面.与传统的CGI和许多其它类似CGI的技术相比,Java Servlet具有更高的效率并更 ...

  7. ar0331

    aptina公司出品 分三个文档:ar0331_ds.pdf 数据表ar0331_dg.pdf 开发指导ar0331_rr_d.pdf 相关寄存器 色调映射(Tone Mapping):http:// ...

  8. java垃圾回收算法和垃圾收集器

    垃圾收集算法.垃圾回收算法.java垃圾收集器 目录1. 垃圾收集算法1)引用计数法2)根搜索法2. 垃圾回收算法1)复制算法2)标记-清除算法3)标记-整理算法4)分代收集算法3. java垃圾收集 ...

  9. hadoop入门学习整理

    技术性网站 1.http://dongxicheng.org/ 2.http://www.iteblog.com/ 3.http://www.cnblogs.com/shishanyuan/p/414 ...

  10. herf 和 src 的区别

    1.herf 表示超文本引用(hypertext reference),指向网络资源所在位置,建立和当前元素( 锚点)或当前文档(链接)之间的链接,如果我们在文档中添加 <link href=& ...