Android开发Service BroadcastReceiver Handler获取当前位置

2016-01-28 16:23 阅读 9,664 次 评论 0 条

概要

现在有这么一个需求:开启一个Service服务,获取当前位置的经纬度数据,将获取的数据以广播的方式发送出去,注册广播的Activity接收广播信息,并将接收到的数据在当前Activity显示,如果当前位置发生变化,经纬度数据改变,获取改变后的经纬度数据,通过Handler发送消息,更新UI界面,显示更新后的内容,请问这样子的Demo该如何实现?

001-LocationManagerDemo

LocationTool获取当前位置信息

Android手机获取当前位置的方式:GPS定位,WIFI定位,基站定位,当前Demo使用GPS卫星定位,在LocationTool中返回Location、LocationManager两者对象,通过Location提供的getLatitude()、getLongitude()读取经纬度数据,同时添加位置改变监听器MyLocationListener,具体代码如下:

  1. package cn.teachcourse.utils;  
  2.   
  3. import android.app.Activity;  
  4. import android.content.Context;  
  5. import android.content.Intent;  
  6. import android.location.Criteria;  
  7. import android.location.Location;  
  8. import android.location.LocationListener;  
  9. import android.location.LocationManager;  
  10. import android.os.Bundle;  
  11. import android.provider.Settings;  
  12. import android.widget.Toast;  
  13.   
  14. /* 
  15.  @author postmaster@teachcourse.cn 
  16.  @date 创建于:2016-1-22 
  17.  */  
  18. public class LocationTool {  
  19.     public Location getLocation() {  
  20.         return mLocation;  
  21.     }  
  22.   
  23.     public void setLocation(Location location) {  
  24.         this.mLocation = location;  
  25.     }  
  26.   
  27.     private Context context;  
  28.     private Location mLocation;  
  29.     private LocationManager mLocationManager;  
  30.   
  31.     public LocationTool(Context context) {  
  32.         super();  
  33.   
  34.         mLocationManager = (LocationManager) context  
  35.                 .getSystemService(Context.LOCATION_SERVICE);  
  36.         mLocation = mLocationManager.getLastKnownLocation(getProvider());  
  37.           
  38.         mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,  
  39.                 200010new MyLocationListener(this));  
  40.     }  
  41.   
  42.     // 获取Location Provider  
  43.     private String getProvider() {  
  44.         // 构建位置查询条件  
  45.         Criteria criteria = new Criteria();  
  46.         // 查询精度:高  
  47.         criteria.setAccuracy(Criteria.ACCURACY_FINE);  
  48.         // 是否查询海拨:否  
  49.         criteria.setAltitudeRequired(false);  
  50.         // 是否查询方位角 : 否  
  51.         criteria.setBearingRequired(false);  
  52.         // 是否允许付费:是  
  53.         criteria.setCostAllowed(true);  
  54.         // 电量要求:低  
  55.         criteria.setPowerRequirement(Criteria.POWER_LOW);  
  56.         // 返回最合适的符合条件的provider,第2个参数为true说明 , 如果只有一个provider是有效的,则返回当前provider  
  57.         return mLocationManager.getBestProvider(criteria, true);  
  58.     }  
  59.   
  60.   
  61.   
  62.     public LocationManager getLocationManager() {  
  63.   
  64.         return mLocationManager;  
  65.     }  
  66.   
  67.     private LocationListener mLocationListener = new LocationListener() {  
  68.   
  69.         @Override  
  70.         public void onStatusChanged(String provider, int status, Bundle extras) {  
  71.             // TODO Auto-generated method stub  
  72.   
  73.         }  
  74.   
  75.         @Override  
  76.         public void onProviderEnabled(String provider) {  
  77.             Location l = mLocationManager.getLastKnownLocation(provider);  
  78.               
  79.             if (l != null) {  
  80.                 mLocation = l;  
  81.             }  
  82.               
  83.         }  
  84.   
  85.         @Override  
  86.         public void onProviderDisabled(String provider) {  
  87.             mLocation = null;  
  88.         }  
  89.   
  90.         @Override  
  91.         public void onLocationChanged(Location location) {  
  92.             if (location != null) {  
  93.                 mLocation = location;  
  94.             }  
  95.   
  96.         }  
  97.     };  
  98.   
  99.     public void closeLocation() {  
  100.         if (mLocationManager != null) {  
  101.             if (mLocationManager != null) {  
  102.                 mLocationManager.removeUpdates(mLocationListener);  
  103.                 mLocationListener = null;  
  104.             }  
  105.             mLocationManager = null;  
  106.         }  
  107.     }  
  108. }  

