Android 使用GPS获取到经纬度后 无法在Android8.0上使用Geocoder类获取位置信息
由于我的应用在获取到经纬度后在Android8.0不能使用如下代码获取位置信息。只好使用百度地图 WEB服务API 通过调接口的方式获取位置信息。
Geocoder geocoder = new Geocoder(context, Locale.getDefault()); List<Address> addresses = geocoder.getFromLocation(latitude, longitude, 1);
首先需要有百度开发者账户,以便获取key/ak,这个很简单略过。请求地址:
String url = String.format( "http://api.map.baidu.com/geocoder/v2/?ak=qmalblOI3MvyturtOgNw0pvp********" + "&location=%s,%s&output=json&pois=1&coordtype=wgs84ll" + "&mcode=E2:AE:A4:FA:64:56:E4:B8:08:25:70:6A:E5:55:B8:E2:BD:**:**:**;com.myapp", latitude, longitude);
其中ak为用户申请注册的key。mcode为安全码,在百度开发者平台的“我的应用”进入创建的应用即可看到安全码。coordtype为参数中经纬度坐标类型,默认为百度的坐标类型。
官方文档 请仔细查看官方文档
请求参数
参数名 | 参数含义 | 类型 | 举例 | 默认值 | 是否必须 |
---|---|---|---|---|---|
location | 根据经纬度坐标获取地址。 | float | 38.76623,116.43213
lat<纬度>,lng<经度> |
无 | 是 |
coordtype | 坐标的类型,目前支持的坐标类型包括:bd09ll(百度经纬度坐标)、bd09mc(百度米制坐标)、gcj02ll(国测局经纬度坐标,仅限中国)、wgs84ll( GPS经纬度) 坐标系说明 | string | bd09ll、gcj02ll | bd09ll | 否 |
_coordtype | 可选参数,添加后返回国测局经纬度坐标或百度米制坐标 坐标系说明 | string | gcj02ll(国测局坐标,仅限中国)、bd09mc(百度墨卡托坐标) | bd09ll(百度经纬度坐标) | 否 |
pois | 是否召回传入坐标周边的poi,0为不召回,1为召回。当值为1时,默认显示周边1000米内的poi。 注意:若需访问海外POI,需申请「逆地理编码海外POI」服务权限,请提交工单申请。 |
int | 0 | 0 | 否 |
radius | poi召回半径,允许设置区间为0-1000米,超过1000米按1000米召回。 | int | 500 | 1000 | 否 |
ak | 用户申请注册的key,自v2开始参数修改为“ak”,之前版本参数为“key” 申请ak | string | E4805d16520de693a3fe70 | 无 | 是 |
sn | 若用户所用ak的校验方式为sn校验时该参数必须 sn生成 |
string | 无 | 否 | |
output | 输出格式为json或者xml | string | json或xml | xml | 否 |
callback | 将json格式的返回值通过callback函数返回以实现jsonp功能 | string | callback=showLocation(JavaScript函数名) | 无 | 否 |
extensions_poi | 区别于pois参数,pois=0,不召回pois数据,但后端仍访问poi相应服务;extensions_poi=null时,后端不调用poi相关服务,可减少服务访问时延。 注意:若需访问海外POI,需申请「逆地理编码海外POI」服务权限,请提交工单申请。 |
string | null | 无 | 否 |
extensions_road | 当取值为true时,召回坐标周围最近的3条道路数据。区别于行政区划中的street参数(street参数为行政区划中的街道,和普通道路不对应)。 | string | false、true | false | 否 |
extensions_town | 当取值为true时,行政区划返回乡镇级数据(仅国内召回乡镇数据)。默认不访问。 | string | true | 无 | 否 |
language | 指定召回的新政区划语言类型。 召回行政区划语言list(全量支持的语言见示例)。 当language=local时,根据请求中坐标所对应国家的母语类型,自动选择对应语言类型的行政区划召回。 目前支持多语言的行政区划区划包含country、provence、city、district 注意:多语言需申请「逆地理编码海外POI」服务权限,请提交工单申请。 |
string | el gu en vi ca it iw sv eu ar cs gl id es en-GB ru sr nl pt tr tl lv en-AU lt zh-TW th ro fil ta fr bg hr bn de hu fa hi pt-BR fi da ja te pt-PT ml ko kn sk zh-CN pl uk sl mr local |
en,国内默认zh-CN | 否 |
language_auto | 是否自动填充行政区划。 1填充,0不填充。 填充:当服务按某种语言类别召回时,若某一行政区划层级数据未覆盖,则按照“英文→中文→本地语言”类别行政区划数据对该层级行政区划进行填充,保证行政区划数据召回完整性。 注意:多语言需申请「逆地理编码海外POI」服务权限,请提交工单申请。 |
int | 0、1 | 无 | 否 |
latest_admin | 是否访问最新版行政区划数据(仅对中国数据生效),1(访问),0(不访问) | int | 0、1 | 0 | 否 |
返回结果参数
名称 | 含义 | 类型 | |
---|---|---|---|
status | 返回结果状态值, 成功返回0,其他值请查看下方返回码状态表。 | int | |
location | 经纬度坐标 | object | |
lat | 纬度值 | float | |
lng | 经度值 | float | |
formatted_address | 结构化地址信息 | string | |
business | 坐标所在商圈信息,如 "人民大学,中关村,苏州街"。最多返回3个。 | string | |
addressComponent (注意,国外行政区划,字段仅代表层级) |
country | 国家 | string |
province | 省名 | string | |
city | 城市名 | string | |
district | 区县名 | string | |
town | 乡镇名 | string | |
street | 街道名(行政区划中的街道层级) | string | |
street_number | 街道门牌号 | string | |
adcode | 行政区划代码 adcode映射表 |
int | |
country_code | 国家代码 | int | |
direction | 相对当前坐标点的方向,当有门牌号的时候返回数据 | string | |
distance | 相对当前坐标点的距离,当有门牌号的时候返回数据 | string | |
pois(周边poi数组) | addr | 地址信息 | string |
cp | 数据来源(已废弃) | string | |
direction | 和当前坐标点的方向 | string | |
distance | 离坐标点距离 | int | |
name | poi名称 | string | |
poiType | poi类型,如’ 办公大厦,商务大厦’ | string | |
point | poi坐标{x,y} | float | |
tel | 电话 | int | |
uid | poi唯一标识 | string | |
zip | 邮编 | int | |
parent_poi | poi对应的主点poi(如,海底捞的主点为上地华联,该字段则为上地华联的poi信息。如无,该字段为空),包含子字段和pois基础召回字段相同。 | ||
poiRegions | direction_desc | 请求中的坐标与所归属区域面的相对位置关系 | string |
name | 归属区域面名称 | string | |
tag | 归属区域面类型 | string | |
sematic_description | 当前位置结合POI的语义化结果描述。 | string | |
cityCode | 百度定义的城市id(正常更新与维护,但建议使用adcode) | int |
服务状态码
返回码 | 英文描述 | 定义 | 常见原因 |
---|---|---|---|
0 | ok | 正常 | 服务请求正常召回 |
1 | 服务器内部错误 | ||
2 | Parameter Invalid | 请求参数非法 | 必要参数拼写错误或漏传(如query和tag请求中均未传入) |
3 | Verify Failure | 权限校验失败 | |
4 | Quota Failure | 配额校验失败 | 服务当日调用次数已超限,请前往API控制台提升(请优先进行开发者认证) |
5 | AK Failure | ak不存在或者非法 | 未传入ak参数;ak已被删除(可前往回收站恢复); |
101 | 服务禁用 | ||
102 | 不通过白名单或者安全码不对 | ||
2xx | 无权限 | ||
3xx | 配额错误 |
PS:不同坐标系之间转换 http://bbs.lbsyun.baidu.com/forum.php?mod=viewthread&tid=10923&logout=success
public class CoordinatesTransformation { static double pi = 3.14159265358979324; static double a = 6378245.0; static double ee = 0.00669342162296594323; public final static double x_pi = 3.14159265358979324 * 3000.0 / 180.0; public static double[] wgs2bd(double lat, double lon) { double[] wgs2gcj = wgs2gcj(lat, lon); double[] gcj2bd = gcj2bd(wgs2gcj[0], wgs2gcj[1]); return gcj2bd; } public static double[] gcj2bd(double lat, double lon) { double x = lon, y = lat; double z = Math.sqrt(x * x + y * y) + 0.00002 * Math.sin(y * x_pi); double theta = Math.atan2(y, x) + 0.000003 * Math.cos(x * x_pi); double bd_lon = z * Math.cos(theta) + 0.0065; double bd_lat = z * Math.sin(theta) + 0.006; return new double[] { bd_lat, bd_lon }; } public static double[] bd2gcj(double lat, double lon) { double x = lon - 0.0065, y = lat - 0.006; double z = Math.sqrt(x * x + y * y) - 0.00002 * Math.sin(y * x_pi); double theta = Math.atan2(y, x) - 0.000003 * Math.cos(x * x_pi); double gg_lon = z * Math.cos(theta); double gg_lat = z * Math.sin(theta); return new double[] { gg_lat, gg_lon }; } public static double[] wgs2gcj(double lat, double lon) { double dLat = transformLat(lon - 105.0, lat - 35.0); double dLon = transformLon(lon - 105.0, lat - 35.0); double radLat = lat / 180.0 * pi; double magic = Math.sin(radLat); magic = 1 - ee * magic * magic; double sqrtMagic = Math.sqrt(magic); dLat = (dLat * 180.0) / ((a * (1 - ee)) / (magic * sqrtMagic) * pi); dLon = (dLon * 180.0) / (a / sqrtMagic * Math.cos(radLat) * pi); double mgLat = lat + dLat; double mgLon = lon + dLon; double[] loc = { mgLat, mgLon }; return loc; } private static double transformLat(double lat, double lon) { double ret = -100.0 + 2.0 * lat + 3.0 * lon + 0.2 * lon * lon + 0.1 * lat * lon + 0.2 * Math.sqrt(Math.abs(lat)); ret += (20.0 * Math.sin(6.0 * lat * pi) + 20.0 * Math.sin(2.0 * lat * pi)) * 2.0 / 3.0; ret += (20.0 * Math.sin(lon * pi) + 40.0 * Math.sin(lon / 3.0 * pi)) * 2.0 / 3.0; ret += (160.0 * Math.sin(lon / 12.0 * pi) + 320 * Math.sin(lon * pi / 30.0)) * 2.0 / 3.0; return ret; } private static double transformLon(double lat, double lon) { double ret = 300.0 + lat + 2.0 * lon + 0.1 * lat * lat + 0.1 * lat * lon + 0.1 * Math.sqrt(Math.abs(lat)); ret += (20.0 * Math.sin(6.0 * lat * pi) + 20.0 * Math.sin(2.0 * lat * pi)) * 2.0 / 3.0; ret += (20.0 * Math.sin(lat * pi) + 40.0 * Math.sin(lat / 3.0 * pi)) * 2.0 / 3.0; ret += (150.0 * Math.sin(lat / 12.0 * pi) + 300.0 * Math.sin(lat / 30.0 * pi)) * 2.0 / 3.0; return ret; } }
Less interests,more interest!