代码改变世界

Android开发中后台的Service服务探索

2012-07-04 15:42  CloudCraft  阅读(893)  评论(0)    收藏  举报

最近在编写一个基于Android 2.1 的手机应用程序,其中的一个功能是利用Google 的地图API接口实现足迹追踪,整个程序设计大概分为三个部分,UI设计、GoogleMapAPI接口调用以及后台Service所做的数据的采集和传 输以及和服务器的通讯。

Android的UI设计和JAVA、MFC、C#.NET有些不 同,毕竟是手持设备,硬件资源的限制要求它用尽量轻便的代码框架去完成功能,Android的用户界面是用XML来进行布局和管理的,支持直接拖拽,但是 效果并不是很好。它的主活动界面是在main.xml中编写的,在这里可以定义一些按钮啊、文本框什么的。GoogleMapAPI的用法网上有很多教 程,首先要去申请一个KEY,然后才能去调用API得到想要的数据,我们这里要获得GPS的实时数据,所以要用到 LocationListeninger 和 LocationManager 两个类,绘制地图可以调用Mapview类,里面有很多操作地图的方法,类似放大缩小、拖拽描点等都可以调用函数直接实现。

主要来说一下后台服务的编写吧,在Android中Service是 用来进行后台数据处理的东西,类似于Linux下的后台进程,就是当前活动创建的Service在这个活动窗口退出后Service还是继续运行的,我们 要对用户的行动进行跟踪,就要长时间采集GPS发送过来的地理位置信息,这样的东西写成一个Service再合适不过了。自己编写的Service要继承 系统的Service类,然后Override其中的方法。

  1. package server.track;  
  2.   
  3. import java.util.Calendar;  
  4. import android.app.Service;  
  5. import android.content.Context;  
  6. import android.content.Intent;  
  7. import android.location.Location;  
  8. import android.location.LocationListener;  
  9. import android.location.LocationManager;  
  10. import android.os.Bundle;  
  11. import android.os.IBinder;  
  12. import android.util.Log;  
  13. import android.widget.Toast;  
  14.   
  15. public class Track extends Service {  
  16.     private static final String TAG = "Track";  
  17.   
  18.     private LocationManager lm;  
  19.     private LocationListener locationListener;  
  20.     final SDRW filerecord = new SDRW();  
  21.     private String record ;  
  22.     private String length;  
  23.     private int headposition;  
  24.     @Override  
  25.     public IBinder onBind(Intent arg0) {  
  26. //      Log.d(TAG, "onBind.");  
  27.         return null;  
  28.     }  
  29.       
  30.     public void onStart(Intent intent, int startId) {    
  31.         Log.d(TAG, "onStart.");  
  32.         Toast.makeText(getApplicationContext(), "启动服务",Toast.LENGTH_SHORT).show();  
  33.         super.onStart(intent, startId);  
  34. //        startDb();  
  35. //      Bundle extras = intent.getExtras();  
  36. //      if (extras != null) {  
  37. //          track_id = extras.getInt(LocateDbAdapter.TRACKID);  
  38. //      }  
  39. //      Log.d(TAG, "track_id =" + track_id);  
  40.         // ---use the LocationManager class to obtain GPS locations---  
  41.         Calendar calendar = Calendar.getInstance();  
  42.         headposition = 5;  
  43.         record = "head:                                                                                 \r\n";  
  44.         filerecord.write(record);  
  45.         record = "user:"+"Yastand\r\n"+"date:"+calendar.get(Calendar.YEAR) + "-" +calendar.get(Calendar.MONTH) + "-" +  calendar.get(Calendar.DAY_OF_MONTH) + " "  
  46.         + calendar.get(Calendar.HOUR_OF_DAY) + ":"  
  47.         + calendar.get(Calendar.MINUTE) + ":"  + calendar.get(Calendar.SECOND)+"\r\n";  
  48.         filerecord.write(record);  
  49.         length = String.valueOf(record.length())+" ";  
  50.         filerecord.writehead(length,headposition);  
  51.         headposition += length.length();  
  52.         lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE);  
  53.         locationListener = new MyLocationListener();  
  54.         lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 00,locationListener);  
  55.     }  
  56.       
  57.       
  58.   
  59.     public void onDestroy() {  
  60.         Toast.makeText(this"service done", Toast.LENGTH_SHORT).show();  
  61.         super.onDestroy();  
  62.         lm.removeUpdates(locationListener);  
  63. //        stopService(new Intent("Context.LOCATION_SERVICE"));  
  64.         stopSelf();  
  65.     }  
  66.   
  67.     protected class MyLocationListener implements LocationListener {  
  68.   
  69.         @Override  
  70.         public void onLocationChanged(Location loc) {  
  71.             Log.d(TAG, "MyLocationListener::onLocationChanged..");  
  72. /*          if (loc != null) { 
  73.                 // ////////// 
  74.                 if(mlcDbHelper == null){ 
  75.                     mlcDbHelper.open(); 
  76.                 } 
  77.                 mlcDbHelper.createLocate(track_id,  loc.getLongitude(),loc.getLatitude(), loc.getAltitude()); 
  78.             } 
  79.             */  
  80.             record = "GPS:"+" lon:"+String.valueOf(loc.getLongitude())+" lat:"+String.valueOf(loc.getLatitude())+" alt:"+String.valueOf(loc.getAltitude())+"\r\n";  
  81.             if (loc != null)  
  82.             {  
  83.             //  filepoint.write(edit1.getText().toString());   
  84.                 filerecord.write(record);  
  85.             }  
  86.         }  
  87.   
  88.   
  89.         @Override  
  90.         public void onProviderDisabled(String provider) {  
  91.             Toast.makeText(  
  92.                     getBaseContext(),  
  93.                     "ProviderDisabled.",  
  94.                     Toast.LENGTH_SHORT).show();     }  
  95.   
  96.         @Override  
  97.         public void onProviderEnabled(String provider) {  
  98.             Toast.makeText(  
  99.                     getBaseContext(),  
  100.                     "ProviderEnabled,provider:"+provider,  
  101.                     Toast.LENGTH_SHORT).show();     }  
  102.   
  103.         @Override  
  104.         public void onStatusChanged(String provider, int status, Bundle extras) {  
  105.             // TODO Auto-generated method stub  
  106.         }  
  107.     }  
  108.   
  109.       
  110. }  

要开启这个Service可以用

  1. Intent i = new Intent("server.track.START_TRACK_SERVICE");  
  2.                 startService(i);  

执行这句话后,Service类首先去找Create函数,再运行Onstart函数,一个Service就成功的运行了,但是退出当前程序这个操作对这个后台运行的Service并没有什么影响,那么怎样结束这个Service呢?可以这样

  1. stopService(new Intent("server.track.START_TRACK_SERVICE"));  

执 行这句话,系统就会调用Service实例的onDestroy()函数,到这里本以为万事大吉了,结果发现调用stopService之后GPS发送回 来的数据还是源源不断的写入到文件中,原来在onDestroy()函数中必须显示的把Service实例中调用的线程都结束之后才能停止,在我们的 Service中调用的LocationLinstener是这问题的关键,必须在onDestroy()中结束它运行的线程

  1.  public void onDestroy() {  
  2.         Toast.makeText(this"service done", Toast.LENGTH_SHORT).show();  
  3.         super.onDestroy();  
  4.         lm.removeUpdates(locationListener);  
  5. //        stopService(new Intent("Context.LOCATION_SERVICE"));  
  6.         stopSelf();  
  7.     }  

ok了,调用这个函数之后后台运行的Service就自己终止了。