您的位置:首页 > 移动开发 > Android开发

【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:

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
}
}
}


欢迎大家提出更好的处理方式~~~~研究研究
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: