Android定时广播和定时服务两种实现方式

几种方式的对面及介绍看这里

http://blog.csdn.net/u014492609/article/details/51475254


自己写了个Demo来实现定时发送广播和定时执行服务




地址https://github.com/wds1181977/TimerBroadcastReceiver-Service.git


[java]  view plain  copy
  1. package com.example.h2;  
  2.   
  3. import android.app.Activity;  
  4. import android.app.AlarmManager;  
  5. import android.app.PendingIntent;  
  6. import android.content.BroadcastReceiver;  
  7. import android.content.ComponentName;  
  8. import android.content.Context;  
  9. import android.content.Intent;  
  10. import android.content.IntentFilter;  
  11. import android.content.ServiceConnection;  
  12. import android.os.Bundle;  
  13. import android.os.Handler;  
  14. import android.os.IBinder;  
  15. import android.os.SystemClock;  
  16. import android.text.TextUtils;  
  17. import android.util.Log;  
  18. import android.view.View;  
  19. import android.view.View.OnClickListener;  
  20. import android.widget.Button;  
  21. import android.widget.TextView;  
  22. import android.widget.Toast;  
  23.   
  24. public class MainActivity extends Activity {  
  25.   
  26.     // private TimerService mTimerService;  
  27.     private final String MESSAGE = "message";// 时间到后接受消息  
  28.     private Context mContext;  
  29.     private TextView tv, tv2;  
  30.     private Button bt1, bt2, bt3, bt4, bt5, bt6,bt7;  
  31.     private final int Time = 5 * 1000;// 约定每隔5秒执行一次  
  32.     private boolean isHanderType = false;  
  33.     private static final String ACTION_NAME = "android.intent.action.alarm.timer";// 广播名称  
  34.     private static final String ACTION_NAME2 = "android.intent.action.handler.timer";// 广播名称  
  35.     private int countHandler = 1;// handler发送次数计数  
  36.     private int countAlarm = 0;// alarm发送次数计数  
  37.     // Handler方式发送  
  38.     Handler handler = new Handler();  
  39.     Runnable runnable = new Runnable() {  
  40.         @Override  
  41.         public void run() {  
  42.             // TODO Auto-generated method stub  
  43.   
  44.             handler.postDelayed(runnable, Time);  
  45.   
  46.             Intent mIntent = new Intent(ACTION_NAME2);  
  47.   
  48.             // 发送广播  
  49.             mIntent.putExtra(MESSAGE, "第" + countHandler + "次"  
  50.                     + "Handler方式发送过来的广播,  我将带头冲锋" + countHandler + "次");  
  51.   
  52.             sendBroadcast(mIntent);  
  53.   
  54.         }  
  55.     };  
  56.   
  57.     Runnable runnable2 = new Runnable() {  
  58.         @Override  
  59.         public void run() {  
  60.             // TODO Auto-generated method stub  
  61.             Intent intent = new Intent(mContext, TimerService.class);  
  62.             startService(intent);  
  63.             handler.postDelayed(runnable2, Time);  
  64.   
  65.         }  
  66.     };  
  67.   
  68.     private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {  
  69.         @Override  
  70.         public void onReceive(Context context, Intent intent) {  
  71.             String action = intent.getAction();  
  72.             String message = intent.getStringExtra(MESSAGE);  
  73.   
  74.             if (action.equals(ACTION_NAME)) {  
  75.   
  76.                 tv.setText("第" + countAlarm + "次"  
  77.                         + "AlarmManager方式发送过来的广播,  是时候表演真正的第" + countAlarm  
  78.                         + "次技术了");  
  79.   
  80.                 tv2.setText("和Handler广播不一样,Alarm是首先执行一次,五秒后在在执行第二次,并且发送时只执行一次");  
  81.                 // Toast.makeText(MainActivity.this, message+countAlarm,  
  82.                 // 0).show();  
  83.                 countAlarm++;  
  84.             } else if (action.equals(ACTION_NAME2)) {  
  85.   
  86.                 if (!TextUtils.isEmpty(message)) {  
  87.                     tv2.setText(message);  
  88.                 }  
  89.   
  90.                 countHandler++;  
  91.   
  92.             }  
  93.   
  94.         }  
  95.   
  96.     };  
  97.   
  98.     // ServiceConnection conn = new ServiceConnection() {  
  99.     // @Override  
  100.     // public void onServiceDisconnected(ComponentName name) {  
  101.     //  
  102.     // }  
  103.     //  
  104.     // @Override  
  105.     // public void onServiceConnected(ComponentName name, IBinder service) {  
  106.     // // TODO Auto-generated method stub  
  107.     // mTimerService = ((TimerService.MsgBinder)service).getService();  
  108.     // tv.setText(mTimerService.getMessage());  
  109.     //  
  110.     //  
  111.     // }  
  112.     //  
  113.     //  
  114.     //  
  115.     //  
  116.     // };  
  117.   
  118.     @Override  
  119.     protected void onResume() {  
  120.         // TODO Auto-generated method stub  
  121.         super.onResume();  
  122.         // 注册广播  
  123.         registerBoradcastReceiver();  
  124.   
  125.     }  
  126.   
  127.     @Override  
  128.     protected void onCreate(Bundle savedInstanceState) {  
  129.         super.onCreate(savedInstanceState);  
  130.   
  131.         setContentView(R.layout.activity_main);  
  132.         mContext = MainActivity.this;  
  133.         tv = (TextView) findViewById(R.id.textView1);  
  134.         tv2 = (TextView) findViewById(R.id.textView2);  
  135.         bt1 = (Button) findViewById(R.id.button1);  
  136.         bt2 = (Button) findViewById(R.id.button2);  
  137.   
  138.         bt3 = (Button) findViewById(R.id.button3);  
  139.         bt4 = (Button) findViewById(R.id.button4);  
  140.         bt5 = (Button) findViewById(R.id.button5);  
  141.   
  142.         bt6 = (Button) findViewById(R.id.button6);  
  143.   
  144.         bt7 = (Button) findViewById(R.id.button7);  
  145.         bt1.setOnClickListener(onClickListener);  
  146.         bt2.setOnClickListener(onClickListener);  
  147.         bt3.setOnClickListener(onClickListener);  
  148.         bt4.setOnClickListener(onClickListener);  
  149.         bt5.setOnClickListener(onClickListener);  
  150.         bt6.setOnClickListener(onClickListener);  
  151.         bt7.setOnClickListener(onClickListener);  
  152.   
  153.     }  
  154.   
  155.     View.OnClickListener onClickListener = new OnClickListener() {  
  156.   
  157.         @Override  
  158.         public void onClick(View v) {  
  159.             // TODO Auto-generated method stub  
  160.             switch (v.getId()) {  
  161.             case R.id.button1:  
  162.                 sendTimerBoaadCastReceiver(true,-1);  
  163.                 bt1.setEnabled(false);  
  164.                 break;  
  165.             case R.id.button2:  
  166.                 sendTimerBoaadCastReceiver(false,2);  
  167.                 bt2.setEnabled(false);  
  168.                 break;  
  169.             case R.id.button3:  
  170.                 sendTimerService(true);  
  171.                 bt3.setEnabled(false);  
  172.                 break;  
  173.             case R.id.button4:  
  174.                 sendTimerService(false);  
  175.                 bt4.setEnabled(false);  
  176.                 break;  
  177.             case R.id.button5:  
  178.                 cancelAlLBR();  
  179.                 break;  
  180.             case R.id.button6:  
  181.                 cancelAlLService();  
  182.                 break;  
  183.             case R.id.button7:  
  184.                 sendTimerBoaadCastReceiver(false,1);  
  185.                 bt7.setEnabled(false);  
  186.                 break;  
  187.   
  188.             }  
  189.   
  190.         }  
  191.     };  
  192.   
  193.     // 注册广播  
  194.   
  195.     private void registerBoradcastReceiver() {  
  196.   
  197.         IntentFilter myIntentFilter = new IntentFilter();  
  198.         myIntentFilter.addAction(ACTION_NAME);  
  199.         myIntentFilter.addAction(ACTION_NAME2);  
  200.   
  201.         // 注册广播  
  202.         registerReceiver(mBroadcastReceiver, myIntentFilter);  
  203.   
  204.     }  
  205.   
  206.     // 发送定时广播  
  207.   
  208.     /** 
  209.      * android提供了四种类型的闹钟: ELAPSED_REALTIME 在指定的延时过后,发送广播,但不唤醒设备。 
  210.      *  
  211.      * ELAPSED_REALTIME_WAKEUP 
  212.      * 在指定的演示后,发送广播,并唤醒设备延时是要把系统启动的时间SystemClock. 
  213.      * elapsedRealtime()算进去的,具体用法看代码。 
  214.      *  
  215.      *  
  216.      * RTC 在指定的时刻,发送广播,但不唤醒设备 
  217.      *  
  218.      * RTC_WAKEUP 在指定的时刻,发送广播,并唤醒设备 
  219.      *  
  220.      *  
  221.      * AlarmManager提供的方法: void set(int type, long 
  222.      * triggerAtTime,PendingIntent operation) 设置一个闹钟 
  223.      *  
  224.      *  
  225.      * void setRepeating(int type, long triggerAtTime, long 
  226.      * interval,PendingIntent operation) 设置一个会重复的闹钟 
  227.      *  
  228.      *  
  229.      * void setInexactRepeating(int type, long triggerAtTime, 
  230.      * longinterval, PendingIntent operation) 
  231.      *  
  232.      *  
  233.      *  
  234.      *  
  235.      *  
  236.      *  
  237.      */  
  238.     private void sendTimerBoaadCastReceiver(boolean isHandler, int state) {  
  239.         if (isHandler) {  
  240.             // Handler方式  
  241.             handler.postDelayed(runnable, Time);// 每Time秒执行一次runnable.  
  242.         } else {  
  243.   
  244.             Intent mIntent = new Intent(ACTION_NAME);  
  245.             // 发送广播  
  246.   
  247.             // 和Handler定时广播不同这里只执行一次,执行多次的是接受到广播消息,所以这里没用  
  248.             // mIntent.putExtra(MESSAGE,  
  249.             // "第"+countAlarm+"次"+"AlarmManager方式发送过来的广播,  是时候表演真正的第"+countAlarm+"次技术了");  
  250.             Toast.makeText(MainActivity.this"发送Alarm广播,全军出击"0).show();  
  251.             // AlarmManager方式发送广播  
  252.             sendBroadcast(mIntent);  
  253.             // 触发服务的起始时间 这里是// 5秒后发送广播,只发送一次  
  254.   
  255.             PendingIntent pendIntent = PendingIntent.getBroadcast(mContext, 0,  
  256.                     mIntent, PendingIntent.FLAG_UPDATE_CURRENT);  
  257.   
  258.             // 进行闹铃注册  
  259.             AlarmManager manager = (AlarmManager) getSystemService(ALARM_SERVICE);  
  260.   
  261.   
  262.             switch (state) {  
  263.   
  264.             case 1:  
  265.                 /** 
  266.                  * 5秒后发送广播,只发送一次 elapsedRealtime() and elapsedRealtimeNanos() 
  267.                  * 返回系统启动到现在的时间,包含设备深度休眠的时间。该时钟被保证是单调的, 
  268.                  * 即使CPU在省电模式下,该时间也会继续计时。该时钟可以被使用在当测量时间间隔可能跨越系统睡眠的时间段。 
  269.                  *  
  270.                  */  
  271.                 long triggerAtTime = SystemClock.elapsedRealtime() + Time;  
  272.                 manager.set(AlarmManager.ELAPSED_REALTIME, triggerAtTime,  
  273.                         pendIntent);  
  274.                 break;  
  275.             case 2:  
  276.                 // 每隔5秒重复发广播  
  277.                 manager.setInexactRepeating(  
  278.                         AlarmManager.ELAPSED_REALTIME_WAKEUP,  
  279.                         SystemClock.elapsedRealtime(), Time, pendIntent);  
  280.                 break;  
  281.             case 3:  
  282.                 break;  
  283.             case 4:  
  284.                 break;  
  285.   
  286.             }  
  287.   
  288.         }  
  289.   
  290.     }  
  291.   
  292.     // 取消Handler广播  
  293.     private void cancelHandlerBR() {  
  294.   
  295.         handler.removeCallbacks(runnable);  
  296.         countHandler = 1;  
  297.         tv2.setText("敌军还有5秒到达战场,碾碎他们");  
  298.   
  299.     }  
  300.   
  301.     // 取消Alarm广播  
  302.     private void cancelAlarmManagerBR() {  
  303.         Intent mIntent = new Intent(ACTION_NAME);  
  304.   
  305.         PendingIntent pendIntent = PendingIntent.getBroadcast(mContext, 0,  
  306.                 mIntent, 0);  
  307.         // 与上面的intent匹配(filterEquals(intent))的闹钟会被取消  
  308.   
  309.         // 进行闹铃取消  
  310.         AlarmManager manager = (AlarmManager) getSystemService(ALARM_SERVICE);  
  311.         manager.cancel(pendIntent);  
  312.   
  313.         countAlarm = 0;  
  314.         tv.setText("敌军还有5秒到达战场,碾碎他们");  
  315.   
  316.     }  
  317.   
  318.     private void cancelAlLBR() {  
  319.   
  320.         cancelHandlerBR();  
  321.         cancelAlarmManagerBR();  
  322.         bt1.setEnabled(true);  
  323.         bt2.setEnabled(true);  
  324.         bt7.setEnabled(true);  
  325.   
  326.     }  
  327.   
  328.     private void cancelAlLService() {  
  329.         handler.removeCallbacks(runnable2);  
  330.         ServiceUtil.cancleAMServicer(mContext);  
  331.         ServiceUtil.stopHandlerService(mContext);  
  332.   
  333.         bt3.setEnabled(true);  
  334.         bt4.setEnabled(true);  
  335.         bt6.setEnabled(true);  
  336.       
  337.         tv.setText("敌军还有5秒到达战场,碾碎他们");  
  338.         tv2.setText("敌军还有5秒到达战场,碾碎他们");  
  339.   
  340.     }  
  341.   
  342.     // 发送定时服务  
  343.   
  344.     private void sendTimerService(boolean isHandler) {  
  345.   
  346.         if (isHandler) {  
  347.             handler.postDelayed(runnable2, Time);// 每Time秒执行一次runnable.  
  348.   
  349.         } else {  
  350.             ServiceUtil.startAMService(mContext);  
  351.   
  352.         }  
  353.   
  354.     }  
  355.   
  356.     @Override  
  357.     protected void onDestroy() {  
  358.         // TODO Auto-generated method stub  
  359.         super.onDestroy();  
  360.         cancelAlLBR();  
  361.         cancelAlLService();  
  362.         // unbindService(conn);  
  363.         unregisterReceiver(mBroadcastReceiver);  
  364.     }  
  365.   
  366.     @Override  
  367.     protected void onPause() {  
  368.         // TODO Auto-generated method stub  
  369.         super.onPause();  
  370.   
  371.     }  
  372.   
  373. }  


