android定时定位 - 利用百度定位API来实现定时定位功能

时下LBS 是最热门的话题,前段时间,公司有个 LBS 项目,要求用到地图导航和定位,就研究了下地图和定位。

android  类库中, 虽然已经提供了几种定位方式,但是从提供的功能和反应速度上,和其他的第三方定位库相比,还是相形见绌。

搜索了几个第三方定位和地图的API平台,综合考虑了下,选择了百度地图。(第三方地图API的选择,具体还要根据自己的项目要求来选择)

言归正传,现在就说说百度的定位API 吧 (该文章,主要是讲定位的,所以就单独说说,百度的定位API 接口)

 

   百度定位API,是 GPS+基站+WIFI+IP混合定位,传感器辅助定位 ,具有 定位方式多,反应时间快等特点(具体的可以搜索一下“百度地图定位API”),下面就讲讲如何实现定时的去定位从而获取实时的定位经纬度。

 

 实现要求:

   LBS应用中,缺少不了定位,但是有时,由于网络环境的不稳定等特殊情况,可能会造成定位失败的情况(获取不到定位信息或者访问延时后报错),那就需要有种补救的措施,来实时的获取一个用户当前的定位信息。该示例就是一个实时定位的助手类。

   在项目开启时,开启定时定位,每隔一段时间,将经纬度保存在本地,来供应用程序的相关方法调用。

 

 思路:

    1. 定时的发送定位请求,首先需要 定时器 Timer 和 TimerTask ,来定时地发送定位请求;

    2. 在定位的回调函数里,将定位获取的信息保存到本地

关键代码实现:

  1. 首先将百度定位的jar包放入工程中;

  2. 定义一个application类,将定位的代码写在里面,放在application中,可以更好的去管理一些全局的变量和操作,由于定时定位是贯穿于整个APP的,所以放在application中比较好。

 

 private LocationClient mLocationClient = null;  //定位类

 //是否启动了定位API
 private boolean isOpenLocation = false;

 

 @Override
 public void onCreate() {
  mLocationClient = new LocationClient(this);  //实例定位类
 }

 

/**
  * start定位
  */
 private void startLocation()
 {
  try {
   if(!isOpenLocation)  //如果没有打开
   {

    //该部分主要是对定位类的配置,并没有实质性的去获取定位信息
    mLocationClient.setCoorType("bd09ll"); //设置返回的坐标类型
    mLocationClient.setTimeSpan(myLocationTime);    //设置时间
    mLocationClient.setAddrType("street_number");   //返回地址类型
    mLocationClient.setServiceMode(LocServiceMode.Immediat); //定位方式为:即时定位
    mLocationClient.addRecerveListener(new MyReceiveListenner());
    mLocationClient.start();  //打开定位
    isOpenLocation = true;  //标识为已经打开了定位
   }
  } catch (Exception e) {
   Log.i(TAG, "打开定位异常"+e.toString());
  }
 }


 
 /**
  * end 定位
  */
 private void closeLocation()
 {
  try {
   mLocationClient.stop();  //结束定位
   isOpenLocation = false;  //标识为已经结束了定位
  } catch (Exception e) {
   Log.i(TAG, "结束定位异常"+e.toString());
  }
 }

 /***
  * 获取经纬度,
  */
 public void getLocationInfo()
 {
  /**
   * 0:正常。

       1:SDK还未启动。

       2:没有监听函数。

       6:请求间隔过短。
   */
  int i = mLocationClient.getLocation();
  String TAGfont = "getLocationInfo() : ";
  switch(i)
  {
   case 0:
    Log.i(TAG, TAGfont+"正常。");
    break;
   case 1:
    Log.i(TAG, TAGfont+"SDK还未启动。");
    break;
   case 2:    
    Log.i(TAG, TAGfont+"没有监听函数。 ");
    break;
   case 6:    
    Log.i(TAG, TAGfont+"请求间隔过短。 ");
    break;
   default:    
    Log.i(TAG, TAGfont+"其他原因 ");
  }
 }

 

//位置发生改变 --- 后台服务模式下有用

 private class MyLocationChangedListener implements LocationChangedListener {
  @Override
  public void onLocationChanged() {
   //logMsg("LocationChangedListener: ");
  }
 }

 //接受定位得到的消息  ---- 用于即时扫描服务
 private class MyReceiveListenner implements ReceiveListener {
  @Override
  public void onReceive(String strData) {
   logMsg(strData);    //调用回调函数
  }
 }
 

//*关于即时扫描和后台服务模式,下面会做介绍。

 

