作者@恺风Wei

Android利用告警管理器可是实现时间触发,这些事件可以在一个特定的时间或者以一定的时间间隔发生。首先学习一个最为基础的告警处理。

小例子

小例子的UI如下。通过菜单,点击Alarm One,将在15秒后发送一个告警,在Activity的TextView和LogCat中都给出log说明。在15秒后,接收器接收到告警,在LogCat中显示log,并在界面上以Toast进行提示。通过这个简单的例子,我们见过学习如何设置告警,已经如何接受告警。基础小例子将只使用一次告警的菜单项。

时间处理

告警管理器可以在指定时间发送告警,使用Calendar作为时间对象,因此我们需要一些基本的Calendar处理。

public class Utils { 
     public static Calendar getTimeAfterInSecs(int secs){ 
         Calendar cal = Calendar.getInstance(); 
         cal.add(Calendar.SECOND,secs); 
         return cal; 
     } 
     
     public static Calendar getCurrentTime(){ 
         return Calendar.getInstance(); 
     } 
     
     /** 获得本日某个时间*/ 
     public static Calendar getTodayAt(int hours,int minute){ 
         Calendar today = Calendar.getInstance(); 
         
         Calendar cal = Calendar.getInstance(); 
         cal.clear(); 
         
         int year = today.get(Calendar.YEAR); 
         int month = today.get(Calendar.MONDAY); 
         int date = today.get(Calendar.DATE); 
         cal.set(year, month,date,hours,0,minute);        
         
         return cal; 
     } 
     
     public static String getDateTimeString(Calendar cal){ 
         SimpleDateFormat df = new SimpleDateFormat("MM/dd/yyyy hh:mm:ss"); 
         df.setLenient(false); 
         return df.format(cal.getTime()); 
     }    
 }

设置接收器

告警管理器将在指定的时间发送告警(intent),通过指定的接收器进行接受。相关的接收器代码如下:

public class TestReceiver extends BroadcastReceiver{ 
     private static String tag = "TestReceiver"; 
     @Override 
    public void onReceive(Context context, Intent intent) { 
        Log.d(tag,"intent = " + intent); 
         String message = intent.getStringExtra("message"); 
         Log.d(tag,message); 
         Toast.makeText(context, message, Toast.LENGTH_SHORT).show(); 
     } 
 }

接收器和我们之前的广播接收器并没有什么差异,在收到告警后,将触发onReceive()进行处理。接收器同样也需要在AndroidManifest.xml中进行声明,但和广播接收器不同,我们不需要说明接收那条广播信息,而是在告警管理器中指明告警接收器。AndroidManifest.xml的相关代码如下:

<receiver android:name=".TestReceiver" />

设置alarm

//BaseTester的具体代码见后面,这个类主要用来传递IReportBack(在Activity中具体实现,在Activity的TextView上显示相关的log信息已经写LogCat),只涉及Log信息的呈现,对于alarm的实现无关重要。

public class SendAlarmOnceTester extends BaseTester{ 
     private static String tag = "SendAlarmOnceTester";
     private static int REQUEST_CODE = 1000; 
     
     public SendAlarmOnceTester(Context context, IReportBack report){ 
         super(context,report); 
     } 
     
     public void sendAlarmOnce(){ 
         //【2】:设置告警时间,本例将在15秒后发生 
         Calendar cal = Utils.getTimeAfterInSecs(15); 
         mReport.reportBack(tag, "计划时间:" + Utils.getDateTimeString(cal) + "当前为" 
                 + Utils.getDateTimeString(Utils.getCurrentTime())); 

         //【3】由于告警是在未来的某个时间发生,需要PendingIntent,在PendingIntent中会带有intent。我们可以理解这个Intent就是告警信息,就如果之前我们学的广播消息,都是以Intent的方式。
        //【3.1】设置告警信息intent,在指定的类中进行接收,我们同时测试携带Extra参数的情况。
         Intent intent = new Intent(mContext,TestReceiver.class);         intent.putExtra("message", tag + " : Single Shot Alarm"); 
        //【3.2】对于延期处理,需要PendingIntent。我们通过getBroadcast()来构建这个pendingIntent,这也对应到到通过接收器进行告警接收处理。此外还可以通过getActivity()(用于开启一个activity)和getService()(用于开启一个服务)来构建。
         PendingIntent pi = PendingIntent.getBroadcast( 
                 mContext,                  //context,activity或者service
                REQUEST_CODE,        //request id,
                intent,                         //需要传递的intent 
                PendingIntent.FLAG_ONE_SHOT);   //flag,用于控制pengding intent的生命周期,然而,在告警中,有生命周期由告警管理器维护,此处可以填0,即no flags。 

         //【1】获取Alarm Manager 
        //【4】通过set()来设置告警 
        am.set(AlarmManager.RTC_WAKEUP,    //RTC_WAKEUP:告警会唤醒设备;RTC:当设备唤醒时传递intent 
                cal.getTimeInMillis(), 
                 pi);        
     } 
 } 

public class BaseTester { 
     protected IReportBack mReport; 
     protected Context mContext; 
     
     public BaseTester(Context context, IReportBack report){ 
         this.mContext = context; 
         this.mReport = report; 
     } 
 } 

 public interface IReportBack { 
     public void reportBack(String tag, String info); 
 }

小例子代码在:Pro Android学习:Alarm Manager小例子