游子的博客
慈母手中线,游子身上衣, 临行密密缝,意恐迟迟归, 谁言寸草心,报得三春晖。 数据读取中,请稍候......
posts - 337,  comments - 546,  trackbacks - 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就自己终止了。


Android SERVICE后台服务进程的自启动和保持

 
Service组件在android开发中经常遇到,其经常作为后台服务,需要始终保持运行,负责处理一些必要(见不得人)的任务。而一些安全软件,如360等,会有结束进程的功能,如果不做Service的保持,就会被其杀掉。

如何保持Service的运行状态是现在要说明的,核心就是利用ANDROID的系统广播,这一不会被其他软件影响的常驻程序触发自己的程序检查Service的运行状态,如果被杀掉,就再起来。

我利用的系统广播是Intent.ACTION_TIME_TICK,这个广播每分钟发送一次,我们可以每分钟检查一次Service的运行状态,如果已经被结束了,就重新启动Service。

下边就是具体的代码和注意事项了:

1、 Intent.ACTION_TIME_TICK的使用

我们知道广播的注册有静态注册和动态注册,但此系统广播只能通过动态注册的方式使用。即你不能通过在manifest.xml里注册的方式接收到这个广播,只能在代码里通过registerReceiver()方法注册。

在ThisApp extends Application 里注册广播:

  1. IntentFilter filter = newIntentFilter(Intent.ACTION_TIME_TICK); 
  2. MyBroadcastReceiver receiver = new MyBroadcastReceiver(); 
  3. registerReceiver(receiver, filter); 

在广播接收器MyBroadcastReceiver extends BroadcastReceiver的onReceive里

  1. if (intent.getAction().equals(Intent.ACTION_TIME_TICK)) { 
  2.   
  3. //检查Service状态 
  4.   

2、Service的检查与启动

  1. boolean isServiceRunning = false
  2. ActivityManager manager = (ActivityManager)ThisApp.getContext().getSystemService(Context.ACTIVITY_SERVICE); 
  3. for (RunningServiceInfo service :manager.getRunningServices(Integer.MAX_VALUE)) { 
  4. if("so.xxxx.WidgetUpdateService".equals(service.service.getClassName())) 
  5.        //Service的类名 
  6. isServiceRunning = true
  7.   
  8.  } 
  9. if (!isServiceRunning) { 
  10. Intent i = new Intent(context, WidgetUpdateService.class); 
  11.        context.startService(i); 

另一个话题,Service的开机启动。

实现和上边的类似,也是通过监控开机的系统广播来启动Service。但其实你做了上边的检查也就不会做开机启动了,因为过一两分钟就会通过上边的程序启动Service了。代码如下:

  1. if (intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED)) { 
  2. Intent i = new Intent(context, LogService.class); 
  3.     context.startService(i); 
  4.     
posted on 2015-01-26 11:41 游子 阅读(1541) 评论(0)  编辑 收藏 引用 所属分类: 软件
只有注册用户登录后才能发表评论。

欢迎大家扔鸡蛋!送鲜花!

博客可以收入过千吗?

<2015年1月>
日一二三四五六28293031123456789101112
131415161718192021222324252627282930311234567

常用链接

留言簿(8)

随笔分类(314)

随笔档案(337)

文章分类(7)

文章档案(10)

相册

收藏夹(1)

其它

友情链接

数字电视

生活、旅游

自己的链接

计算机

搜索

  •  

积分与排名

  • 积分 - 407922
  • 排名 - 9

最新评论

阅读排行榜

评论排行榜