Android中的AlarmManager功能很强大,它是一个全局定时器,可以在指定时间或者指定周期启动其他组件(包括Activity、Service、BroadcastReceiver)。

使用AlarmManager编程也很简单,只要按照以下步骤即可:

1.获取AlarmManager对象;

2.创建PendingIntent对象;

3.设定执行任务的时间和周期。

下面将详细介绍各个步骤:

AlarmManager是一个系统服务,在Android应用中可以通过Context对象的getSystemService()方法来获取AlarmManager对象,如下代码所示:

  1. AlarmManager aManager=(AlarmManager)getSystemService(Service.ALARM_SERVICE);

获取了AlarmManager对象之后就可以调用它的方法来设置定时启动指定组件。

常用的有如下几个方法:

  • set(int type,long triggerAtTime,PendingIntent operation):设置在triggerAtTime时间启动由operation参数指定的组件。
  • setInexactRepeating(int type,long triggerAtTime,long interval, PendingIntent operation):设置一个非精确的周期性任务。任务近似地以interval参数指定的时间间隔执行,如果果由于某些原因(如垃圾回收或其他后台活动)使得某一个任务延迟执行了,那么系统就会调整后续任务的执行时间,保证不会因为一个任务的提前或滞后而影响到所有任务的执行,这样看来,任务就没有精确地按照interval参数指定的间隔执行。
  • setRepeating(int type,long triggerAtTime,long interval,PendingIntent operation):设置一个周期性执行的定时任务,和上面的方法相比,这个方法执行的是精确的定时任务,系统会尽量保证时间间隔固定不变,如果某一个任务被延迟了,那么后续的任务也相应地被延迟。

上面几个方法中几个参数含义如下:

1. type 定时任务的类型,该参数可以接收如下值:

  • ELAPSED_REALTIME:表示闹钟在手机睡眠状态下不可用,该状态下闹钟使用相对时间(相对于系统启动开始)。
  • ELAPSED_REALTIME_WAKEUP: 表示闹钟在睡眠状态下会唤醒系统并执行提示功能,该状态下闹钟也使用相对时间。
  • RTC:表示闹钟在手机睡眠状态下不可用,该状态下闹钟使用绝对时间(即系统时间)。当系统调用System.currentTimeMillis()方法的返回值与triggerAtTime相等时启动operation所对应的组件。
  • RTC_WAKEUP:表示闹钟在睡眠状态下会唤醒系统并执行提示功能,该状态下闹钟也使用绝对时间。

2. triggerAtTime 定时任务首次触发的时间,是一个毫秒值,该参数值的含义受type参数影响,二者具体的对应关系如下:

type triggerAtTime

ELAPSED_REALTIME

ELAPSED_REALTIME_WAKEUP

相对系统启动的时间。要获取当前时间相对系统启动的时间用SystemClock.elapsedRealtime()方法。

例如:我想在开机一个小时后执行某个任务,那么这里的triggerAtTime的值就应该是1小时的毫秒值(360 0000 millis).

RTC

RTC_WAKEUP

绝对时间,即和1970年1月1日00:00:00时间上的差值,以毫秒为单位。此时定时任务第一次触发的条件是当系统调用System.currentTimeMillis()方法的返回值与triggerAtTime相等。

3. interval 定时任务执行的周期

4. operation 是一个PendingIntent对象,代表闹钟需要执行的动作,如启动Activity、Service,发送广播等。

PendingIntent是Intent的封装类,代表一个延迟执行的意图。需要注意的是,如果希望到设定的时间启动Service,则应该采用PendingIntent.getService(Context context, int requestCode, Intent intent, int flags)方法来获取PendingIntent对象;如果希望到设定的时间发送Broadcast,则PendingIntent对象的获取就应该采用PendingIntent.getBroadcast(Context context, int requestCode, Intent intent, int flags)方法;如果希望到设定的时间启动Activity,则PendingIntent对象的获取就应该采用PendingIntent.getActivity(Context context, int requestCode, Intent intent, int flags)方法。如果这三种方法错用了的话,虽然不会报错,但是看不到闹钟提示效果。另外,还有一个PendingIntent.getActivities(Context context, int requestCode, Intent[] intents, int flags)方法,允许传入一个Intent数组,这样就可以同时启动多个Activity。

