【Android】AlarmManager 实现提醒一次,每天提醒,周自定义提醒,月自定义提醒

前言

关于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);
        intent.putExtra("Mode", "1");
        intent.putExtra("remind_number", "");
        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);
        intent.putExtra("Mode", Mode);
        intent.putExtra("remind_number", remind_number);
        //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);
		    	    		AlarmAlert(context,msg,id);
		    	    		MyAlarmManager.cancleAlarm(id);
					break;
				case "2"://每天
					initUrlWithMedia(context);
		    	   		 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);
					    	 	 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);
					    	 	 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);
					    	 	 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)