【Android】AlarmManager 实现提醒一次,每天提醒,周自定义提醒,月自定义提醒
2016-03-31 15:54
411 查看
前言
关于AlarmManager,网上介绍的文章很多,我要总结的是关于如何通过AlarmManager实现提醒一次,每天提醒,周自定义提醒,月自定义提醒
常用方法
(1)set(int type,long startTime,PendingIntent pi);
该方法用于设置一次性闹钟,第一个参数表示闹钟类型,第二个参数表示闹钟执行时间,第三个参数表示闹钟响应动作。
(2)setRepeating(int type,long startTime,long intervalTime,PendingIntent pi);
该方法用于设置重复闹钟,第一个参数表示闹钟类型,第二个参数表示闹钟首次执行时间,第三个参数表示闹钟两次执行的间隔时间,第三个参数表示闹钟响应动作。
(3)setInexactRepeating(int type,long startTime,long intervalTime,PendingIntent pi);
参数介绍
(1)int type: 闹钟的类型,常用的有5个值:AlarmManager.ELAPSED_REALTIME、 AlarmManager.ELAPSED_REALTIME_WAKEUP、AlarmManager.RTC、 AlarmManager.RTC_WAKEUP、AlarmManager.POWER_OFF_WAKEUP。
AlarmManager.ELAPSED_REALTIME表示闹钟在手机睡眠状态下不可用,该状态下闹钟使用相对时间(相对于系统启动开始),状态值为3;
AlarmManager.ELAPSED_REALTIME_WAKEUP表示闹钟在睡眠状态下会唤醒系统并执行提示功能,该状态下闹钟也使用相对时间,状态值为2;
AlarmManager.RTC表示闹钟在睡眠状态下不可用,该状态下闹钟使用绝对时间,即当前系统时间,状态值为1;
AlarmManager.RTC_WAKEUP表示闹钟在睡眠状态下会唤醒系统并执行提示功能,该状态下闹钟使用绝对时间,状态值为0;
AlarmManager.POWER_OFF_WAKEUP表示闹钟在手机关机状态下也能正常进行提示功能,所以是5个状态中用的最多的状态之一,该状态下闹钟也是用绝对时间,状态值为4;不过本状态好像受SDK版本影响,某些版本并不支持;
(2)long startTime: 闹钟的第一次执行时间,以毫秒为单位,可以自定义时间,不过一般使用当前时间。需要注意的是,本属性与第一个属性(type)密切相关,如果第一个参数对 应的闹钟使用的是相对时间(ELAPSED_REALTIME和ELAPSED_REALTIME_WAKEUP),那么本属性就得使用相对时间(相对于 系统启动时间来说),比如当前时间就表示为:SystemClock.elapsedRealtime();如果第一个参数对应的闹钟使用的是绝对时间 (RTC、RTC_WAKEUP、POWER_OFF_WAKEUP),那么本属性就得使用绝对时间,比如当前时间就表示
为:System.currentTimeMillis()。
(3)long intervalTime:对于后两个方法来说,存在本属性,表示两次闹钟执行的间隔时间,也是以毫秒为单位。
(4)PendingIntent pi: 绑定了闹钟的执行动作,比如发送一个广播、给出提示等等。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)方法。如果这三种方法错用了的话,虽然不会报错,但是看不到闹钟提示效果。
实现功能代码思路
这里面我要用的是set和setRepeating这两个方法。
实现单次提醒 用set方法就可以了,代码见示例A,注意PendingIntent.getBroadCast里面第二个参数,第二个参数也可以用随机数来表示(不推荐),只要每次提醒这个值不同就可以了,防止两次产生的pendingIntent值一样,那么 多个单次提醒就会只响应一次。
每天提醒用setRepeat这个方法,代码见示例B, 这里面只需要调整一下间隔时间是一天 就可以了。
每周自定义提醒也是用setRepeat这个方法,代码见示例B,间隔时间仍然是一天,这里面注意intent 传给receiver的值,多了一个模式和自定义的时间,我们需要在receiver里面来处理收到信息后 决定是否提醒,何时提醒,判断模式和自定义的时间就可以了,当自定义设置的星期与Calender获取的当前星期一致,发送提醒就可以了。见示例D。
月自定义同周自定义,在receiver里面判断 自定义的日期 与 Calender获取的当前日期一致,发送提醒就可以了,见示例D。
代码示例
单次提醒方法示例A:
多次提醒方法示例B:
取消也需要方法示例C:
receiver里面的代码示例D:
欢迎大家提出更好的处理方式~~~~研究研究
关于AlarmManager,网上介绍的文章很多,我要总结的是关于如何通过AlarmManager实现提醒一次,每天提醒,周自定义提醒,月自定义提醒
常用方法
(1)set(int type,long startTime,PendingIntent pi);
该方法用于设置一次性闹钟,第一个参数表示闹钟类型,第二个参数表示闹钟执行时间,第三个参数表示闹钟响应动作。
(2)setRepeating(int type,long startTime,long intervalTime,PendingIntent pi);
该方法用于设置重复闹钟,第一个参数表示闹钟类型,第二个参数表示闹钟首次执行时间,第三个参数表示闹钟两次执行的间隔时间,第三个参数表示闹钟响应动作。
(3)setInexactRepeating(int type,long startTime,long intervalTime,PendingIntent pi);
参数介绍
(1)int type: 闹钟的类型,常用的有5个值:AlarmManager.ELAPSED_REALTIME、 AlarmManager.ELAPSED_REALTIME_WAKEUP、AlarmManager.RTC、 AlarmManager.RTC_WAKEUP、AlarmManager.POWER_OFF_WAKEUP。
AlarmManager.ELAPSED_REALTIME表示闹钟在手机睡眠状态下不可用,该状态下闹钟使用相对时间(相对于系统启动开始),状态值为3;
AlarmManager.ELAPSED_REALTIME_WAKEUP表示闹钟在睡眠状态下会唤醒系统并执行提示功能,该状态下闹钟也使用相对时间,状态值为2;
AlarmManager.RTC表示闹钟在睡眠状态下不可用,该状态下闹钟使用绝对时间,即当前系统时间,状态值为1;
AlarmManager.RTC_WAKEUP表示闹钟在睡眠状态下会唤醒系统并执行提示功能,该状态下闹钟使用绝对时间,状态值为0;
AlarmManager.POWER_OFF_WAKEUP表示闹钟在手机关机状态下也能正常进行提示功能,所以是5个状态中用的最多的状态之一,该状态下闹钟也是用绝对时间,状态值为4;不过本状态好像受SDK版本影响,某些版本并不支持;
(2)long startTime: 闹钟的第一次执行时间,以毫秒为单位,可以自定义时间,不过一般使用当前时间。需要注意的是,本属性与第一个属性(type)密切相关,如果第一个参数对 应的闹钟使用的是相对时间(ELAPSED_REALTIME和ELAPSED_REALTIME_WAKEUP),那么本属性就得使用相对时间(相对于 系统启动时间来说),比如当前时间就表示为:SystemClock.elapsedRealtime();如果第一个参数对应的闹钟使用的是绝对时间 (RTC、RTC_WAKEUP、POWER_OFF_WAKEUP),那么本属性就得使用绝对时间,比如当前时间就表示
为:System.currentTimeMillis()。
(3)long intervalTime:对于后两个方法来说,存在本属性,表示两次闹钟执行的间隔时间,也是以毫秒为单位。
(4)PendingIntent pi: 绑定了闹钟的执行动作,比如发送一个广播、给出提示等等。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)方法。如果这三种方法错用了的话,虽然不会报错,但是看不到闹钟提示效果。
实现功能代码思路
这里面我要用的是set和setRepeating这两个方法。
实现单次提醒 用set方法就可以了,代码见示例A,注意PendingIntent.getBroadCast里面第二个参数,第二个参数也可以用随机数来表示(不推荐),只要每次提醒这个值不同就可以了,防止两次产生的pendingIntent值一样,那么 多个单次提醒就会只响应一次。
每天提醒用setRepeat这个方法,代码见示例B, 这里面只需要调整一下间隔时间是一天 就可以了。
每周自定义提醒也是用setRepeat这个方法,代码见示例B,间隔时间仍然是一天,这里面注意intent 传给receiver的值,多了一个模式和自定义的时间,我们需要在receiver里面来处理收到信息后 决定是否提醒,何时提醒,判断模式和自定义的时间就可以了,当自定义设置的星期与Calender获取的当前星期一致,发送提醒就可以了。见示例D。
月自定义同周自定义,在receiver里面判断 自定义的日期 与 Calender获取的当前日期一致,发送提醒就可以了,见示例D。
代码示例
单次提醒方法示例A:
public static void AddAlarmForOnce(Context context,String id,long timeString,String txt){ AlarmManager alarmManager = (AlarmManager) context.getSystemService(context.ALARM_SERVICE); Intent intent = new Intent(); intent.setClass(context, AlarmBroadcastReceiver.class); intent.putExtra("id", id); intent.putExtra("msg", txt); <strong> intent.putExtra("Mode", "1"); intent.putExtra("remind_number", "");</strong> PendingIntent pendingIntent = PendingIntent.getBroadcast(context, UUID.randomUUID().hashCode(), intent, PendingIntent.FLAG_UPDATE_CURRENT); Log.e("currentIntent", currentIntent+"=="); if (listpeinhHashMap.get(id)==null) { listpeinhHashMap.put(id, pendingIntent); alarmManager.set(AlarmManager.RTC_WAKEUP,timeString, pendingIntent); }else { alarmManager.cancel(listpeinhHashMap.get(id)); listpeinhHashMap.remove(id); listpeinhHashMap.put(id, pendingIntent); alarmManager.set(AlarmManager.RTC_WAKEUP,timeString, pendingIntent); } }
多次提醒方法示例B:
public static void AddRepeatAlarm(Context context,String id,long timeString,Long duration,String txt,String Mode ,String remind_number){ AlarmManager alarmManager = (AlarmManager) context.getSystemService(context.ALARM_SERVICE); Intent intent = new Intent(); intent.setClass(context, AlarmBroadcastReceiver.class); intent.putExtra("id", id); intent.putExtra("msg", txt); <strong> intent.putExtra("Mode", Mode); intent.putExtra("remind_number", remind_number);</strong> //UUID.randomUUID().hashCode() PendingIntent pendingIntent = PendingIntent.getBroadcast(context, new Random().nextInt(10000), intent, PendingIntent.FLAG_UPDATE_CURRENT); Log.e("currentIntent", currentIntent+"=="); if (listpeinhHashMap.get(id)==null) { listpeinhHashMap.put(id, pendingIntent); alarmManager.setRepeating(AlarmManager.RTC_WAKEUP,timeString,duration, pendingIntent); }else { alarmManager.cancel(listpeinhHashMap.get(id)); listpeinhHashMap.remove(id); listpeinhHashMap.put(id, pendingIntent); alarmManager.setRepeating(AlarmManager.RTC_WAKEUP,timeString,duration, pendingIntent); } }
取消也需要方法示例C:
public static void cancleAlarm(String id){ try { if (listpeinhHashMap.get(id)!=null) { alarmManager.cancel(listpeinhHashMap.get(id)); listpeinhHashMap.remove(id); } } catch (Exception e) { } }
receiver里面的代码示例D:
public class AlarmBroadcastReceiver extends BroadcastReceiver { private Uri ringUri; private MediaPlayer mMediaPlayer; private String msg; private String id; private String Mode; private String remind_number; @Override public void onReceive(Context context, Intent intent) { msg = intent.getStringExtra("msg"); id = intent.getStringExtra("id"); Mode = intent.getStringExtra("Mode"); if (Mode.equals("usual")) { initUrlWithMedia(context); //移除队列中的提醒 MyAlarmManager.cancleAlarm(id); AlarmAlert(context,msg,id); }else { remind_number = intent.getStringExtra("remind_number");//提醒的日期 switch (Mode) { case "1"://只提醒一次 initUrlWithMedia(context); <span style="white-space:pre"> </span>AlarmAlert(context,msg,id); <span style="white-space:pre"> </span>MyAlarmManager.cancleAlarm(id); break; case "2"://每天 initUrlWithMedia(context); <span style="white-space:pre"> </span> AlarmAlert(context,msg,id); break; case "3"://周一到周五 /*String[] arr = remind_number.split(","); Calendar c = Calendar.getInstance(); int week = c.get(Calendar.DAY_OF_WEEK); String Tweek = (week-1)+""; for (int i = 0; i < arr.length; i++) { if (arr[i] .equals(Tweek)) { initUrlWithMedia(context); <span style="white-space:pre"> </span> AlarmAlert(context,msg,id); } } break;*/ case "4"://每周自定义 String[] arrr = remind_number.split(","); Calendar cc = Calendar.getInstance(); int weeks = cc.get(Calendar.DAY_OF_WEEK); String Tweeks = (weeks-1)+""; for (int i = 0; i < arrr.length; i++) { if (arrr[i] .equals(Tweeks)) { initUrlWithMedia(context); <span style="white-space:pre"> </span> AlarmAlert(context,msg,id); } } break; case "5"://每月自定义 String[] arrrr = remind_number.split(","); Calendar ccc = Calendar.getInstance(); int day = ccc.get(Calendar.DATE); String days = (day)+""; for (int i = 0; i < arrrr.length; i++) { if (arrrr[i] .equals(days)) { initUrlWithMedia(context); <span style="white-space:pre"> </span> AlarmAlert(context,msg,id); } } break; } } } //弹出闹钟提示框 private void AlarmAlert(Context context,String msg,String id){ try { Intent intent2=new Intent(context,AlarmAlert.class); intent2.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); intent2.putExtra("msg", msg); intent2.putExtra("id", id); context.startActivity(intent2); } catch (Exception e) { } } //初始化Media private void initUrlWithMedia(Context context) { Uri uri=RingtoneManager.getActualDefaultRingtoneUri(context, RingtoneManager.TYPE_NOTIFICATION); if (uri==null) { mMediaPlayer = MediaPlayer.create(context, R.raw.iphonewarn); }else { mMediaPlayer = MediaPlayer.create(context, uri); } mMediaPlayer.setLooping(false); try { mMediaPlayer.start(); } catch (Exception e) { // TODO: handle exception } } }
欢迎大家提出更好的处理方式~~~~研究研究
相关文章推荐
- Android Studio 导入项目说明
- Using Multiple Android Studio Versions
- Android 自定义View高级特效,神奇的贝塞尔曲线
- 笔记 Android的Fragment初使用
- Android程序中价格的处理
- Realm for Android 快速入门
- Android开源项目分类汇总(七)优秀项目
- android6.0 statusbar 通知栏颜色
- Android Studio使用总结 [未完待续]
- (4.6.9)Android属性allowBackup安全风险浅析
- Android开源项目分类汇总(六)工具库
- 安卓下拉刷新开源库对比
- Android开源项目分类汇总(四)TextView、ScrollView、TimeView、TipView、FlipView
- Android让dialog充满整个屏幕
- Android开源项目分类汇总(三) ViewPager 、Gallery、GridView、ImageView、ProgressBar
- android dialog屏蔽back返回键的解决方法
- Android Studio 快捷设置
- Android开源项目分类汇总(二) ActionBar;Menu
- Android获取本周本月本年的第一天和最后一天
- Android应用:StatusBar状态栏、NavigationBar虚拟按键栏、ActionBar标题栏、Window屏幕内容区域等的宽高