AlarmManager是Android中常用的一种系统级别的提示服务,在特定的时刻为我们广播一个指定的Intent。简单的说就是我们设定一个时间,然后在该时间到来时,AlarmManager为我们广播一个我们设定的Intent,通常我们使用 PendingIntent,PendingIntent可以理解为Intent的封装包,简单的说就是在Intent上在加个指定的动作。在使用Intent的时候,我们还需要在执行startActivity、startService或sendBroadcast才能使Intent有用。而PendingIntent的话就是将这个动作包含在内了。
注意!因为在较高的android版本(大概应该是5.0,其他厂商的机器都会有所不同)里,为了节省电源使用了一种在一段时间的所有定时器都会自动合并到一个时间点上一起发出的机制。所以,现在的定时器启动的时间并不是十分精确,它只是一个大概时间。就算你在后续设置了精确版本重复模式也是如此,它只是稍微好一点点。
关于更详解的了解在后续说明,我们先简单大概的了解一下使用流程。帮助理解后续更详细的参数说明。
我们创建一个定时器启动Activity的简单demo:
'''java
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_time);
mBtnStart = (Button)findViewById(R.id.btn_start);
mBtnStart.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//正常的创建intent,TimeDemoActivity是我要启动的活动
Intent intent = new Intent(TimeActivity.this,TimeDemoActivity.class);
long time = System.currentTimeMillis()+5*1000;//得到当前时间并且增加5秒,表示我们在5秒后触发定时器
//创建PendingIntent封装了intent
PendingIntent pi = PendingIntent.getActivity(TimeActivity.this,0,intent,0);
AlarmManager manager = (AlarmManager)getSystemService(ALARM_SERVICE);//得到系统AlarmManager服务
//设置了AlarmManager类型参数,时间值,PendingIntent
manager.set(AlarmManager.RTC_WAKEUP,time,pi);
}
});
}
'''
这样就完成了,下面我们来看看效果:
//这是启动activity的PendingIntent
PendingIntent pi = PendingIntent.getActivity(TimeActivity.this,0,intent,0);
不介绍setTimeZone方法
闹钟的类型,常用的有5个值:AlarmManager.ELAPSED_REALTIME、 AlarmManager.ELAPSED_REALTIME_WAKEUP、AlarmManager.RTC、 AlarmManager.RTC_WAKEUP、AlarmManager.POWER_OFF_WAKEUP。
闹钟的第一次执行时间,以毫秒为单位,可以自定义时间,不过一般使用当前时间。需要注意的是,本属性与第一个属性(type)密切相关,如果第一个参数对 应的闹钟使用的是相对时间(ELAPSED_REALTIME和ELAPSED_REALTIME_WAKEUP),那么本属性就得使用相对时间(相对于 系统启动时间来说),比如当前时间就表示为:SystemClock.elapsedRealtime();如果第一个参数对应的闹钟使用的是绝对时间 (RTC、RTC_WAKEUP、POWER_OFF_WAKEUP),那么本属性就得使用绝对时间,比如当前时间就表示 为:System.currentTimeMillis()。
对于后两个方法来说,存在本属性,表示两次闹钟执行的间隔时间,也是以毫秒为单位。这里系统代码上已经提供了一些快捷的间隔时间,让你可以不需要在另外计算一天的毫秒级时间:
使用方法:
manager.setRepeating(AlarmManager.RTC_WAKEUP,time+10*1000,AlarmManager.INTERVAL_DAY,pi);
绑定了闹钟的执行动作,比如发送一个广播、给出提示等等。PendingIntent是Intent的封装类。
AlarmManager manager = (AlarmManager)getSystemService(ALARM_SERVICE);
Intent intent = new Intent(AlarmTest.this, AlarmActivity.class);
intent.setAction("111111");
PendingIntent pendingIntent = PendingIntent.getActivity( AlarmTest.this, 0, intent, 0);
manager.cancel(pendingIntent);
说明一下为什么需要setAction,因为有一种情况就是多个 AlarmManager 都在不同时间段要启动相同activity的intent,所以为了区分不同时段的intent,我们需要添加setAction。这样取消的时候只会取消指定的intent。注意!如果你添加了2个一样的Intent到定时器里,那么第一个被添加到定时器的Intent会自动被取消。
请移步到本人另一篇博客了解Java的时间值操作与获取:https://blog.csdn.net/qq_37217804/article/details/81741684取消
定时器广播Demo_1
注意!必需静态广播!
在AndroidManifest.xml静态广播注册与action接收器注册:
创建接收器class:
public class MyReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals("com.yt.owl.MyReceiver")) {
Toast.makeText(context, "定时器广播成功接收", Toast.LENGTH_SHORT).show();
}
}
}
创建定时器:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_time);
mBtnStart = (Button)findViewById(R.id.btn_start);
mBtnStart.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
mFormat = new SimpleDateFormat("yyyy年MM月dd日 : HH时mm分ss秒");
long time = System.currentTimeMillis();
Log.e(TAG, "TIME1: "+time);
Intent intent = new Intent(TimeActivity.this,MyReceiver.class);
intent.setAction("com.xxx.xxx.MyReceiver");
PendingIntent pt = PendingIntent.getBroadcast(TimeActivity.this,0,intent, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager manager = (AlarmManager)getSystemService(ALARM_SERVICE);
manager.set(AlarmManager.RTC_WAKEUP,time+5*1000,pt);
Toast.makeText(TimeActivity.this,"定时器启动 触发时间"+mFormat.format(time+5*1000),Toast.LENGTH_SHORT).show();
}
});
}
效果图:
定时器广播Demo_2
当然我们可以不添加action
AndroidManifest.xml注册静态广播
创建广播class
public class MyReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "定时器广播成功接收", Toast.LENGTH_SHORT).show();
}
}
创建定时器:
mBtnStart.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
mFormat = new SimpleDateFormat("yyyy年MM月dd日 : HH时mm分ss秒");
long time = System.currentTimeMillis();
Log.e(TAG, "TIME1: "+time);
Intent intent = new Intent(TimeActivity.this,MyReceiver.class);
PendingIntent pi = PendingIntent.getBroadcast(TimeActivity.this,0,intent, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager manager = (AlarmManager)getSystemService(ALARM_SERVICE);
manager.set(AlarmManager.RTC_WAKEUP,time+5*1000,pi);
Toast.makeText(TimeActivity.this,"定时器启动 触发时间"+mFormat.format(time+5*1000),Toast.LENGTH_SHORT).show();
}
});