警报系统--时间段计算

//------------------2019-10-24 

居然看不懂了,估计使用系统时钟AlarmManager,

在工作时间段内使用Repeating方式每8分钟执行一次,而是休息时段

着使用定时唤醒方式跳过,即比分在08:00使用RTC_WAKEUP唤醒

//------------------End 2019-10-24---------

允许用户指定工作时间段,只有在指定的时间段内警报才会被触发

时段记录结构:
 /**
  * 说明表示格式与范围是:[00,00  - 24,00]
  * 分钟部分范围是[0-59]
  * 8,50 表示8点50
  * 最小单位是分钟,由0,1,2,3,....1439
  * 个指定时间段不能相交,开始时间点与结束时间点必需唯一
  * includeTime内各时间段必须按小到大排序
  */
 private void initIncludeTime() {
  includeTime=new ArrayList<AlarmSetting.HourSegment>();
     includeTime.add(new HourSegment(7,0,10,30)); //7:00 - 10:30
     includeTime.add(new HourSegment(13,30, 16,30));//13:30 - 16:30
     includeTime.add(new HourSegment(18,30, 20,30));//18:30 - 20:30
  
 }

排除时段列表计算:

  //计算排除时间列表
  int bPoint=0;
        List<HourSegment> excludes=new ArrayList<AlarmSetting.HourSegment>();
  for (HourSegment s : getIncludeTime()) {
 
   int sBIndex=getIndex(s.beginHour,s.beginMinute);
   int sEIndex=getIndex(s.endHour,s.endMinute);
   
   if(sBIndex > bPoint){
    excludes.add(new HourSegment(getMoment(bPoint),  getMoment(sBIndex-1)));
   }
   bPoint=sEIndex + 1;
   if(bPoint>1439)break;
  }
  if(bPoint<=1439){
   excludes.add(new HourSegment(getMoment(bPoint), getMoment(1439)));
  }

完整代码:

package cn.fstudio.alarm;

import java.io.Serializable;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;

import cn.fstudio.util.AppSettingUtil;

import android.R.bool;
import android.content.Context;
import android.util.Log;
import android.util.Pair;


/**
 * @author Administrator
 *
 */
public class AlarmSetting implements Serializable{

    /**
     * 
     */
    private static final long serialVersionUID = 1L;
    /**
     * 两次警报窗口的最小间隔时间
     */
    private Integer fireInterval =10;
    private Integer pollInterval = 10;
    private Integer localReviewInterval=5;
    private Integer refireDelay=45;
    private List<HourSegment> includeTime=null;
    public AlarmSetting(){
        initIncludeTime();
    }

    
    /**
     * 说明表示格式与范围是:[00,00  - 24,00]
     * 分钟部分范围是[0-59]
     * 8,50 表示8点50
     * 最小单位是分钟,由0,1,2,3,....1439
     * 个指定时间段不能相交,开始时间点与结束时间点必需唯一
     * includeTime内各时间段必须按小到大排序
     */
    private void initIncludeTime() {
        includeTime=new ArrayList<AlarmSetting.HourSegment>();
        includeTime.add(new HourSegment(7,0,10,30)); //7:00 - 10:30
        includeTime.add(new HourSegment(13,30, 16,30));//13:30 - 16:30
        includeTime.add(new HourSegment(18,30, 20,30));//18:30 - 20:30
        
    }

    /**
     * 本地轮讯时间
     * 指Service触发间隔
     * */
    public Integer getLocalReviewInterval() {
        if(localReviewInterval==null)localReviewInterval=5;
        return localReviewInterval;
    }

    public void setLocalReviewInterval(Integer localReviewInterval) {
        this.localReviewInterval = localReviewInterval;
    }


    public Integer getPollInterval() {
        if(pollInterval==null)pollInterval=10;
        return pollInterval;
    }

    public void setPollInterval(Integer i) {
        this.pollInterval = i;
    }

    public Integer getFireInterval() {
        if(fireInterval==null)fireInterval=10;
        return fireInterval;
    }

    public void setFireInterval(Integer fireInterval) {
        this.fireInterval = fireInterval;
    }
    
    public List<HourSegment> getIncludeTime() {
        if(includeTime==null 
                || (includeTime.size()>0 && includeTime.get(0).beginHour==null))initIncludeTime();
        return includeTime;
    }

    public void setIncludeTime(List<HourSegment> includeTime) {
        this.includeTime = includeTime;
    }


    public Integer getRefireDelay() {
        if(refireDelay==null)refireDelay=45;
        return refireDelay;
    }

    public void setRefireDelay(Integer refireDelay) {
        this.refireDelay = refireDelay;
    }


    //========内部类========
    public static class HourSegment implements Serializable{
        /**
         * 
         */
        private static final long serialVersionUID = 1L;
        private Integer  beginHour=null;
        private Integer  beginMinute=null;
        private Integer endHour=null;
        private Integer endMinute=null;
        
        public Pair<Integer, Integer> getBegin(){
            return new Pair<Integer, Integer>(beginHour, beginMinute);
        }
        public Pair<Integer, Integer> getEnd(){
            return new Pair<Integer, Integer>(endHour, endMinute);
        }
        public Integer getBeginHour() {
            return beginHour;
        }
        public void setBeginHour(Integer beginHour) {
            this.beginHour = beginHour;
        }
        public Integer getBeginMinute() {
            return beginMinute;
        }
        public void setBeginMinute(Integer beginMinute) {
            this.beginMinute = beginMinute;
        }
        public Integer getEndHour() {
            return endHour;
        }
        public void setEndHour(Integer endHour) {
            this.endHour = endHour;
        }
        public Integer getEndMinute() {
            return endMinute;
        }
        public void setEndMinute(Integer endMinute) {
            this.endMinute = endMinute;
        }
        public HourSegment(Integer beginHour, Integer beginMinute,
                Integer endHour, Integer endMinute) {
            super();
            this.beginHour = beginHour;
            this.beginMinute = beginMinute;
            this.endHour = endHour;
            this.endMinute = endMinute;
        }
        public HourSegment(Pair<Integer, Integer> begin,Pair<Integer, Integer> end){
            this.beginHour = begin.first;
            this.beginMinute = begin.second;
            this.endHour = end.first;
            this.endMinute = end.second;
        }
        
    }
    
    // =========通用======================
    public transient static AlarmSetting instance = null;
    public transient static final String FILENAME="alarmSetting";
    private transient static Context appCtx=null;
    public static synchronized AlarmSetting create(Context ctx) {
        if (instance == null) {
            appCtx=ctx;
            Object obj = AppSettingUtil.load(FILENAME, ctx);
            if(obj==null){
                obj=new AlarmSetting();
                AppSettingUtil.save(FILENAME, ctx, obj);
                
            }
            instance=(AlarmSetting) obj;
            
        }
        return instance;
    }
    
    public void save(){
        AppSettingUtil.save(FILENAME, appCtx, this);
    }

    @Override
    public String toString() {
        return "AlarmSetting [fireInterval=" + fireInterval + ", pollInterval="
                + pollInterval + ", includeTime=" + includeTime + "]";
    }

    //==================Helper===================
    
    public boolean inWorkTime(){
        Calendar calendar=Calendar.getInstance();
        int hour=calendar.get(Calendar.HOUR_OF_DAY);
        int minute= calendar.get(Calendar.MINUTE);
    
        Pair<Integer, Integer> curV=new Pair<Integer, Integer>(hour, minute);
        
        
        
        for (HourSegment s : getIncludeTime()) {
            if( comparePair(curV,s.getBegin())>=0 && comparePair(curV ,s.getEnd())<=0){
                 calendar.add(Calendar.MINUTE, getLocalReviewInterval());
                 return true;
            }
        }
        return false;
    }
    
    /**
     * @param times 不提供使用系统当前时间
     * 如果提供格式是 first=hour,second=minute
     * 只使用times[0]
     * @return 返回下一次执行的时间(毫秒)
     */
    public  long getNextTriggerMillis(Calendar calendar){
        
        int hour=calendar.get(Calendar.HOUR_OF_DAY);
        int minute= calendar.get(Calendar.MINUTE);
    
        Pair<Integer, Integer> curV=new Pair<Integer, Integer>(hour, minute);
        
        
        
        for (HourSegment s : getIncludeTime()) {
            if( comparePair(curV,s.getBegin())>=0 && comparePair(curV ,s.getEnd())<=0){
                 calendar.add(Calendar.MINUTE, getLocalReviewInterval());
                 return calendar.getTimeInMillis();
            }
        }
        
        //计算排除时间列表
        int bPoint=0;
        List<HourSegment> excludes=new ArrayList<AlarmSetting.HourSegment>();
        for (HourSegment s : getIncludeTime()) {
    
            int sBIndex=getIndex(s.beginHour,s.beginMinute);
            int sEIndex=getIndex(s.endHour,s.endMinute);
            
            if(sBIndex > bPoint){
                excludes.add(new HourSegment(getMoment(bPoint),  getMoment(sBIndex-1)));
            }
            bPoint=sEIndex + 1;
            if(bPoint>1439)break;
        }
        if(bPoint<=1439){
            excludes.add(new HourSegment(getMoment(bPoint), getMoment(1439)));
        }
        
        
        int index=-1;
        for (HourSegment s : excludes) {
            index++;
            if( comparePair(curV,s.getBegin())>=0 && comparePair(curV ,s.getEnd())<=0){
    
                 int waitMinute= comparePair(s.getEnd(), curV);
                 //处理凌晨相连的时间端
                 if(s.endHour==24 ){
                    if( excludes.get(0).beginHour==0 && excludes.get(0).beginMinute==0){
                      waitMinute +=    (excludes.get(0).endHour * 60 +  excludes.get(0).endMinute);
                    }
                 }
                 calendar.add(Calendar.MINUTE, waitMinute + 1); //加一,以便落在执行区域
                 
                 return calendar.getTimeInMillis();
            }
        }
        return System.currentTimeMillis();
    }
    
    /**
     * 转化成分钟下标
     * 0,1,2,3....1439
     * */
    private static int getIndex(int hour,int minute){
           if(hour==0 && minute==0)return 0;
           return (hour  * 60) + minute -1;       
    }

    /**
     * 根据下标获取时刻
     * */
    private static Pair<Integer, Integer> getMoment(int point){
        if(point==0)return new Pair<Integer, Integer>(0, 0);
        point=point +1;
        return new Pair<Integer, Integer>((point / 60 ) , (point % 60));
    }
    
    private int comparePair(Pair<Integer, Integer> a,Pair<Integer, Integer> b){
        return (a.first * 60 + a.second) - (b.first * 60 + b.second);
    }
}
View Code
原文地址:https://www.cnblogs.com/wdfrog/p/3359019.html