时下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

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

更多相关文章

  1. 实现Android的不同精度的定位(基于网络和GPS)
  2. Google Map Api 在android 中的使用(转载)
  3. Android使用Google Map服务 - 根据GPS信息在地图上定位
  4. Android基站定位原理及实现代码
  5. android定位服务:查看位置源及其属性
  6. GPS 定位经纬度
  7. 基站定位获取位置坐标
  8. Android百度地图的搜索及附近地址的检索
  9. 百度地图locationClient.start()没反应解决办法

随机推荐

  1. android去掉标题的方法
  2. Android(安卓)4.0 HttpUrlConnection的ge
  3. Android(安卓)解屏代码
  4. android 输入框自动匹配-AutoCompleteTex
  5. onRetainNonConfigurationInstance和getL
  6. Android(安卓)之各种颜色
  7. android > ImageView 加载本地/服务器图
  8. TextView——行间距与字母间隔
  9. Android(安卓)ListView里设置默认Item的
  10. Android(安卓)ImageView图片自适应