AlarmManager 是系统级别定时任务的一个Manager。本文是关于相关参数和用法的集合。都是摘抄自各位大神,仅做本人备忘。
本文很长,包括:alarmmanager/pendingintent详解/contex详解。因为都是alarmmanager里面要用到的,所以没有分开总结。全放在一起,这样一下就能看个明白。
- set(int type,long startTime,PendingIntent pi):一次性闹钟
- setRepeating(int type,long startTime,long intervalTime,PendingIntent pi): 重复性闹钟,和3有区别,3闹钟间隔时间不固定
- setInexactRepeating(int type,long startTime,long intervalTime,PendingIntent pi): 重复性闹钟,时间不固定
- cancel(PendingIntent pi):取消AlarmManager的定时服务
- getNextAlarmClock():得到下一个闹钟,返回值AlarmManager.AlarmClockInfo
- setAndAllowWhileIdle(int type, long triggerAtMillis, PendingIntent operation) 和set方法类似,这个闹钟运行在系统处于低电模式时有效
- setExact(int type, long triggerAtMillis, PendingIntent operation): 在规定的时间精确的执行闹钟,比set方法设置的精度更高
- setTime(long millis):设置系统墙上的时间
- setTimeZone(String timeZone):设置系统持续的默认时区
- setWindow(int type, long windowStartMillis, long windowLengthMillis, PendingIntent operation): 设置一个闹钟在给定的时间窗触发。类似于set,该方法允许应用程序精确地控制操作系统调整闹钟触发时间的程度。
参数:
- Type(闹钟类型): 有五个可选值:
- 1、AlarmManager.ELAPSED_REALTIME: 闹钟在手机睡眠状态下不可用,该状态下闹钟使用相对时间(相对于系统启动开始),状态值为3;
- 2、AlarmManager.ELAPSED_REALTIME_WAKEUP 闹钟在睡眠状态下会唤醒系统并执行提示功能,该状态下闹钟也使用相对时间,状态值为2;
- 3、AlarmManager.RTC 闹钟在睡眠状态下不可用,该状态下闹钟使用绝对时间,即当前系统时间,状态值为1;
- 4、AlarmManager.RTC_WAKEUP 表示闹钟在睡眠状态下会唤醒系统并执行提示功能,该状态下闹钟使用绝对时间,状态值为0;
- 5、AlarmManager.POWER_OFF_WAKEUP 表示闹钟在手机关机状态下也能正常进行提示功能,所以是5个状态中用的最多的状态之一,该状态下闹钟也是用绝对时间,状态值为4;不过本状态好像受SDK版本影响,某些版本并不支持;
- startTime:闹钟的第一次执行时间,以毫秒为单位,可以自定义时间,不过一般使用当前时间。 需要注意的是,本属性与第一个属性(type)密切相关,如果第一个参数对应的闹钟使用的是相对时间 (ELAPSED_REALTIME和ELAPSED_REALTIME_WAKEUP),那么本属性就得使用相对时间 (相对于系统启动时间来说),比如当前时间就表示为:SystemClock.elapsedRealtime(); 如果第一个参数对应的闹钟使用的是绝对时间(RTC、RTC_WAKEUP、POWER_OFF_WAKEUP), 那么本属性就得使用绝对时间,比如当前时间就表示 为:System.currentTimeMillis()。
- intervalTime:表示两次闹钟执行的间隔时间,也是以毫秒为单位.
- PendingIntent:绑定了闹钟的执行动作,比如发送一个广播、给出提示等等。 PendingIntent是Intent的封装类。需要注意的是,如果是通过启动服务来实现闹钟提 示的话,PendingIntent对象的获取就应该采用Pending.getService (Context c,int i,Intent intent,int j)方法;如果是通过广播来实现闹钟 提示的话,PendingIntent对象的获取就应该采用 PendingIntent.getBroadcast (Context c,int i,Intent intent,int j)方法;如果是采用Activity的方式来实 现闹钟提示的话,PendingIntent对象的获取就应该采用 PendingIntent.getActivity(Context c,int i,Intent intent,int j)方法。 如果这三种方法错用了的话,虽然不会报错,但是看不到闹钟提示效果。
以上资源地址:10.5 AlarmManager(闹钟服务) | 菜鸟教程
PendingIntent:
1. 英文释义:intent,意图; pending 表示即将发生的事;
2. 作用:PendingIntent这个类用来处理即将发生的事;
3. 例如:在通知Notification中用于页面跳转,但不马上跳转;
4. 对比:Intent 是及时启动的,intent随activity消失而消失;PendingIntent可以看作是对intent的包装,
5. 提示:Intent 一般是用来作Activity、 Service、BroadcastReceiver之间传递数据,而Pendingintent,一般用在Notification上,可以理解为延迟执行的intent;
6. 获取PendingIntent的实例:三个静态方法可以获取
a) PendingIntent.getBroadcast();
b) PendingIntent.getActivity();
c) PendingIntent.getService();
7. 说明:由于pendingintetn 中,保存了当前APP 的context,使它赋予外部App一种能力,使得外部APP可以如同当前APP一样执行pendingintent里的intetn,就算执行时当前的APP已经不存在了,也能通过存在pendingintent的context照样执行intent,另外还可以处理intent执行后的操作;经常和alermaner 和notificationmanager一起使用。
以上资源地址:https://www.iteye.com/blog/sunzone-1998091
pendingIntent对象,使用方法类的静态方法 :
getActivity(Context, int, Intent, int)------->跳转到一个activity组件、
getBroadcast(Context, int, Intent, int)------>打开一个广播组件
getService(Context, int, Intent, int)-------->打开一个服务组件。
分别对应着Intent的3个行为和参数有4个,比较重要的是第三个和第一个,其次是第四个和第二个。可以看到,要得到这个对象,必须传入一个Intent作为参数,必须有context作为参数。
pendingIntent是一种特殊的Intent。主要的区别在于Intent的执行立刻的,而pendingIntent的执行不是立刻的。Intent 是及时启动,intent 随所在的activity 消失而消失。
如上内容来自:Android中pendingIntent的深入理解 - 全球顶尖骇客 - 博客园
PendingIntent的参数说明
拿广播的形式说明下
PendingIntent sentIntent = PendingIntent.getBroadcast(this, 0,sIntent, 0);
第一个参数是上下文.
第二个参数是每次requestcode不同,就能产生多个Pendingintent.
第三个参数是用来存储信息.
第四个参数是对不同操作作标识.
getBroadcast(Context context, int requestCode, Intent intent, int flags)中的flags有几种状态:
1.FLAG_CANCEL_CURRENT:如果AlarmManager管理的PendingIntent已经存在,那么将会取消当前的PendingIntent,从而创建一个新的PendingIntent.
2.FLAG_UPDATE_CURRENT:如果AlarmManager管理的PendingIntent已经存在,让新的Intent更新之前Intent对象数据,
例如更新Intent中的Extras,另外,我们也可以在PendingIntent的原进程中调用PendingIntent的cancel ()把其从系统中移除掉
3.FLAG_NO_CREATE:如果AlarmManager管理的PendingIntent已经存在,那么将不进行任何操作,直接返回已经.
4.FLAG_ONE_SHOT:该PendingIntent只作用一次.在该PendingIntent对象通过send()方法触发过后,
PendingIntent将自动调用cancel()进行销毁,那么如果你再调用send()方法的话,系统将会返回一个SendIntentException.
如上内容来自:android PendingIntent参数详细解析_xyjikl-CSDN博客
上面4个flag中最经常使用的是FLAG_UPDATE_CURRENT,因为描述的Intent有更新的时候需要用到这个flag去更新你的描述,否则组件在下次事件发生或时间到达的时候extras永远是第一次Intent的extras。使用FLAG_CANCEL_CURRENT也能做到更新extras,只不过是先把前面的extras清除,另外FLAG_CANCEL_CURRENT和FLAG_UPDATE_CURRENT的区别在于能否新new一个Intent,FLAG_UPDATE_CURRENT能够新new一个Intent,而FLAG_CANCEL_CURRENT则不能,只能使用第一次的Intent。是否更新还取决于第二个参数,如果第二个。另外两flag就比较少用,利用FLAG_ONE_SHOT获取的PendingIntent只能使用一次,即使再次利用上面三个方法重新获取,再使用PendingIntent也将失败,利用FLAG_NO_CREAT获取的PendingIntent若描述的Intent不存在则返回NULL值.
如上内容来自:PendingIntent的Flags_枫轻舞云飘散-CSDN博客
关于Context
Context是一个抽象类,其通用实现在ContextImpl类中。它的主要作用是一个访问application环境全局信息的接口,通过它可以访问application的资源和相关的类,其主要功能如下:
- 启动Activity
- 启动和停止Service
- 发送广播 消息
- 注册广播消息接受者
- 访问APK中各种资源
- 访问Package的相关信息
- APK的各种权限管理
简单的说:Context负责Activity,Service,Intent,资源,Package和权限。
Context对象可以获取应用状态的信息,其使得activitys和Fragments以及Services能够使用资源文件,图片,主题,以及其他的文件夹内容。其也可以用于使用Android自带服务,例如inflate,键盘,以及content providers。
很多情况下,当你需要用到Context的时候,你肯定只是简单的利用当前activity的实例this。当你一个被activity创建的内部对象的时候,例如adapters里或者fragments里的时候,你需要将activity的实例传给它们。而当你在activity之外,例如application或者service的时候,我们需要利用application的context对象代替。
Contex的用途
明确地启动一个组件,例如activity或者service
Intent intent = new Intent(context, MyActivity.class); startActivity(intent);
创建视图
TextView textView = new TextView(context);
Contexts包含了以下信息:
-
设备的屏幕大小以及将dp,sp转化为px的尺寸。
-
style属性
-
onClick属性
inflate xml布局文件
我们使用context来获得LayoutInflater,其可以在内存中inflate xml布局文件
LayoutInflater inflater = LayoutInflater.from(context); inflater.inflate(R.layout.my_layout, parent);
发送本地广播
我们使用context来获得LocalBroadcastManager,其可以发送或者注册广播接收。
Intent broadcastIntent = new Intent("custom-action"); LocalBroadcastManager.getInstance(context).sendBroadcast(intent);
获取系统服务
例如当你需要发送通知,你需要NotificationManager。
NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); int notificationId = 1; // Context is required to construct RemoteViews Notification.Builder builder = new Notification.Builder(context).setContentTitle("custom title"); notificationManager.notify(notificationId, builder.build());