MyLocationListener位置改变监听器

LocationManager对象调用requestLocationUpdates(String provider, long minTime, float minDistance,LocationListener listener),在回调的方法中获取改变后的Location对象,其中provider表示LocationManager.GPS_PROVIDER,minTime表示最短时间间隔内更新位置信息(单位毫秒),minDistance表示最短距离内更新位置信息(单位米),MyLocationListener继承LocationListener,需要重写的方法如下:

  1. package cn.teachcourse.utils;  
  2.   
  3. import android.location.Location;  
  4. import android.location.LocationListener;  
  5. import android.os.Bundle;  
  6.   
  7. /* 
  8.  @author postmaster@teachcourse.cn 
  9.  @date 创建于:2016-1-22 
  10.  */  
  11.   
  12. public class MyLocationListener implements LocationListener {  
  13.   
  14.     private LocationTool gpsTool;  
  15.   
  16.     /**构造方法,传入LocationTool 
  17.      * @param gpsTool  
  18.      */  
  19.     public MyLocationListener(LocationTool gpsTool) {  
  20.         super();  
  21.         this.gpsTool = gpsTool;  
  22.     }  
  23.   
  24.     /** 
  25.      * 当前位置改变后,回调onLocationChanged方法,获取改变后的Location对象 
  26.      * 
  27.      */  
  28.     @Override  
  29.     public void onLocationChanged(Location location) {  
  30.         if (location != null) {  
  31.             gpsTool.setLocation(location);  
  32.         }  
  33.   
  34.     }  
  35.   
  36.     /** 
  37.      * 当provider状态改变时回调的方法,当前的provider无法读取位置信息或者provider从无法读取位置信息变为能够读取为信息被回调的方法 
  38.      * 
  39.      */  
  40.     @Override  
  41.     public void onStatusChanged(String provider, int status, Bundle extras) {  
  42.         // TODO Auto-generated method stub  
  43.   
  44.     }  
  45.   
  46.     /** 
  47.      * 当provider被用户允许开启,回调的onProviderEnabled方法,比如:开启定位功能,回调该方法 
  48.      * 
  49.      */  
  50.     @Override  
  51.     public void onProviderEnabled(String provider) {  
  52.         Location l = gpsTool.getLocationManager()  
  53.                 .getLastKnownLocation(provider);  
  54.   
  55.         if (l != null) {  
  56.             gpsTool.setLocation(l);  
  57.         }  
  58.   
  59.     }  
  60.   
  61.     /** 
  62.      * 当provider不被用户允许开启,回调的onProviderDisabled方法,比如:无法开启定位功能,回调该方法 
  63.      * 
  64.      */  
  65.     @Override  
  66.     public void onProviderDisabled(String provider) {  
  67.         gpsTool.setLocation(null);  
  68.   
  69.     }  
  70.   
  71. }  

LocationService服务读取位置信息

为什么要开启Service呢?Service和Activity、Fragment一样也有自己的生命周期,onCreate——>onStartCommand(onStart)——>onUnbind——>onRebind——>onDestroy,在LocationService执行的操作是启动一个线程获取更新后的位置信息,并以广播的方式发送出去,具体代码如下:

  1. package cn.teachcourse.utils;  
  2.   
  3. import android.app.Activity;  
  4. import android.app.Service;  
  5. import android.content.Context;  
  6. import android.content.Intent;  
  7. import android.location.Location;  
  8. import android.location.LocationManager;  
  9. import android.os.IBinder;  
  10. import android.provider.Settings;  
  11. import android.widget.Toast;  
  12.   
  13. /* 
  14.  @author postmaster@teachcourse.cn 
  15.  @date 创建于:2016-1-22 
  16.  */  
  17. public class LocationService extends Service {  
  18.     private LocationTool mGPSTool = null;  
  19.     private boolean threadDisable = false;  
  20.     private final static String TAG = LocationService.class.getSimpleName();  
  21.   
  22.     @Override  
  23.     public void onCreate() {  
  24.         // TODO Auto-generated method stub  
  25.         super.onCreate();  
  26.         mGPSTool = new LocationTool(this);  
  27.         startThread();  
  28.     }  
  29.   
  30.     private void startThread() {  
  31.         new Thread(new Runnable() {  
  32.             @Override  
  33.             public void run() {  
  34.                 while (!threadDisable) {  
  35.                     try {  
  36.                         Thread.sleep(1000);  
  37.                     } catch (InterruptedException e) {  
  38.                         e.printStackTrace();  
  39.                     }  
  40.                     if (mGPSTool != null) { // 当结束服务时gps为空  
  41.                         // 获取经纬度  
  42.                         Location location = mGPSTool.getLocation();  
  43.   
  44.                         // 发送广播  
  45.                         Intent intent = new Intent();  
  46.                         intent.putExtra("lat",  
  47.                                 location == null ? "" : location.getLatitude()  
  48.                                         + "");  
  49.                         intent.putExtra("lon",  
  50.                                 location == null ? "" : location.getLongitude()  
  51.                                         + "");  
  52.                         intent.setAction("cn.teachcourse.utils.GPSService");  
  53.                           
  54.                         sendBroadcast(intent);  
  55.                     }  
  56.   
  57.                 }  
  58.             }  
  59.         }).start();  
  60.     }  
  61.   
  62.     @Override  
  63.     public void onDestroy() {  
  64.         super.onDestroy();  
  65.         threadDisable = true;  
  66.         if (mGPSTool != null) {  
  67.             mGPSTool.closeLocation();  
  68.             mGPSTool = null;  
  69.         }  
  70.     }  
  71.   
  72.     @Override  
  73.     public IBinder onBind(Intent intent) {  
  74.           
  75.         return null;  
  76.     }  
  77.   
  78. }  

