开始搞个android定位demo(2)高德

话说这几天新闻挺多啊

先是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++) {

google建议设置成1到5,max number of addresses to return. Smaller numbers (1 to 5) are recommended

莫非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()); }

综上,在试用阶段,高德上手还是比较快的,起码pk google的geocoder不成问题,下一篇试一下baidu的


你可能感兴趣的:(android)