遗忘海岸

江湖程序员 -Feiph(LM战士)

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

统计

警报系统--时间段计算

//------------------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
复制代码

 

posted on   遗忘海岸  阅读(472)  评论(0编辑  收藏  举报

编辑推荐:
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
阅读排行:
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· .NET周刊【3月第1期 2025-03-02】
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· [AI/GPT/综述] AI Agent的设计模式综述
点击右上角即可分享
微信分享提示