说了这么多,接下来就用代码来演示一下吧。

  1. package com.example.androidtest;
  2. import android.os.Bundle;
  3. import android.app.Activity;
  4. import android.app.AlarmManager;
  5. import android.app.PendingIntent;
  6. import android.app.Service;
  7. import android.content.Intent;
  8. public class AlarmDemoActivity extends Activity {
  9. @Override
  10. protected void onCreate(Bundle savedInstanceState) {
  11. super.onCreate(savedInstanceState);
  12. setContentView(R.layout.activity_alarm_demo);
  13. // 获取AlarmManager对象
  14. AlarmManager aManager=(AlarmManager)getSystemService(Service.ALARM_SERVICE);
  15. Intent intent=new Intent();
  16. // 启动一个名为DialogActivity的Activity
  17. intent.setClass(this, DialogActivity.class);
  18. // 获取PendingIntent对象
  19. // requestCode 参数用来区分不同的PendingIntent对象
  20. // flag 参数常用的有4个值:
  21. //      FLAG_CANCEL_CURRENT 当需要获取的PendingIntent对象已经存在时,先取消当前的对象,再获取新的;
  22. //  FLAG_ONE_SHOT 获取的PendingIntent对象只能使用一次,再次使用需要重新获取
  23. //  FLAG_NO_CREATE 如果获取的PendingIntent对象不存在,则返回null
  24. //  FLAG_UPDATE_CURRENT 如果希望获取的PendingIntent对象与已经存在的PendingIntent对象相比,如果只是Intent附加的数据不      //  同,那么当前存在的PendingIntent对象不会被取消,而是重新加载新的Intent附加的数据
  25. PendingIntent pi=PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
  26. // 设置定时任务,这里使用绝对时间,即使休眠也提醒,程序启动后过1s钟会启动新的Activity
  27. aManager.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis()+1000, pi);
  28. }
  29. }

那么问题又来了,如果设定的闹钟想取消怎么办?

很简单,AlarmManager有一个方法cancel(PendingIntent
operation),需要注意的是,这里传入的PendingIntent 对象必须和前面设定闹钟时传入的PendingIntent
对象相等才行。两个PendingIntent 如何才算相等?

the same kind of PendingIntent (same operation, same Intent action, data, categories, and components, and same flags)

可见,要求还是挺严格的,几乎所有的东西都要一样,如果我们的程序中需要频繁地设定和取消闹钟,我们可以把这两个方法封装一下,方便使用:

  1. /**
  2. * 设定提醒
  3. * @param context
  4. * @param aManager
  5. * @param reminder 自定义的一个实体类,封装了提醒相关的东西,如提醒的编号ID,提醒的时间等
  6. */
  7. public static void setAlarm(Context context,AlarmManager aManager,Reminder reminder)
  8. {
  9. // 注册AlarmManager的定时服务
  10. Intent intent=new Intent(Constants.ACITON_REMIND);// Constants.ACITON_REMIND是自定义的一个action
  11. // 使用Reminder实体的ID作为PendingIntent的requestCode可以保证PendingIntent的唯一性
  12. PendingIntent pi=PendingIntent.getBroadcast(context, (int)reminder.getId(), intent,
  13. PendingIntent.FLAG_UPDATE_CURRENT);
  14. // 设定的时间是Reminder实体中封装的时间
  15. aManager.set(AlarmManager.RTC_WAKEUP, reminder.getReminderDate().getTime(), pi);
  16. }
  17. /**
  18. * 取消提醒
  19. * @param context
  20. * @param aManager
  21. * @param reminder
  22. */
  23. public static void cancelAlarm(Context context,AlarmManager aManager,Reminder reminder)
  24. {
  25. // 取消AlarmManager的定时服务
  26. Intent intent=new Intent(Constants.ACITON_REMIND);// 和设定闹钟时的action要一样
  27. // 这里PendingIntent的requestCode、intent和flag要和设定闹钟时一样
  28. PendingIntent pi=PendingIntent.getBroadcast(context, (int)reminder.getId(), intent,
  29. PendingIntent.FLAG_UPDATE_CURRENT);
  30. aManager.cancel(pi);
  31. }

在使用AlarmManager的时候还有几点需要注意:

1. 闹钟在关机或重启之后会失效。如果希望闹钟一直有效,先把闹钟信息存储到本地,然后开机启动一个Service,通过Service重新设定闹钟。

2. 如果闹钟设定的时间小于当前时间,那么闹钟事件会立即触发,如果想避免这种情况,可以在设定闹钟之前先添加一个判断,判断需要设定的时间如果小于当前时间则什么也不做。

3. 后续再发现需要注意的问题会继续补充……

转载请指明原文出处http://blog.csdn.net/fxdaniel/article/details/41150129