服务类


[java]  view plain  copy
  1. package com.example.h2;  
  2.   
  3. import android.app.Service;  
  4. import android.content.Intent;  
  5. import android.os.Binder;  
  6. import android.os.IBinder;  
  7. import android.util.Log;  
  8. import android.widget.Toast;  
  9.   
  10.   
  11. /** 
  12.  * Created by coder80 on 2016/3/31. 
  13.  */  
  14. public class TimerService extends Service{  
  15.     private String TAG = TimerService.class.getSimpleName();  
  16.   
  17.     String message;  
  18.     int count=1;  
  19.   
  20.       
  21.     @Override  
  22.     public void onCreate() {  
  23.         super.onCreate();  
  24.         sendMessage();  
  25.     }  
  26.       
  27.     @Override  
  28.     public void onDestroy() {  
  29.         super.onDestroy();  
  30.         count=1;  
  31.         Log.i(TAG, "UploadPOIService onDestroy here.... ");  
  32.     }  
  33.   
  34.     private void sendMessage() {  
  35.         //simulation HTTP request to server   
  36. //        count++;  
  37. //      message="第"+count+"次"+"执行定时服务, 真是个深思熟虑的选择";  
  38.         Toast.makeText(getApplicationContext(), "执行定时服务, 真是个深思熟虑的选择"0).show();  
  39.         stopSelf();  
  40.     }  
  41.       
  42.     public String  getMessage(){  
  43.           
  44.         return message;  
  45.     }  
  46.   
  47.     @Override  
  48.     public IBinder onBind(Intent intent) {  
  49.         // TODO Auto-generated method stub  
  50.         return null;  
  51.     }  
  52.   
  53. //  /**  
  54. //   * 返回一个Binder对象  
  55. //   */  
  56. //  @Override  
  57. //  public IBinder onBind(Intent intent) {  
  58. //      return new MsgBinder();  
  59. //  }  
  60. //    
  61. //  public class MsgBinder extends Binder{  
  62. //      /**  
  63. //       * 获取当前Service的实例  
  64. //       * @return  
  65. //       */  
  66. //      public TimerService getService(){  
  67. //          return TimerService.this;  
  68. //      }  
  69. //  }  
  70.   
  71.   
  72.   
  73. }  


