浅谈 Android 中的地图和定位

来源:互联网 发布:如何成为淘宝供应商 编辑:程序博客网 时间:2024/06/05 10:37

因为最近在项目上需要用到地图和定位相关的开发,所以花了一些时间把着百度和Google的相关部分看了下。


1. 首先谈下 google 关于这个部分

为什么要首先说 google 呢?因为这是刚开始最早使用的,但是后来因为不能通过经纬度来获取地址而放弃了(不知道是不是天朝的原因),所以使用的较少就先说。

总的来说,按照网上的说法 google 相关的 sdk 是最强的,从 sdk 来看百度也是步步跟随 google 的步伐来走。


google 提供的关于map部分,目前分为两套:

第一套,老的,是在 framework 层的老的 sdk,官方的培训在这里,api guide 中的两个介绍 Location and Maps 和 Location Strategies

Location and Maps 对于基本的地图和定位开发做了简单介绍,简单看看就好了。

Location Strategies 是强烈建议大家做位置相关的开发之前要看的,里面介绍了很多开发的心得和技巧,避免走很多弯路。

第二套,新的,是在 google play service 中(这样做之后,将来相关 api 的升级就不用等着 android 的升级而升级了,只要重新装下 apk 就可以升级了,是不是很方便啊!)


1.1 Google play service 中的定位和 map

如果条件允许的话,当然是用最新最强的 google play service(gms) 中的部分,但是因为 google play service 不能保证在每台 android 的设备中都可以用(特别是我国的设备,应该大多数都没有),所以如果要使用的话必须要检查有没有这个玩意在手机中,google 自己也给出了相关的说明(看看其中的  Ensure Devices Have the Google Play services APK)。


如果万幸你可以用的话,则关于通过 gms 使用 location 的说明在 location 和 这里,通过 gms 使用 map 的说明在这里,但是正是因为天朝手机大多数应该都没有 gms 的原因,所以这个部分我并没有去实际使用,有兴趣可以看 google io 2013 的视频,关于 location 的是 Beyond the Blue Dot: New Features in Android Location,关于 map 的是 When Android Meets Maps(请自备梯子)


详细的可以看上面的视频介绍,主要想说的就是:

a. geofence 这是新的特色,也就是在地图上画个范围(类似于围栏,baidu现在也有了,不过还是beta),然后有东西进入这个围栏之后就可以做些事情了,很好。

b. requestLocationUpdates() 这个函数注册的时候使用 listener 还是 pendingIntent 的原则

如果是想后台默默的做些事情使用 pendingIntent,如果是前台马上有反应使用 listener


另外,google map 的部分已经升级到了 V2 版本,详细的可以看下 Google Maps Android API v2,同时在 github 上也有一个和 google map 相关的资源,根据 google io 视频的介绍都是 google 做 map 的人开发的,如果需要用到一些和 map 相关的例子和工具的时候可以看下这里。


1.2 目前 Framework 中使用的 api

首先把官方的培训看下,此处要说明的是,在 provider (除了 network,gps,best 之外)中,新增了 passive provider 其强悍的地方在于用了它,也就是说在其他程序请求位置的时候也会给你发一份,这样你就不用去真的请求一个 provider 了,是不是很节省资源。


2. 百度 sdk 的使用

目前百度的这个部分,也分成了两块 map sdk 和 定位 sdk,旧的 map sdk 可以获得位置,而新的 map sdk 中去了获取位置的部分,只支持通过经纬度来获取地址,所有的获取位置的操作都放到了定位 sdk中。


2.1 关于定位的问题

在定位 sdk中获取位置的函数只有一个 LocationClient.requestLocation()  这时候肯定就有同学问了,那么如何知道是一次请求还是周期性请求呢?仔细看 sdk 就知道通过 LocationClientOption.setScanSpan() 可以实现,如果是小于1秒则是一次请求,如果大于1秒则是周期性的请求。


2.2 关于坐标的问题

在 google 中使用的标准的坐标格式 WGS-84,而百度使用的是另外三种格式,所以百度和 google 的坐标系不能相互使用,如果需要坐标转换的算法需要单独发邮件给百度。


其他就没有什么特殊要说的了,再做开发之前需要仔细阅读相关的开发常见问题避免走弯路。


3. 实际开发中的经验总结

3.1 如何获取我当前的位置

通常情况下大家都会启动一个 requestLocationUpdates() 模样的函数(百度是 requestLocation())来定期获取位置,但是根据 Location Strategies 文章的介绍,这样做是会费电的,所以最好的做法是不要一直定期获取,而是在启动某个 activity 之前获取,例如:A 这个 activity 中有个按钮,点击之后就会进入 B,而 B 是一个地图的 activity 会显示我当前的位置,那么就应该在 A 这个 activity 就启动我当前位置的追踪。


接下来就有另外一个问题,追踪我当前的位置,通常都是异步操作结果会返回给一个 listener,那么如果是在 A 这里启动,则这个 listener 必然是在 A 中,那么这个结果怎么告诉给 B,让它来显示我的位置呢?答案是通过数据库,A 将结果写入到数据库中,然后 B 启动之后先从数据库中获取最新的我的位置(这个肯定比从网络获取要快很多),然后响应数据库的变化来更新我的当前位置。


3.2 如何计算两点之间的距离

获取完位置之后,通常需要判断下是不是同一个点,如果是则就不见得需要更新到数据库中(或许只需要更新下时间),那么此处就有两个函数可以来知道两点之间的距离

google Location.distanceBetween(),百度 DistanceUtil.getDistance(),得到距离之后可以判断是不是在一定范围内(例如:10米)从而来决定这两个点是不是相同的位置。


3.3 同一套代码如何同时支持百度和google

基本思路:创建一个抽象层封装大部分的细节,上层通过回调函数和数据库来和下层要数据,从而不用管底层具体是百度还是google。


只是因为坐标系不同,所以获得到经纬度之后还需要知道是谁提供的(百度,google)然后在做接下来的操作,如果将 google 的坐标值交给百度相关的 sdk 直接处理(没有做任何转换)是会有误差的。


当然上面的说法只适合简单 app 中使用地图的场合,如果真的做复杂了可能还是要分开处理,例如:在国内用使用百度,在其他地区使用 google。


4. 其他

国内还有高德地图,当年google在中国就是和他合作的但是我还没有用过所以没有什么好说的,等之后用过在补充。