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

2016-01-28 16:23 评论 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.     }  

当前文章价值8.08元,扫一扫支付后添加微信提供帮助!(如不能解决您的问题,可以申请退款)

你可能感兴趣的文章

来源:每日教程每日一例,深入学习实用技术教程,关注公众号TeachCourse
转载请注明出处: https://www.teachcourse.cn/1346.html ,谢谢支持!

资源分享

生活杂谈之万网域名注册过程详解 生活杂谈之万网域名注册过程详解
Android常用基本控件 Android常用基本控件
为什么Genymotion在Window10运行不了? 为什么Genymotion在Window10运
浅谈DMS 浅谈DMS

发表评论

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

表情