谈谈百度API的定位

来源:互联网 发布:vs2015如何编译c语言 编辑:程序博客网 时间:2024/05/21 14:56

     项目开发的过程中,可能需要用到定位。例如大众点评,一进入就开始定位。有时,你需要得到当前的Longitude、Latitude,或者Address,或者只是City。这时,你可能会使用Google的GPS模块进行定位。这种例子在网上是大把的,不过在谈及百度定位之前,咱们先回顾一下Google定位的做法。

     在Google的定位模块中,一般是GPS、Network或者基站方式。而且Google也提供了Criteria类给你定制你所需要的条件来进行定位,例如setAccuracysetPowerRequirementsetAltitudeRequired等,然后由LocationManager这个位置服务管理类getBestProvider获取当前最适合你的定位方式,然后getLastKnownLocation获得你要的Location。就这么简单!

     但是,这种方式经常没有那么理想(或者是我本身了解还不够全面的问题),而百度API这种“神级”的定位方式也应运而生。为什么称它神级,如果你使用过就应该比较清楚:基本只需要Network即可定位,如果需要精确定位则需要开启GPS,而且速度极快。但它最大的缺点是模式化。什么是模式化,就是写那个代码的时候,有些人都不知道到底是为什么,而且它提供的Lib的类都是木有注释,需要的话就得上官网看。

     不管怎样,下面给出一个例子代码:

