话说这几天新闻挺多啊
先是baidu map在东莞大发神威
然后就是阿里巴巴把高德给收购了
搞定了location之后,开始研究geocoder
本来打算从baidu map开始的,可是baidu map实在没有高德map简单,申请key也繁琐
所以就先调试了下高德map
结果真是令本人惊讶
用的同样都是network,得到的是同一个精度和纬度,我不知道为什么geocoder的精度差这么多,geocoder按道理来说调用的是google map才对,结果连区都不对
而高德基本上可以精确到街道了,想想都有点恐怖。。。。。
下面代码是根据高德的sample精简过的activity,location用的是另一篇作者的例子,模拟器用的是手上的闲置里程碑,
权限什么的直接copy的高德的sample
package com.example.gaode;
import java.io.IOException;
import java.util.List;
import com.amap.api.maps.AMap;
import com.amap.api.maps.CameraUpdateFactory;
import com.amap.api.maps.model.BitmapDescriptorFactory;
import com.amap.api.maps.model.MarkerOptions;
import com.amap.api.services.core.LatLonPoint;
import com.amap.api.services.geocoder.GeocodeResult;
import com.amap.api.services.geocoder.GeocodeSearch;
import com.amap.api.services.geocoder.GeocodeSearch.OnGeocodeSearchListener;
import com.amap.api.services.geocoder.RegeocodeQuery;
import com.amap.api.services.geocoder.RegeocodeResult;
import android.app.Activity;
import android.app.ProgressDialog;
import android.location.Address;
import android.location.Criteria;
import android.location.Geocoder;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.util.Log;
import android.widget.Button;
import android.widget.Toast;
public class MainActivity extends Activity implements OnGeocodeSearchListener {
private AMap aMap;
private GeocodeSearch geocoderSearch;
private String addressName ;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
init();
// 获取到LocationManager对象
LocationManager locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
// 创建一个Criteria对象
Criteria criteria = new Criteria();
// 设置粗略精确度
criteria.setAccuracy(Criteria.ACCURACY_COARSE);
// 设置是否需要返回海拔信息
criteria.setAltitudeRequired(false);
// 设置是否需要返回方位信息
criteria.setBearingRequired(false);
// 设置是否允许付费服务
criteria.setCostAllowed(false);
// 设置电量消耗等级
criteria.setPowerRequirement(Criteria.POWER_MEDIUM);
// 设置是否需要返回速度信息
criteria.setSpeedRequired(false);
// 根据设置的Criteria对象,获取最符合此标准的provider对象
String currentProvider = locationManager
.getBestProvider(criteria, true);
Log.d("Location", "currentProvider: " + currentProvider);
// 根据当前provider对象获取最后一次位置信息
Location currentLocation = locationManager
.getLastKnownLocation(currentProvider);
// 如果位置信息为null,则请求更新位置信息
if (currentLocation == null) {
locationManager.requestLocationUpdates(currentProvider, 0, 0,
locationListener);
}
// 直到获得最后一次位置信息为止,如果未获得最后一次位置信息,则显示默认经纬度
// 每隔10秒获取一次位置信息
while (true) {
currentLocation = locationManager
.getLastKnownLocation(currentProvider);
if (currentLocation != null) {
Log.d("Location", "Latitude: " + currentLocation.getLatitude());
Log.d("Location", "location: " + currentLocation.getLongitude());
break;
} else {
Log.d("Location", "Latitude: " + 0);
Log.d("Location", "location: " + 0);
}
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
Log.e("Location", e.getMessage());
}
}
// 解析地址并显示 原装geocoder
Geocoder geoCoder = new Geocoder(this);
try {
int latitude = (int) currentLocation.getLatitude();
int longitude = (int) currentLocation.getLongitude();
List list = geoCoder.getFromLocation(latitude, longitude,
2);
for (int i = 0; i < list.size(); i++) {
Address address = list.get(i);
Toast.makeText(
MainActivity.this,
address.getCountryName() + address.getAdminArea()
+ address.getFeatureName(), Toast.LENGTH_LONG)
.show();
Log.d("Location", address.getCountryName() + address.getAdminArea() + address.getFeatureName());
}
} catch (IOException e) {
Toast.makeText(MainActivity.this, e.getMessage(), Toast.LENGTH_LONG)
.show();
}
// 解析地址并显示 高德geocoder
LatLonPoint latLonPoint = new LatLonPoint(currentLocation.getLatitude(), currentLocation.getLongitude());
RegeocodeQuery query = new RegeocodeQuery(latLonPoint, 200,
GeocodeSearch.AMAP);// 第一个参数表示一个Latlng,第二参数表示范围多少米,第三个参数表示是火系坐标系还是GPS原生坐标系
geocoderSearch.getFromLocationAsyn(query);
}
// 创建位置监听器
private LocationListener locationListener = new LocationListener() {
// 位置发生改变时调用
@Override
public void onLocationChanged(Location location) {
Log.d("Location", "onLocationChanged");
Log.d("Location",
"onLocationChanged Latitude" + location.getLatitude());
Log.d("Location",
"onLocationChanged location" + location.getLongitude());
}
// provider失效时调用
@Override
public void onProviderDisabled(String provider) {
Log.d("Location", "onProviderDisabled");
}
// provider启用时调用
@Override
public void onProviderEnabled(String provider) {
Log.d("Location", "onProviderEnabled");
}
// 状态改变时调用
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
Log.d("Location", "onStatusChanged");
}
};
private void init() {
geocoderSearch = new GeocodeSearch(this);
geocoderSearch.setOnGeocodeSearchListener(this);
}
@Override
public void onGeocodeSearched(GeocodeResult arg0, int arg1) {
// TODO Auto-generated method stub
}
@Override
public void onRegeocodeSearched(RegeocodeResult result, int rCode) {
if (rCode == 0) {
if (result != null && result.getRegeocodeAddress() != null
&& result.getRegeocodeAddress().getFormatAddress() != null) {
addressName = result.getRegeocodeAddress().getFormatAddress()
+ "附近";
// aMap.animateCamera(CameraUpdateFactory.newLatLngZoom(
// AMapUtil.convertToLatLng(latLonPoint), 15));
// regeoMarker.setPosition(AMapUtil.convertToLatLng(latLonPoint));
Toast.makeText( MainActivity.this,addressName, Toast.LENGTH_LONG).show();
Log.d("Location", addressName);
// ToastUtil.show(GeocoderActivity.this, addressName);
} else {
Log.d("Location", "gaode no_result ");
// ToastUtil.show(GeocoderActivity.this, R.string.no_result);
}
} else if (rCode == 27) {
Log.d("Location", "gaode error_network ");
// ToastUtil.show(GeocoderActivity.this, R.string.error_network);
} else if (rCode == 32) {
Log.d("Location", "gaode error_key ");
// ToastUtil.show(GeocoderActivity.this, R.string.error_key);
} else {
Log.d("Location", "gaode error_other ");
// ToastUtil.show(GeocoderActivity.this, R.string.error_other);
}
}
}
查了下关于geocoder的描述
上面代码里面的这块地方可疑性最大
List list = geoCoder.getFromLocation(latitude, longitude,
2);
for (int i = 0; i < list.size(); i++) {
莫非1是最精确的?我用了2的缘故?
将这个数字从1到5试了下
结果没有变化,也就是说,设为1,就是设为5时的第一个结果,这个数字与精度无关
看来了下,第一个和第二个结果
在getFeatureName时有区别,好吧,虽然连区居然都错了,但是为什么会有这个区别呢??????
暂时解决不了,这个参数很奇怪,而且找不到什么给说明下
好吧,暂时放弃下
getFeatureName()
Returns the feature name of the address, for example, "Golden Gate Bridge", or null if it is unknown
02-15 09:19:20.379: D/Location(3021): 0中国上海市null四联路四联路
02-15 09:19:20.395: D/Location(3021): 1中国上海市null青浦区null
02-15 09:19:20.411: D/Location(3021): 2中国上海市null上海市null
02-15 09:19:20.426: D/Location(3021): 3中国上海市null上海市null
02-15 09:19:20.442: D/Location(3021): 4中国nullnull中国null
// 得到的地址数目设为5,然后用list循环,得到具体地址
List list = geoCoder.getFromLocation(latitude, longitude,
5);
for (int i = 0; i < list.size(); i++) {
Address address = list.get(i);
Toast.makeText(
MainActivity.this,
address.getCountryName() + address.getAdminArea()
+ address.getFeatureName()+address.getThoroughfare(), Toast.LENGTH_LONG)
.show();
Log.d("Location", i + address.getCountryName() + address.getAdminArea() + address.getSubLocality() +
address.getFeatureName()+address.getThoroughfare());
}