Android:利用Google GeoCoding API替代Geocoder & 解决地址语言问题

摘要:Android定位开发中碰到GeoCoder间歇抽风问题,查证后得知可以用Google GeoCoding API来Workaround,这里记录此过程中遇到的两个收获吧,一是对这个Workaround给出自己的简单多线程解决方案,并未做太多封装。二是解决解析结果中地址的语言问题。

一.问题描述

最近在使用Android SDK中Geocoder类进行地址解析时发现有很大概率发生下面的悲剧…..

 java.io.IOException: Service not Available

具体原因有各种说法吧,也有文档

The Geocoder class requires a backend service that is not included in the core android framework. The Geocoder query methods will return an empty list if there no backend service in the platform. Use the isPresent() method to determine whether a Geocoder implementation exists.
意思应该是Geocoder类的使用描述在使用的前提是必须有 后台服务的支持,但是andorid sdk中不包含该服务的,Google可真够开玩笑的。在真机上不一定存在。据称可以用isPresent() 检测一下,就知道有没有了。

二.锁定解决方案

我在Android 的Google Code上发现各国的Developer都碰到这个问题了(http://code.google.com/p/android/issues/detail?id=8816),当然他们也提出了一些解决方案,简单总结下:

1.使用GoogleMap请求KML来解析位置(KML的Wiki传送门),当然要了解怎么使用KML的话,还得去http://code.google.com/apis/kml/documentation/,看看文档。具体的解决方案是使用URL请求,这是Issues里给的示例,Comment 20 by musicwit…@gmail.com

http://maps.google.com.tw/maps?f=q&source=s_q&hl=zh-TW&geocode=&q=%E5%8F%B0%E5%8D%97%E7%81%AB%E8%BB%8A%E7%AB%99&ie=UTF8&0&om=0&output=kml

2.像Comment21里说的我们可以直接利用http地址,实现地址查询:如:

根据地址查询经纬度:

http://maps.googleapis.com/maps/api/geocode/json?address=SFO&sensor=false

根据经纬度查询地址:

http://maps.googleapis.com/maps/api/geocode/json?latlng=40.714224,-73.961452&sensor=false

bounds的作用

http://maps.googleapis.com/maps/api/geocode/json?address=Winnetka&sensor=false

http://maps.googleapis.com/maps/api/geocode/json?address=Winnetka&bounds=34.172684,-118.604794|34.236144,-118.500938&sensor=false

region的作用

http://maps.googleapis.com/maps/api/geocode/json?address=Toledo&sensor=false

http://maps.googleapis.com/maps/api/geocode/json?address=Tole

具体可以查看GoogleMap服务的文档http://code.google.com/intl/zh-CN/apis/maps/documentation/geocoding/

因为项目时间的原因,我果断采用了第二种我比较熟悉的方法。

三.多线程完成HTTP地址解析

这方面的教程网上已经有很多了,我就不列出我的方案了,给大家一个传送门吧

四.中文地址问题

我的需求是由地理位置解析出中文地址,但由Google Map  GeoCoding API返回的确实英文地址,我试过在HTTP请求中带Charset参数,但并没有成功返回中文…..

在网上搜了一大圈以后才发现一个解决方法,原来可以直接在Url里带language=zh-CN参数,服了,估计经常使用GoogleAPI的才知道吧,也没发现相关文档,示例:

http://maps.google.com/maps/api/geocode/json?latlng=39.9727642,116.3753401&sensor=true&language=zh-CN

可以返回中文了,Problem Done!

Update 2011-09-22:使用使用Google GeoCoding API过程的问题

千万别觉得这就结束了,下面列举在实际使用Google GeoCoding API过程中发现的几个问题:

1.HTTP连接不太稳定,注意多次尝试,而不是仅发送一次请求就使用,而要判断在没有返回值的时候尝试一定次数。

2.有时候Google GeoCodingAPI会返回错误格式的地址,记得做处理,例如:

请求:返回formatted_address字段,Url:

Request URL: http://maps.googleapis.com/maps/api/geocode/json?latlng=30.511381,114.401893&sensor=false&language=zh-CN

返回: “formatted_address”: “中国湖北省武汉市洪山区鲁磨路118号 邮政编码: 430079″

崩溃了,居然错带了邮编…..所以还要人工处理下,防止以上情况的发生!

参考文献:

Android Google Code Issue 8816: service not available

Android:用户定位User Localtion和利用HTTP解析地址—GeoCoding

Google Geocoding API 开发语言问题