本文主要介绍了Android项目集成百度地图API,使用AlarmManager定时调用Service,在Service中请求坐标更新,并通过坐标得到省、市和县三级地理位置信息的方法。

程序结构很简单,先做简单介绍,后面详细说明:

  1. MainActivity.java是创建项目自带的,不用管;
  2. BMapApiDemoApp.java是大部分是百度自带demo文件没有改动,只是在里面添加了Alarm相关的代码;
  3. GetLocationService.java是Alarm启动的Service类,在这个类中请求位置更新;
  4. GeoCoderParser.java是用于接收地理位置信息的回调类。

百度地图API

集成百度地图API的方式很简单,可以上官网http://developer.baidu.com/map/sdk-android.htm下载相应的库文件和demo。具体的集成方法这里不再赘述,仅仅讨论一下BMapApiDemoApp这个类。代码如下:

View Code
 1 public class BMapApiDemoApp extends Application { 2  3     private static final String TAG = "BMapApiDemoApp"; 4  5     static BMapApiDemoApp mDemoApp; 6  7     BMapManager mBMapMan = null; 8  9     String mStrKey = "Your key here!!";10     boolean m_bKeyRight = true;11 12     static class MyGeneralListener implements MKGeneralListener {13         @Override14         public void onGetNetworkState(int iError) {15             Log.d("MyGeneralListener", "onGetNetworkState error is " + iError);16             Toast.makeText(BMapApiDemoApp.mDemoApp.getApplicationContext(),17                     "Network error", Toast.LENGTH_LONG).show();18         }19 20         @Override21         public void onGetPermissionState(int iError) {22             Log.d("MyGeneralListener", "onGetPermissionState error is "23                     + iError);24             if (iError == MKEvent.ERROR_PERMISSION_DENIED) {25                 Toast.makeText(BMapApiDemoApp.mDemoApp.getApplicationContext(),26                         "Permission deny! Add key in BMapApiDemoApp.java!", Toast.LENGTH_LONG).show();27                 BMapApiDemoApp.mDemoApp.m_bKeyRight = false;28             }29         }30     }31 32     @Override33     public void onCreate() {34         mDemoApp = this;35         mBMapMan = new BMapManager(this);36         boolean isSuccess = mBMapMan37                 .init(this.mStrKey, new MyGeneralListener());38         if (isSuccess) {39             mBMapMan.getLocationManager().setNotifyInternal(10, 5);40             startAlarm();41         } else {42         }43         super.onCreate();44     }45 46     private void startAlarm() {47         Log.d(TAG, "start alarm");48         AlarmManager am = (AlarmManager)getSystemService(Context.ALARM_SERVICE);49         Intent collectIntent = new Intent(this, GetLocationService.class);50         PendingIntent collectSender 51             = PendingIntent.getService(this, 0, collectIntent, 0);52         am.cancel(collectSender);53         am.setRepeating(AlarmManager.ELAPSED_REALTIME54             , SystemClock.elapsedRealtime()55             , 10 * 100056             , collectSender);57     }58     59     @Override60     public void onTerminate() {61         // TODO Auto-generated method stub62         if (mBMapMan != null) {63             mBMapMan.destroy();64             mBMapMan = null;65         }66         super.onTerminate();67     }68 69 }

主要关注如下几点:

  1. BMapApiDemoApp覆盖了Application类,并在onCreate()函数中初始化BMapManager对象,这样程序就可以共享这个对象。
  2. BMapManager类主要有4个函数,init(), start(), stop() 和destory()。一般在Application类的onCreate()函数中调用init,在onDestory()函数中调用destory,这样在需要使用其他API的地方只需要取到这个对象并调用start和stop方法就可以了。但是为了保证BMapManager对象存在,在其他调用的类中还是会做相应的检查。
  3. 文件中变量mStrKey保存的是需要去官网申请的API的key,申请很容易。
  4. 我在onCreate()函数中还调用了startAlarm()函数。这个函数的作用是每隔10s调用GetLocationService类。

GetLocationService

GetLocationService主要覆写了两个函数onStartCommand()和onCreate(),代码如下:

View Code
 1 public class GetLocationService extends Service { 2  3     protected static final String TAG = null; 4     LocationListener mLocationListener = null; 5     BMapApiDemoApp app = null; 6     @Override 7     public void onCreate() { 8         super.onCreate(); 9         app = (BMapApiDemoApp) this.getApplication();10         if (app.mBMapMan == null) {11             app.mBMapMan = new BMapManager(getApplication());12             app.mBMapMan.init(app.mStrKey,13                     new BMapApiDemoApp.MyGeneralListener());14         }15         app.mBMapMan.start();16         final MKSearch mMKSearch = new MKSearch();17         mMKSearch.init(app.mBMapMan, new GeoCoderParser());18 19         // 注册定位事件20         mLocationListener = new LocationListener() {21 22             @Override23             public void onLocationChanged(Location location) {24                 Log.d(TAG, "location change");25                 if (location != null) {26                     String strLog = String.format("经度:%f\r\n" + "纬度:%f", 27                             location.getLongitude(),28                             location.getLatitude());29                     Log.d(TAG, strLog);30                     GeoPoint point = new GeoPoint((int)(location.getLatitude() * 1E6), (int)(location.getLongitude() * 1E6));31                     mMKSearch.reverseGeocode(point);32                     33                     app.mBMapMan.getLocationManager().removeUpdates(mLocationListener);34                     app.mBMapMan.stop();35                 }36             }37         };38     }39 40     @Override41     public int onStartCommand(Intent intent, int flag, int startId) {42         app.mBMapMan.getLocationManager().requestLocationUpdates(43                 mLocationListener);44         app.mBMapMan.start();45         return Service.START_NOT_STICKY;46     }47 48     @Override49     public IBinder onBind(Intent intent) {50         // TODO Auto-generated method stub51         return null;52     }53 54 }

其中:

  1. 在onCreate()中取到在BMapApiDemoApp里定义的BMapManager对象,并检查是否存在,不存在就初始化一个;
  2. 在onStartCommand()中注册LocationListener并调用BMapManager的start函数;
  3. LocationListener是在onCreate()中定义的,mMKSearch.reverseGeocode()传入GeoPoint对象,搜索之后的返回值通过GeoCoderParser类取到;当得到Location信息之后我调用了removeUpdates和stop函数停止请求更新。
1 GeoPoint point = new GeoPoint((int)(location.getLatitude() * 1E6), (int)(location.getLongitude() * 1E6));2 mMKSearch.reverseGeocode(point);3                     4 app.mBMapMan.getLocationManager().removeUpdates(mLocationListener);5 app.mBMapMan.stop();

代码最后执行的时候有一个小bug就是removeUpdate()貌似被执行了两次,没有详细追究,不知道是什么原因。不过也无伤大雅。

GeoCoderParser

最后就是用于接收MKSearch.reverseGeocode()结果的类。

这个类的实现了MKSearchListener接口,接口的函数比较多,但是我们这里只关注onGetAddrResult(MKAddrInfo arg0, int arg1)函数。这个函数有两个参数:

  1. arg1是错误码,搜索失败的时候通过错误码得到失败原因;
  2. arg0是传入的地址信息,它是一个MKAddrInfo对象,对象有个字段是addressComponents,这个字段保存了从省、市一直到门牌号的信息。
 1 public class GeoCoderParser implements MKSearchListener { 2  3     private static final String TAG = "GeoCoderParser"; 4  5     @Override 6     public void onGetAddrResult(MKAddrInfo arg0, int arg1) { 7         if (arg1 != 0) { 8             String str = String.format("%d", arg1); 9             Log.d(TAG, str);10             return;11         }12         MKGeocoderAddressComponent address = arg0.addressComponents;13         Log.d(TAG, "Location info:" + address.province + address.city + address.district);14     }15 16     //other functions17 18 }

总结

程序的流程大致就是这样,我也是初学,如果哪里写错了欢迎批评指正。

最后给出项目代码的链接:http://files.cnblogs.com/wangfenjin/BaiduMapService.zip 。我没找到博客园哪里可以传附件,所以是通过“文件”那个标签上传的,不知道你们可不可以下载。

项目代码没什么特殊的地方,主要注意一下Manifest文件里面请求相应的权限和注册Service就行了。

更多相关文章

  1. C语言函数的递归(上)
  2. Android(安卓)Binder机制学习笔记之一
  3. Android(安卓)代码混淆技术总结
  4. Android(安卓)GreenDao实现CRUD和升级详解
  5. Android-如何在代码中获取attr属性的值
  6. Android(安卓)Intent机制实例详解
  7. Android(安卓)判断网络状态,并且在没有网络的时候,打开网络设置对
  8. JNI 数据类型转换
  9. Android(安卓)电话系统rild分析

随机推荐

  1. Android短信管家(确认需求)1
  2. 关于android版本spice协议tls端口链接方
  3. 框架设计之ADO.NET Command的ExecuteScal
  4. 使用HBuilder打包Android和iOS,并上线
  5. Android(安卓)程序读写Office文件
  6. android上面遇到的一些内存泄露问题
  7. 金三银四热潮下。Android高级工程师面试
  8. Android(安卓)适配器教程 (六)
  9. (讲课篇)让小白都能明白的Android开发-1.
  10. Android通用标题栏组合控件