//获取到定位信息后的回调操作

 private void logMsg(String str) {
  try {
   mData = str.trim();
     
   Log.i(TAG, "进入了定位 定时器 更新了经纬度方法  -- 信息:"+ mData);
   //解析经纬度
   JSONObject jsonObject = new JSONObject(mData) ;
   JSONObject jsonjingweidu = jsonObject.getJSONObject("content").getJSONObject("point");
   String longitude =jsonjingweidu.getString("y");
   String latitude =jsonjingweidu.getString("x");
   jingweidu=  new double[]{stringToDouble(longitude),stringToDouble(latitude)};
   Log.i(TAG, "longitude :"+jingweidu[0] +"latitude : "+jingweidu[1]);


   int  r = setLocalJingweidu();   //经纬度保存到本地 --------- 文章中省略
   if(r==1)
   {
    double[] temp = getLocalJingweidu();   //从本地获得保存的经纬度信息 --------- 文章中省略

    Log.i(TAG, "保存经纬度到本地成功  ,经度:"+temp[0]+"纬度:"+temp[1]);
   }else
   {
    Log.i(TAG, "保存经纬度到本地失败");
   }
  } catch (Exception e) {
   Log.i(TAG, "更新操作异常"+e.toString());
  }
 }


 //定时器
 private Timer myLocationTimer = null;
 //定时线程
 private  TimerTask myLocationTimerTask = null;

  /***
  * 初始化定时器
  */
 private void initLocationTime()
 {
  if(myLocationTimer==null)
  {
   Log.i(TAG, "myLocationTimer 已经被清空了");
   myLocationTimer = new Timer();
  }else
  {
   Log.i(TAG, "myLocationTimer 任然存在");
  }
 }
 
 /***
  * 初始化 定时器线程
  */
 private void initLocationTimeTask()
 {
  myLocationTimerTask = new TimerTask() {
   /***
    * 定时器线程方法
    */
   @Override
   public void run() {
    handler.sendEmptyMessage(1); //发送消息
   }
  };
 }
 
 /***
  * 初始化 time 对象 和 timetask 对象
  */
 private void initLocationTimeAndTimeTask()
 {
  initLocationTime();
  initLocationTimeTask();
 }
 
 /***
  * 销毁 time 对象 和 timetask 对象
  */
 private void destroyLocationTimeAndTimeTask()
 {
  myLocationTimer = null;
  myLocationTimerTask = null;
 }
 
 
 /***
  * 打开定位定时器线程
  */
 public void openLocationTask()
 {
 
  try {
   
   if(!isOpenLocationTask)   ///如果不是打开状态,则打开线程
   {
    startLocation();//启动定位更新经纬度
    //开启定时器
    initLocationTimeAndTimeTask();  //初始化定时器和定时线程
    myLocationTimer.schedule(myLocationTimerTask, myTime, myTime);
    Log.i(TAG, " 打开了定位定时器线程 ");
    isOpenLocationTask = true;  //标记为打开了定时线程
   }else
   {
    Log.i(TAG, " 已经开启了定位定时器线程 ");
   }
  } catch (Exception e) {
   Log.i(TAG, "打开定位定时器线程 异常"+e.toString());
  }
 }

 

/***
  * 定时器的回调函数,用来定时的去发送定位请求
  */
 private  Handler handler = new Handler() {
  //更新的操作
  @Override
  public void handleMessage(Message msg) {
   getLocationInfo();   //获取经纬度 
   
   Log.i(TAG,"调用了获取经纬度方法");
   super.handleMessage(msg);
  }
 };

 

//****

设置定位的服务模式。服务模式类型为枚举类型LocServiceMode。目前有两种:一是Background,一是Immediat
      Background为后台服务模式,后台每隔设定的时间扫描一次定位依据信息,判定位置是否改变,如果改变,生成定位依据加密串。在此模式下,用户可以调用getLocation来根据当前的定位加密串从服务器获取定位依据。也可以实现并注册一个接口LocationChangedListener,当locationChanged的时候,被调用。
      Immediat为即时扫描服务。后台不扫描。当用户想获取当前位置时,需要实现并注册一个接口ReceiveListener,然后调用startLocating函数,会异步的发起wifi扫描。当有结果时,定位SDK会调用接口函数。   

(详细的请查看百度地图定位API)

3.好了,application 类中的定位代码完成,接下来要做的就是两件事,一件是,在合适的地方,打开这个定位的定时器来获取定位信息,第二件,就是在关闭APP的时候,去关闭这个定位的定时器。

  1>  开启代码:

       ((locationApplicationBean)getApplication()).openLocationTask(); //开启定时的定位线程

  2>  关闭代码:

        ((locationApplicationBean)getApplication()).closeLocationTask(); //关闭定时的定位线程

4.好了,大功告成了,一个定位定时器就完成了,文章中可能没有说明清楚,示例项目请点击链接下载:http://download.csdn.net/detail/zjl5211314/3712551 

 

如果大家有什么疑问,或者好的建议欢迎交流。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值