Android利用AlarmManager执行定时任务
Android中的AlarmManager功能很强大,它是一个全局定时器,可以在指定时间或者指定周期启动其他组件(包括Activity、Service、BroadcastReceiver)。
使用AlarmManager编程也很简单,只要按照以下步骤即可:
1.获取AlarmManager对象;
2.创建PendingIntent对象;
3.设定执行任务的时间和周期。
下面将详细介绍各个步骤:
AlarmManager是一个系统服务,在Android应用中可以通过Context对象的getSystemService()方法来获取AlarmManager对象,如下代码所示:
- 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。
说了这么多,接下来就用代码来演示一下吧。
- package com.example.androidtest;
- import android.os.Bundle;
- import android.app.Activity;
- import android.app.AlarmManager;
- import android.app.PendingIntent;
- import android.app.Service;
- import android.content.Intent;
- public class AlarmDemoActivity extends Activity {
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_alarm_demo);
- // 获取AlarmManager对象
- AlarmManager aManager=(AlarmManager)getSystemService(Service.ALARM_SERVICE);
- Intent intent=new Intent();
- // 启动一个名为DialogActivity的Activity
- intent.setClass(this, DialogActivity.class);
- // 获取PendingIntent对象
- // requestCode 参数用来区分不同的PendingIntent对象
- // flag 参数常用的有4个值:
- // FLAG_CANCEL_CURRENT 当需要获取的PendingIntent对象已经存在时,先取消当前的对象,再获取新的;
- // FLAG_ONE_SHOT 获取的PendingIntent对象只能使用一次,再次使用需要重新获取
- // FLAG_NO_CREATE 如果获取的PendingIntent对象不存在,则返回null
- // FLAG_UPDATE_CURRENT 如果希望获取的PendingIntent对象与已经存在的PendingIntent对象相比,如果只是Intent附加的数据不 // 同,那么当前存在的PendingIntent对象不会被取消,而是重新加载新的Intent附加的数据
- PendingIntent pi=PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
- // 设置定时任务,这里使用绝对时间,即使休眠也提醒,程序启动后过1s钟会启动新的Activity
- aManager.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis()+1000, pi);
- }
- }
那么问题又来了,如果设定的闹钟想取消怎么办?
很简单,AlarmManager有一个方法cancel(PendingIntent
operation),需要注意的是,这里传入的PendingIntent 对象必须和前面设定闹钟时传入的PendingIntent
对象相等才行。两个PendingIntent 如何才算相等?
the same kind of PendingIntent (same operation, same Intent action, data, categories, and components, and same flags)
可见,要求还是挺严格的,几乎所有的东西都要一样,如果我们的程序中需要频繁地设定和取消闹钟,我们可以把这两个方法封装一下,方便使用:
- /**
- * 设定提醒
- * @param context
- * @param aManager
- * @param reminder 自定义的一个实体类,封装了提醒相关的东西,如提醒的编号ID,提醒的时间等
- */
- public static void setAlarm(Context context,AlarmManager aManager,Reminder reminder)
- {
- // 注册AlarmManager的定时服务
- Intent intent=new Intent(Constants.ACITON_REMIND);// Constants.ACITON_REMIND是自定义的一个action
- // 使用Reminder实体的ID作为PendingIntent的requestCode可以保证PendingIntent的唯一性
- PendingIntent pi=PendingIntent.getBroadcast(context, (int)reminder.getId(), intent,
- PendingIntent.FLAG_UPDATE_CURRENT);
- // 设定的时间是Reminder实体中封装的时间
- aManager.set(AlarmManager.RTC_WAKEUP, reminder.getReminderDate().getTime(), pi);
- }
- /**
- * 取消提醒
- * @param context
- * @param aManager
- * @param reminder
- */
- public static void cancelAlarm(Context context,AlarmManager aManager,Reminder reminder)
- {
- // 取消AlarmManager的定时服务
- Intent intent=new Intent(Constants.ACITON_REMIND);// 和设定闹钟时的action要一样
- // 这里PendingIntent的requestCode、intent和flag要和设定闹钟时一样
- PendingIntent pi=PendingIntent.getBroadcast(context, (int)reminder.getId(), intent,
- PendingIntent.FLAG_UPDATE_CURRENT);
- aManager.cancel(pi);
- }
在使用AlarmManager的时候还有几点需要注意:
1. 闹钟在关机或重启之后会失效。如果希望闹钟一直有效,先把闹钟信息存储到本地,然后开机启动一个Service,通过Service重新设定闹钟。
2. 如果闹钟设定的时间小于当前时间,那么闹钟事件会立即触发,如果想避免这种情况,可以在设定闹钟之前先添加一个判断,判断需要设定的时间如果小于当前时间则什么也不做。
3. 后续再发现需要注意的问题会继续补充……
转载请指明原文出处http://blog.csdn.net/fxdaniel/article/details/41150129
Android利用AlarmManager执行定时任务的更多相关文章
- Android开发之执行定时任务AlarmManager,Timer,Thread
1.Thread:使用线程方式2.Timer是java的特性3.AlarmManager:AlarmManager将应用与服务分割开来后,使得应用程序开发者不用 关心具体的服务,而是直接通过Alarm ...
- Android 的 AlarmManager 和 wakeLock联合使用
http://stackoverflow.com/questions/6864712/android-alarmmanager-not-waking-phone-up 主要说的是,对于android ...
- Android中AlarmManager使用示例(持续更新,已经更改)
现在普遍的手机都会有一个闹钟的功能,如果使用Android来实现一个闹钟可以使用AtarmManager来实现.AtarmManager提供了一种系统级的提示服务,允许你安排在将来的某个时间执行一个服 ...
- Android闹钟 AlarmManager的使用
Android闹钟 AlarmManager的使用 AlarmManager介绍 AlarmManager这个类提供对系统闹钟服务的访问接口. 你可以为你的应用设定一个在未来某个时间唤醒的功能. 当闹 ...
- linux(以ubuntu为例)下Android利用ant自动编译、修改配置文件、批量多渠道,打包生成apk文件
原创,转载请注明:http://www.cnblogs.com/ycxyyzw/p/4555328.html 之前写过一篇<windows下Android利用ant自动编译.修改配置文件.批量 ...
- Android 中延迟执行的小结
一.开启新线程 new Thread(new Runnable(){ public void run(){ Thread.sleep(XXXX); handler.sendMessage();---- ...
- Android利用tcpdump和wireshark抓取网络数据包
Android利用tcpdump和wireshark抓取网络数据包 主要介绍如何利用tcpdump抓取andorid手机上网络数据请求,利用Wireshark可以清晰的查看到网络请求的各个过程包括三次 ...
- Android 开发 AlarmManager 定时器
介绍 AlarmManager是Android中常用的一种系统级别的提示服务,在特定的时刻为我们广播一个指定的Intent.简单的说就是我们设定一个时间,然后在该时间到来时,AlarmManager为 ...
- 使用Quartz.net来执行定时任务
Quartz.net使用方法:http://www.cnblogs.com/lizichao1991/p/5707604.html 最近,项目中需要执行一个计划任务,组长就让我了解一下Quartz.n ...
随机推荐
- 使用Vue动态生成form表单
form-create 表单生成器 具有数据收集.校验和提交功能的表单生成器,支持双向数据绑定和事件扩展,组件包含有复选框.单选框.输入框.下拉选择框等表单元素以及省市区三级联动,时间选择,日期选择, ...
- VMware Vsphere 6.0安装部署 总体部署架构
(一)总体部署架构 本教程用于学习目的,力求详尽的介绍安装部署过程和各组件之间的关系,部署过程从最简单的模型开始,系列文章按时间顺序依次展开,每篇介绍一个组件. 开始阶段,按照一台物理服务器,部署所有 ...
- ST和LCA和无根树连接
#include <stdio.h> #include <iostream> #include <string.h> #include <algorithm& ...
- 给Linux设置SSH登录邮件提醒
给Linux设置SSH登录邮件提醒 心血来潮,用 last 命令查看了登录记录,不看不知道,一看就有问题.竟然有两个陌生的IP ,一个是美国欧莱雅的,一个是北京联通的.真是郁闷,密码简单了真不行 后来 ...
- PHP 实现断点续传的原理和方法
PHP 实现断点续传的原理和方法 0. http协议从1.1开始支持静态获取文件的部分内容,为多线程下载和断点续传提供了技术支持.它通过在Header里两个参数实现的,客户端发请求时对应的是Accep ...
- 判断移动端跳转,从移动端来的不跳转。利用localStorage保存状态,window.location.pathname跳转不同的url
手机访问 www.yourdomain.com 跳转,从m.yourdomain.com来的不跳转. 访问www.yourdomain.com/category8, 跳转到m.yourdomain.c ...
- BZOJ2002: [Hnoi2010]Bounce 弹飞绵羊(LCT)
Description 某天,Lostmonkey发明了一种超级弹力装置,为了在 他的绵羊朋友面前显摆,他邀请小绵羊一起玩个游戏.游戏一开始,Lostmonkey在地上沿着一条直线摆上n个装置,每个装 ...
- java list 容器的ConcurrentModificationException
java中的很多容器在遍历的同时进行修改里面的元素都会ConcurrentModificationException,包括多线程情况和单线程的情况.多线程的情况就用说了,单线程出现这个异常一般是遍历( ...
- VC中画矩形框 & polyline画多点
搞自动化会经常遇到一个问题就是记录实时的曲线,通常做法是首先将数据保存在一个记事本中,或数据库.使用VB或DELPHI可以直接调用现成的控件画图,只是控制起来不方便.所以使用VC就需要程序来控制.在网 ...
- 01011_怎么打开任务管理器?win7打开任务管理器方法
以下几种方法可以打开任务管理器 1.在系统的任务栏点击鼠标右键,然后在弹出的右键菜单中选择“启动任务管理器”: 2.同时按下这三个按钮:Ctrl + Shift + Esc: 3.同时按下键盘的Ctr ...