/** * This Activity is mainly responsible for the preparation of the Navigation data  * and Location information. * @author XijieChen */public class WelcomeActivity extends MapActivity {/** * Regist this Listener when execute OnCreate and remove it when execute OnDestroy. */private LocationListener mLocationListener = null;private MKSearch mMKSearch = null;/** * These four variables are the location data which will be used in  * all the application. */private String CityAddress = null;private String subLongitude = null;private String subLatitude = null;private String cityName = null;LocationBean userLocation;/** * This variable will equal to 1 when the Location file is exist and it will equal to  * 0 on the contrary. */private int Flag = 0;private SharedPreferences settings = null;/** * This handler is mainly responsible for dealing with the message sent from threads.  */Handler newhandler = new Handler() {public void handleMessage(Message msg) {switch (msg.what) {case Constant.WELCOME_DOWNLOADSUCCESS:Intent intent = new Intent();intent.setClass(WelcomeActivity.this, StartActivity.class);startActivity(intent);finish();//Finish the current activity.break;case Constant.WELCOME_STARTSEARCH:try {int Longitude = (int) (1000000 * Double.parseDouble(subLongitude));int Latitude = (int) (1000000 * Double.parseDouble(subLatitude));// Search the address in this GeoPoint.mMKSearch.reverseGeocode(new GeoPoint(Latitude, Longitude));} catch (Exception e) {e.printStackTrace();}break;case Constant.WELCOME_GETADDRESS:GetCityFromAddress getCity = new GetCityFromAddress(CityAddress);cityName = getCity.getCityFromAddress();if(Flag == 0) {userLocation.setLocationAddress(CityAddress);userLocation.setCity(cityName);WriteLocation write = new WriteLocation(userLocation,settings);write.WriteLocationData();}// Start the download thread to download the navigation data.DownLoadThread downLoadThread = new DownLoadThread(userLocation.getCity());downLoadThread.start();break;}super.handleMessage(msg);}};@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);this.requestWindowFeature(Window.FEATURE_NO_TITLE);this.requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);setContentView(R.layout.activity_welcome);settings = getPreferences(Activity.MODE_APPEND);initLocationData(settings);}/** * Initialize the Location data and judge whether the location SharedPreferences  * is exist or not at the same time. */private void initLocationData(SharedPreferences settings) {ReadLocation read = new ReadLocation(settings);if(read.GetLocation() != null) {userLocation = read.GetLocation();Flag = 1;//It means that the location SharedPreferences is exist.newhandler.obtainMessage(Constant.WELCOME_DOWNLOADSUCCESS).sendToTarget();} else {userLocation = new LocationBean();Flag = 0;//It means that the location SharedPreferences isn't exist.ApplicationData app = (ApplicationData) this.getApplication();if (app.mBMapMan == null) {app.mBMapMan = new BMapManager(getApplication());app.mBMapMan.init(app.mStrKey, new ApplicationData.MyGeneralListener());}app.mBMapMan.start();WRSearchListener wrtempListener = new WRSearchListener();mMKSearch = new MKSearch();mMKSearch.init(app.mBMapMan, wrtempListener);// To initialize the MKSearchmLocationListener = new LocationListener() { public void onLocationChanged(Location location) {if (location != null) {StringBuilder longitude = new StringBuilder("" + location.getLongitude());subLongitude = (String) longitude.subSequence(0, 10);StringBuilder latitude = new StringBuilder("" + location.getLatitude());subLatitude = (String) latitude.subSequence(0, 9);userLocation.setLongitude(subLongitude);userLocation.setLatitude(subLatitude);newhandler.obtainMessage(Constant.WELCOME_STARTSEARCH).sendToTarget();}}};}}/** * When the data download successfully, this thread is responsible for sending a * DOWNLOADSUCCESS message to the newhandler. */private class DownLoadThread extends Thread {private String cityString = null;public DownLoadThread(String city) {cityString = city;}@Overridepublic void run() {DownLoadNaviData navidata = new DownLoadNaviData(WelcomeActivity.this,cityString);if (navidata.DownLoadData()) {newhandler.obtainMessage(Constant.WELCOME_DOWNLOADSUCCESS).sendToTarget();}}}protected void onPause() {if(Flag == 0) {ApplicationData app = (ApplicationData) this.getApplication();app.mBMapMan.getLocationManager().removeUpdates(mLocationListener);app.mBMapMan.stop();}ApplicationData.userLocation = userLocation;super.onPause();} protected void onResume() {if(Flag == 0) {ApplicationData app = (ApplicationData) this.getApplication();app.mBMapMan.getLocationManager().requestLocationUpdates(mLocationListener);app.mBMapMan.start();}super.onResume();}protected void onDestroy() {ApplicationData app = (ApplicationData) this.getApplication();if (app.mBMapMan != null) {app.mBMapMan.destroy();app.mBMapMan = null;}super.onDestroy();}@Overridepublic void onBackPressed() {// TODO Auto-generated method stubsuper.onBackPressed();}@Overrideprotected boolean isRouteDisplayed() {// TODO Auto-generated method stubreturn false;}/** * Implement the MKSearchListener interface in order to search the address * with the Logitude and the Latitude. */public class WRSearchListener implements MKSearchListener { public void onGetAddrResult(MKAddrInfo result, int iError) {if (result == null) {return;}StringBuffer sb = new StringBuffer();sb.append(result.strAddr);// The location depends on its Logitude and Latitude.CityAddress = sb.toString();newhandler.obtainMessage(Constant.WELCOME_GETADDRESS).sendToTarget();}public void onGetDrivingRouteResult(MKDrivingRouteResult result, int iError) {}public void onGetPoiResult(MKPoiResult result, int type, int iError) {}public void onGetTransitRouteResult(MKTransitRouteResult result, int iError) {}public void onGetWalkingRouteResult(MKWalkingRouteResult result, int iError) {}}}

在程序中,在Application的OnCreate中你会发现这样的代码:mBMapMan.init(this.mStrKey, new MyGeneralListener());其中MyGeneralListener是继承了MKGeneralListener,Key就是从http://dev.baidu.com/wiki/static/imap/key/上申请得到的。实际上,上面那个代码就是在注册一个BMapManager类对象。


1、BMapManager:注册该类,用于得到LocationManager,获取位置信息;

2、LocationListener:BMapManager要start前,需要requestLocationUpdates添加一个LocationListener。主要从该事件中onLocationChanged获取Location,从而获取Longitude、Latitude;(一般经纬度的获取是秒级的)

3、MKSearch:需要BMapManager的对象,以及一个实现了MKSearchListener的事件对象,进行init;

4、GeoPoint:使用你前面获得的Longitude、Latitude去new一个GeoPoint。值得注意的是,GeoPoint使用的经纬度必须是int型,所以首先必须将你的Longitude、Latitude转换为int。原因很简单,int运算速度快;

5、使用MKSearch的对象对一个GeoPoint进行reverseGeocode,这个时候,在你实现了MKSearchListener的事件对象中onGetAddrResult即可得到MKAddrInfo result,其中result就是你要的Address了。(一般情况下可以定位到市区,GPS下可以准确到街道门牌号,神级!!)


另外,百度这种定位强大在就算你使用它定位成功,其实你也不清楚里面的原理的,因为百度压根就没有告诉你,你会发现IDE中的类都是没有JavaDoc的。。。(或许是我学艺不精,还不理解吧,如果是这样,还望各位不吝指教)





原创粉丝点击