服务工具类

[java]  view plain  copy
  1. package com.example.h2;  
  2.   
  3. import android.app.Activity;  
  4. import android.app.ActivityManager;  
  5. import android.app.AlarmManager;  
  6. import android.app.PendingIntent;  
  7. import android.content.Context;  
  8. import android.content.Intent;  
  9. import android.util.Log;  
  10.   
  11. import java.util.List;  
  12.   
  13.   
  14. /** 
  15.  * Created by coder80 on 2014/10/31. 
  16.  */  
  17.   
  18. public class ServiceUtil {  
  19.     private final static String ServiceName="com.example.h2.TimerService";  
  20.     public static boolean isServiceRunning(Context context, String className) {  
  21.         boolean isRunning = false;  
  22.           
  23.         ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);  
  24.         List<ActivityManager.RunningServiceInfo> serviceInfos = activityManager.getRunningServices(50);  
  25.   
  26.         if(null == serviceInfos || serviceInfos.size() < 1) {  
  27.             return false;  
  28.         }  
  29.   
  30.         for(int i = 0; i < serviceInfos.size(); i++) {  
  31.             if(serviceInfos.get(i).service.getClassName().contains(className)) {  
  32.                 isRunning = true;  
  33.                 break;  
  34.             }  
  35.         }  
  36.         Log.i("ServiceUtil-AlarmManager", className + " isRunning =  " + isRunning);  
  37.         return isRunning;  
  38.     }  
  39. ;  
  40.     public static void startAMService(Context context){  
  41.         Log.i("ServiceUtil-AlarmManager""invokeTimerPOIService wac called.." );  
  42.         PendingIntent alarmSender = null;  
  43.         Intent startIntent = new Intent(context, TimerService.class);  
  44.         startIntent.setAction(ServiceName);  
  45.   
  46.   
  47.   
  48.   
  49.         try {  
  50.       
  51.             alarmSender = PendingIntent.getService(context, 0, startIntent, 0);  
  52.         } catch (Exception e) {  
  53.             Log.i("ServiceUtil-AlarmManager""failed to start " + e.toString());  
  54.         }  
  55.         AlarmManager am = (AlarmManager) context.getSystemService(Activity.ALARM_SERVICE);  
  56.         am.setInexactRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), 5*1000, alarmSender);  
  57.     }  
  58.   
  59.     public static void cancleAMServicer(Context context){  
  60.         Log.i("ServiceUtil-AlarmManager""cancleAlarmManager to start ");  
  61.         Intent intent = new Intent(context,TimerService.class);  
  62.         intent.setAction(ServiceName);  
  63.         PendingIntent pendingIntent=PendingIntent.getService(context, 0, intent,PendingIntent.FLAG_UPDATE_CURRENT);  
  64.         AlarmManager alarm=(AlarmManager)context.getSystemService(Activity.ALARM_SERVICE);  
  65.         alarm.cancel(pendingIntent);  
  66.     }  
  67.       
  68.       
  69.       
  70.     //启动service 方式2    
  71.     //    
  72.     public static void startHandlerService(Context cxt){    
  73.         Intent intent = new Intent(cxt,TimerService.class);    
  74.   
  75.         cxt.startService(intent);  
  76.     }    
  77.         
  78.     public  static void stopHandlerService(Context cxt){    
  79.         Intent intent = new Intent(cxt,TimerService.class);    
  80.    
  81.         cxt.stopService(intent);  
  82.     }    
  83. }  