MainActivity启动服务、注册广播、显示位置信息

在MainActivity需要做的事情有:第一启动LocationService服务,调用startService()方法;第二注册广播接收器(BroadcastReceiver),创建了一个内部类MyBroadcastReceiver,继承BroadcastReceiver,重写onReceive方法;第三获取经纬度数据,更新UI界面,显示当前位置信息,具体代码如下:

  1. //启动服务  
  2. startService(new Intent(this, LocationService.class));  
  1. //注册广播  
  2. private class MyReceiver extends BroadcastReceiver {  
  3.   
  4.         @Override  
  5.         public void onReceive(Context context, Intent intent) {  
  6.             Bundle bundle = intent.getExtras();  
  7.             String lon = bundle.getString("lon");  
  8.             String lat = bundle.getString("lat");  
  9.             if (!TextUtils.isEmpty(lon) && !TextUtils.isEmpty(lat)) {  
  10.                 mLatitude = lat;  
  11.                 mLongitude = lon;  
  12.                 isObtainLoc = true;  
  13.                   
  14.                 new Thread(new Runnable() {  
  15.                       
  16.                     @Override  
  17.                     public void run() {  
  18.                         Message msg = new Message();  
  19.                         msg.what = REFRESH_UI;// 发送消息,通知刷新界面  
  20.                         mHandler.sendMessage(msg);  
  21.                     }  
  22.                 }).start();  
  23.             }  
  24.         }  
  25.   
  26.     }  
  27.   
  28. //更新UI界面  
  29. private Handler mHandler = new Handler() {  
  30.   
  31.         @Override  
  32.         public void handleMessage(Message msg) {  
  33.             // TODO Auto-generated method stub  
  34.             super.handleMessage(msg);  
  35.             switch (msg.what) {  
  36.             case REFRESH_UI:  
  37.   
  38.                 reFreshUI();  
  39.   
  40.                 break;  
  41.             default:  
  42.                 break;  
  43.             }  
  44.         }  
  45.     };  
  46.   
  47.     private void reFreshUI() {  
  48.         if (isObtainLoc) {  
  49.             mTextView.setText("目前经纬度\n经度:" + mLongitude + "\n纬度:" + mLatitude);  
  50.             mDialog.dismiss();  
  51.         }  
  52.   
  53.     }  
关注公众号 扫一扫二维码,加我QQ

如果文章对你有帮助,欢迎点击上方按钮关注作者

来源:TeachCourse每周一次,深入学习Android教程,关注(QQ158#9359$239或公众号TeachCourse)
转载请注明出处:https://www.teachcourse.cn/1346.html ,谢谢支持!

资源分享

下载demo源码
浅谈DMS 浅谈DMS
Building and Running Overview Building and Running Overvi
Conversion to Dalvik format failed Conversion to Dalvik format
Android开发之Genymotion安装第三方软件的“APP not installed”问题 Android开发之Genymotion安装第

发表评论

呲牙 憨笑 坏笑 偷笑 色 微笑 抓狂 睡觉 酷 流汗 鼓掌 大哭 可怜 疑问 晕 惊讶 得意 尴尬 发怒 奋斗 衰 骷髅 啤酒 吃饭 礼物 强 弱 握手 OK NO 勾引 拳头 差劲 爱你

表情