您的位置:首页 > 移动开发 > Android开发

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

2011-10-25 19:14 891 查看
时下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

如果大家有什么疑问,或者好的建议欢迎交流。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