Android利用AlarmManager执行定时任务的更多相关文章

  1. Android开发之执行定时任务AlarmManager,Timer,Thread

    1.Thread:使用线程方式2.Timer是java的特性3.AlarmManager:AlarmManager将应用与服务分割开来后,使得应用程序开发者不用 关心具体的服务,而是直接通过Alarm ...

  2. Android 的 AlarmManager 和 wakeLock联合使用

    http://stackoverflow.com/questions/6864712/android-alarmmanager-not-waking-phone-up 主要说的是,对于android ...

  3. Android中AlarmManager使用示例(持续更新,已经更改)

    现在普遍的手机都会有一个闹钟的功能,如果使用Android来实现一个闹钟可以使用AtarmManager来实现.AtarmManager提供了一种系统级的提示服务,允许你安排在将来的某个时间执行一个服 ...

  4. Android闹钟 AlarmManager的使用

    Android闹钟 AlarmManager的使用 AlarmManager介绍 AlarmManager这个类提供对系统闹钟服务的访问接口. 你可以为你的应用设定一个在未来某个时间唤醒的功能. 当闹 ...

  5. linux(以ubuntu为例)下Android利用ant自动编译、修改配置文件、批量多渠道,打包生成apk文件

    原创,转载请注明:http://www.cnblogs.com/ycxyyzw/p/4555328.html  之前写过一篇<windows下Android利用ant自动编译.修改配置文件.批量 ...

  6. Android 中延迟执行的小结

    一.开启新线程 new Thread(new Runnable(){ public void run(){ Thread.sleep(XXXX); handler.sendMessage();---- ...

  7. Android利用tcpdump和wireshark抓取网络数据包

    Android利用tcpdump和wireshark抓取网络数据包 主要介绍如何利用tcpdump抓取andorid手机上网络数据请求,利用Wireshark可以清晰的查看到网络请求的各个过程包括三次 ...

  8. Android 开发 AlarmManager 定时器

    介绍 AlarmManager是Android中常用的一种系统级别的提示服务,在特定的时刻为我们广播一个指定的Intent.简单的说就是我们设定一个时间,然后在该时间到来时,AlarmManager为 ...

  9. 使用Quartz.net来执行定时任务

    Quartz.net使用方法:http://www.cnblogs.com/lizichao1991/p/5707604.html 最近,项目中需要执行一个计划任务,组长就让我了解一下Quartz.n ...

随机推荐

  1. POJ 1989 贪心

    题意: 思路: 从前到后扫一遍 如果k个数都出现过了 ans++ 从当前接着判断 最后答案就是ans+1 //By SiriusRen #include <cstdio> using na ...

  2. Android Studio 解决unspecified on project app resolves to an APK archive which is not supported

    出现该问题unspecified on project app resolves to an APK archive which is not supported as a compilation d ...

  3. javafx ComboBox Event and change cell color

    public class EffectTest extends Application { public static void main(String[] args) { launch(args); ...

  4. Spring 实现数据库读写分离(转)

    现在大型的电子商务系统,在数据库层面大都采用读写分离技术,就是一个Master数据库,多个Slave数据库.Master库负责数据更新和实时数据查询,Slave库当然负责非实时数据查询.因为在实际的应 ...

  5. UVa 11743 - Credit Check

    题目:推断卡号是否合法,给你4组4位的数字.偶数位的2倍的位和加上奇数位的和,推断尾数是否为0. 分析:简单题,模拟. 直接依照提议推断就可以. 说明:460题,加油! #include <io ...

  6. SICP 习题 (1.39)解题总结

    SICP 习题1.39沿着习题1.37, 1.38的方向继续前行,要求我们依据德国数学家J.H.Lambert的公式定义tan-cf过程,用于计算正切函数的近似值. J.H.Lambert的公式例如以 ...

  7. js---BOM 的理解方法

    windows 方法 window.close(); //关闭窗口   window.alert("message"); //弹出一个具有OK按钮的系统消息框,显示指定的文本   ...

  8. centos7.2 64位安装java

    1.  wget http://download.oracle.com/otn-pub/java/jdk/8u131-b11/d54c1d3a095b4ff2b6607d096fa80163/jdk- ...

  9. [Javascript] Iterate Over Items with JavaScript's for-of Loop

    In this lesson we will understand the For Of loop in Javascript which was introduced in ES6. The for ...

  10. progerssbar-style 属性分析

    先看如下代码 <ProgressBar android:id="@+id/stateProgressBar" android:orientation="horizo ...