zoukankan      html  css  js  c++  java
  • Android通过百度地图API用Service和Alarm在后台定时获取地理位置信息

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

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

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

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

     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         @Override
    14         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         @Override
    21         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     @Override
    33     public void onCreate() {
    34         mDemoApp = this;
    35         mBMapMan = new BMapManager(this);
    36         boolean isSuccess = mBMapMan
    37                 .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_REALTIME
    54             , SystemClock.elapsedRealtime()
    55             , 10 * 1000
    56             , collectSender);
    57     }
    58     
    59     @Override
    60     public void onTerminate() {
    61         // TODO Auto-generated method stub
    62         if (mBMapMan != null) {
    63             mBMapMan.destroy();
    64             mBMapMan = null;
    65         }
    66         super.onTerminate();
    67     }
    68 
    69 }

    主要关注如下几点:

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

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

    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             @Override
    23             public void onLocationChanged(Location location) {
    24                 Log.d(TAG, "location change");
    25                 if (location != null) {
    26                     String strLog = String.format("经度:%f
    " + "纬度:%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     @Override
    41     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     @Override
    49     public IBinder onBind(Intent intent) {
    50         // TODO Auto-generated method stub
    51         return null;
    52     }
    53 
    54 }

    其中:

    在onCreate()中取到在BMapApiDemoApp里定义的BMapManager对象,并检查是否存在,不存在就初始化一个; 在onStartCommand()中注册LocationListener并调用BMapManager的start函数; 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)函数。这个函数有两个参数:

    arg1是错误码,搜索失败的时候通过错误码得到失败原因; 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 functions
    17 
    18 }

    总结

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

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

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

  • 相关阅读:
    POI2014 洛谷P3574 FarmCraft 题解
    JZOJ 3468 OSU!题解
    sublime配置C++编译环境
    本地配置gitee
    数论基础
    HDU
    HDU-3033 I love sneakers! 题解
    HDU-4341 Gold miner 题解
    HDU
    MyBatis框架及原理分析
  • 原文地址:https://www.cnblogs.com/zhujiabin/p/7592995.html
Copyright © 2011-2022 走看看