源自:http://blog.csdn.net/wds1181977/article/details/51154026















  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Android定时任务一般有两种实现方式,一种是使用Java API中的Timer类,另一种是使用Android的Alarm机制。 Timer类适用于需要在前台运行的定时任务,但不适用于需要长期在后台运行的定时任务。因为Android手机为了节省电池电量,会在长时间不操作的情况下将CPU进入睡眠状态,这可能导致Timer中的定时任务无法正常运行。 而Alarm机制具有唤醒CPU的功能,可以在需要执行定时任务时唤醒CPU。与唤醒屏幕不同,唤醒CPU是指在CPU进入睡眠状态时,通过Alarm机制来唤醒CPU执行定时任务。 在Android中,可以使用AlarmManager来设置定时任务。常用的AlarmManager方法有: - set:用于设置一次性定时任务,即到达指定时间后执行完就结束。 - setRepeating:用于设置可重复执行的定时任务,可以指定开始时间和间隔时间。 - setInexactRepeating:用于设置可重复执行的定时任务,与setRepeating相比,它更加考虑系统电量,可以调整报警的交付时间以避免过多唤醒设备。 除了以上方法,还可以使用Calendar类来设置定时任务的具体时间,然后通过Intent和PendingIntent来发送广播,并在广播接收器中执行相应的任务。 需要注意的是,Android开发中定时器的应用场景非常多,比如轮询业务需求、轮询网络或倒计时等。根据具体的需求,可以选择适合的定时任务实现方式。 总结起来,Android中的定时任务可以使用Timer类或Alarm机制来实现,其中Alarm机制更适合需要在后台长期运行的定时任务。可以使用AlarmManager的set、setRepeating和setInexactRepeating方法来设置定时任务,也可以结合Calendar类和PendingIntent来发送广播并执行相应的任务。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值