精华内容
下载资源
问答
  • 机顶盒EPG菜单自动处理程序20131118 本系列文章由ex_net(张建波)编写,转载请注明出处。 http://blog.csdn.net/zjianbo/article/details/16808121 作者:张建波 邮箱: 281451020@qq....

    机顶盒EPG菜单自动处理程序20131118


    本系列文章由ex_net(张建波)编写,转载请注明出处。


    http://blog.csdn.net/zjianbo/article/details/16808121


    作者:张建波 邮箱: 281451020@qq.com 电话:13577062679 欢迎来电交流!



    用来处理网上下载的各个电视台节目单,按照一定的规律处理后,导入服务器,就可以下发给机顶盒了。

    以下程序适用于处理2013年10、11、12月的节目

    主要处理2个内容:从网上下载的节目单中截取“下个星期”的内容,并格式化日期。

    [vb] view plain copy
    1. dim fileName  
    2. Set objArgs=WScript.Arguments  
    3. fileName=objArgs(0)  
    4.   
    5.   
    6.   
    7. Call Main()  
    8. Sub Main()  
    9.   Dim fso,OutFile,InFile  
    10.   Set fso=CreateObject("Scripting.FileSystemObject")  
    11.   'fileName=OpenFileDialog()  
    12.   
    13.   Set InFile=fso.OpenTextFile(fileName,1,True)  
    14.   Set OutFile=fso.CreateTextFile(fileName+".out.txt",Ture)  
    15.   
    16.   dim OK  
    17.   OK=0  
    18.   
    19.   do  until   InFile.atendofstream  
    20.      strline=InFile.readline  
    21.      '开始截取日期  
    22.      if strline="13/10/28" then  
    23.        OK=1  
    24.      end if  
    25.        
    26.      if OK=1 then  
    27.          OutFile.WriteLine(Fx(strLine))  
    28.      end if  
    29.   loop  
    30.   InFile.close  
    31.   OutFile.Close  
    32.   Set fso=nothing  
    33.   
    34.   Msgbox "文件处理完成!转换后的文件名为"+fileName+".out.txt"  
    35. End Sub  
    36.   
    37.   
    38. Function Fx(str)  
    39.   
    40.    '星期替换  
    41.    str=Replace(str,"13/10/28","13/10/28  星期一")  
    42.    str=Replace(str,"13/10/29","13/10/29  星期二")  
    43.    str=Replace(str,"13/10/30","13/10/30  星期三")  
    44.    str=Replace(str,"13/10/31","13/10/31  星期四")  
    45.    str=Replace(str,"13/11/01","13/11/01  星期五")  
    46.    str=Replace(str,"13/11/02","13/11/02  星期六")  
    47.    str=Replace(str,"13/11/03","13/11/03  星期天")  
    48.    Fx=str  
    49.   
    50. End Function  
    51.   
    52. function OpenFileDialog()  
    53.    OpenFileDialog=inputbox("请输入文件名?")  
    54. end function  

    下面给个截图示意



    感兴趣的朋友,可以把上面的代码复制到“记事本中”,另存为 jm.vbs 文件即可。


    使用的时候,把要处理的 文本文件,拖到上面即可自动运行处理。

    展开全文
  • 最近需要改进PEG View的响应速度,因为我们目前的框架是采用...经过一段时间的查找,终于有了如下的EPG View,速度极快。 1、自定义EPG View,代码如下: package com.amlogic.dvb_custom_view; import androi...

            最近需要改进PEG View的响应速度,因为我们目前的框架是采用动态创建TextView的方法,导致上下左右切换时响应没有那么快,老板很不高兴,作为员工那必须得改进啊。经过一段时间的查找,终于有了如下的EPG View,速度极快。

      1、自定义EPG View,代码如下:

    package com.amlogic.dvb_custom_view;
    
    import android.content.Context;
    import android.graphics.Canvas;
    import android.graphics.Color;
    import android.graphics.Paint;
    import android.graphics.Rect;
    import android.text.TextPaint;
    import android.text.TextUtils;
    import android.util.AttributeSet;
    import android.util.Log;
    import android.view.ViewConfiguration;
    import android.view.ViewGroup;
    import android.widget.Scroller;
    
    import com.amlogic.DVBPlayer.AndroidNineMainMenu;
    import com.amlogic.DVBPlayer.R;
    import com.amlogic.aidl.ServiceInfoEntity;
    import com.amlogic.dvb_interface.EPGData;
    
    import com.amlogic.dvb_util.EPGUtil;
    import com.nes.gracenote.bean.EnhancedScheduleGridBean;
    
    import org.joda.time.DateTime;
    import org.joda.time.LocalDateTime;
    
    import java.util.Calendar;
    import java.util.List;
    
    public class EpgView extends ViewGroup {
        public static int DAYS_BACK_MILLIS;
        public static final int DAYS_FORWARD_MILLIS = 5 * 24 * 60 * 60 * 1000;
        private static int HOURS_IN_VIEWPORT_MILLIS = 2 * 60 * 60 * 1000;
        private static final int TIME_LABEL_SPACING_MILLIS = 30 * 60 * 1000;
        public static final int UP_DIRECTION = 0;
        public static final int DOWN_DIRECTION = 1;
    
        private Context contextObj;
        private boolean mEventNeedSelectedStatus = false;
    
        private final Rect mClipRect;
        private final Rect mDrawingRect;
        private final Rect mMeasuringRect;
        private final Paint mPaint;
        private final Scroller mScroller;
    
        private int mChannelLayoutPadding;
        private int mChannelLayoutHeight;
        private int mChannelLayoutWidth;
        private final int mChannelLayoutMargin;
        private final int mChannelLayoutBackground;
        private final int mRedColor;
        private final int mColorPrimaryDark;
        private final int mTimerBarBackground;
    
        private final int mEventLayoutSelected;
        private final int mEventLayoutBackground;
        private final int mEventLayoutBackgroundCurrent;
        private final int mEventLayoutTextColor;
        public int mEventLayoutTextSize;
    
        private final int mTimeBarLineWidth;
        private final int mTimeBarLineColor;
        private int mTimeBarHeight;
        private int mTimeBarTextSize;
    
        private final int mEPGBackground;
        //private final Map<String, Bitmap> mChannelImageCache;
        //private final Map<String, Target> mChannelImageTargetCache;
    
        private int mMaxHorizontalScroll;
        private int mMaxVerticalScroll;
    
        //event显示区域(2个小时)里,每一个像素占的毫秒数
        private long mMillisPerPixel;
    
        //时刻表上最左边的那个时间,单位毫秒
        private long mTimeOffset;
    
    
        private long mTimeLowerBoundary;
        private long mTimeUpperBoundary;
    
        public EnhancedScheduleGridBean.ScheduleGridBean.ChannelBean.ProgrammeBean currentProgram = null;
        private boolean drawCurrentTimeLine = false;
        public int currentChannelPosition = -1;
    
        private int cuDays = 0;
        private boolean isMoveRight;
        private boolean isMoveLeft;
    
        private EnhancedScheduleGridBean.ScheduleGridBean.ChannelBean.ProgrammeBean referenceEvent;
        private int referenceEventPosition;
    
        private EPGData epgData = null;
        private List<ServiceInfoEntity> serviceList;
    
    
        public EpgView(Context context) {
            this(context, null);
        }
    
        public EpgView(Context context, AttributeSet attrs) {
            this(context, attrs, 0);
        }
    
        public EpgView(Context context, AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
    
            DAYS_BACK_MILLIS = 0;
            contextObj = context;
    
            if (cuDays > 0) {
                DAYS_BACK_MILLIS = cuDays * 24 * 60 * 60 * 1000;
            } else {
                DAYS_BACK_MILLIS = 0;
            }
    
            setWillNotDraw(false);
    
            //resetBoundaries();
    
            mDrawingRect = new Rect();
            mClipRect = new Rect();
            mMeasuringRect = new Rect();
            mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
            //mChannelImageCache = Maps.newHashMap();
            //mChannelImageTargetCache = Maps.newHashMap();
    
            // Adding some friction that makes the epg less flappy.
            mScroller = new Scroller(context);
            mScroller.setFriction(ViewConfiguration.getScrollFriction());
    
            mEPGBackground = getResources().getColor(R.color.epg_background);
            mChannelLayoutMargin = getResources().getDimensionPixelSize(R.dimen.epg_channel_layout_margin_8);
            mChannelLayoutPadding = getResources().getDimensionPixelSize(R.dimen.epg_channel_layout_padding_8);
            mChannelLayoutHeight = getResources().getDimensionPixelSize(R.dimen.epg_channel_layout_height_8);
            mChannelLayoutWidth = getResources().getDimensionPixelSize(R.dimen.epg_channel_layout_width);
            mChannelLayoutBackground = getResources().getColor(R.color.epg_channel_layout_background);
            mEventLayoutBackground = getResources().getColor(R.color.translucent_black);
            mEventLayoutBackgroundCurrent = getResources().getColor(R.color.epg_background_black);
            mEventLayoutTextColor = getResources().getColor(R.color.epg_event_layout_text);
            mEventLayoutSelected = getResources().getColor(R.color.epg_date_title_color);
            mEventLayoutTextSize = getResources().getDimensionPixelSize(R.dimen.epg_event_layout_text_8);
            mTimeBarHeight = getResources().getDimensionPixelSize(R.dimen.epg_time_bar_height_8);
            mTimeBarTextSize = getResources().getDimensionPixelSize(R.dimen.epg_time_bar_text_8);
            mTimeBarLineWidth = getResources().getDimensionPixelSize(R.dimen.epg_time_bar_line_width_8);
            mTimeBarLineColor = getResources().getColor(R.color.mainmenu_epg_time_bar);
            mRedColor = getResources().getColor(R.color.colorAccent);
            mColorPrimaryDark = getResources().getColor(R.color.colorPrimaryDark);
            mTimerBarBackground = getResources().getColor(R.color.color_epg_focus);
        }
    
        /*<dimen name="epg_channel_layout_margin_8">1dp</dimen> <!--EPG 每一行的间隔距离-->
          <dimen name="epg_channel_layout_padding_8">5dp</dimen> <!-- epg event里的文字和边框的间隔-->
          <dimen name="epg_channel_layout_height_8">50dp</dimen>
          <dimen name="epg_channel_layout_width_8">165dp</dimen>
          <dimen name="epg_channel_layout_width">0dp</dimen>
          <dimen name="epg_event_layout_text_8">15dp</dimen> <!-- epg event里的文字大小-->
          <dimen name="epg_time_bar_height_8">30dp</dimen>
          <dimen name="epg_time_bar_height">40dp</dimen>
          <dimen name="epg_time_bar_text_8">15dp</dimen>
          <dimen name="epg_time_bar_line_width_8">1dp</dimen> <!-- epg 时间竖线粗-->*/
    
        /*<!--整个epg 区域的背景色-->
          <color name="epg_background">#ff4A4A4A</color>
          <color name="epg_background_white">#ffffffff</color>
          <!--epg event背景颜色-->
          <color name="epg_background_black">#ff000000</color>
          <color name="epg_event_layout_selected">#4772a4</color>
          <color name="epg_channel_layout_background">#ff323232</color>
          <color name="epg_event_layout_text">#ffd6d6d6</color>
          <color name="epg_logo_background">#ff9a9a9a</color>
          <color name="mainmenu_epg_time_bar">#ffc57120</color>
          <color name="translucent_black">#E6000000</color>
          <color name="epg_line_data_background">#D91c1c1c</color> */
    
        public void setEPGData(Context context, EPGData epgData) {
            this.epgData = epgData;
            serviceList = epgData.getChannels();
    
            contextObj = context;
    
            Log.d("wujiang", "EpgView: setEPGData->serviceList size = " + serviceList.size());
    
            if (serviceList.size() == 0) {
                return;
            }
    
            currentChannelPosition = getFirstVisibleChannelPosition();
            //Log.d("wujiang", "EpgView: currentChannelPosition = " + currentChannelPosition);
            int programPosition = getProgramPosition(currentChannelPosition, Calendar.getInstance().getTimeInMillis());
            currentProgram = epgData.getEvent(currentChannelPosition, programPosition);
    
            //Log.d("wujiang", "setEPGData: Calendar.getInstance().getTimeInMillis() = " + Calendar.getInstance().getTimeInMillis());
            Log.d("wujiang", "setEPGData: programPosition = " + programPosition);
    
            Log.d("wujiang", "setEPGData: channel name = " + serviceList.get(currentChannelPosition).getName());
    
            if (currentProgram == null) {
                Log.d("wujiang", "setEPGData: currentProgram == null");
            }
    
            //暂时不设置被选中的event
            //if (currentProgram != null) {
            //    currentProgram.setSelected(true);
            //}
    
            referenceEventPosition = programPosition;
            //Log.e(TAG, " * * * EPG setEPGData() (referenceEventPosition) " + referenceEventPosition);
            referenceEvent = currentProgram;
        }
    
        @Override
        protected void onLayout(boolean changed, int l, int t, int r, int b) {
    
        }
    
        @Override
        protected void onDraw(Canvas canvas) {
            //super.onDraw(canvas);
            if (epgData != null && epgData.hasData()) {
                mTimeLowerBoundary = getTimeFrom(getScrollX());
                mTimeUpperBoundary = getTimeFrom(getScrollX() + getWidth());
                //Log.e("M_TIME_UPPER",  new Date(mTimeUpperBoundary).toString());
    
                Rect drawingRect = mDrawingRect;
                drawingRect.left = getScrollX();
                drawingRect.top = getScrollY();
                drawingRect.right = drawingRect.left + getWidth();
                drawingRect.bottom = drawingRect.top + getHeight();
    
                //drawChannelListItems(canvas, drawingRect);
                drawEvents(canvas, drawingRect);
                drawTimebar(canvas, drawingRect);
                drawTimeLine(canvas, drawingRect);
    
                //drawResetButton(canvas, drawingRect);
    
                // If scroller is scrolling/animating do scroll. This applies when doing a fling.
                if (mScroller.computeScrollOffset()) {
                    scrollTo(mScroller.getCurrX(), mScroller.getCurrY());
                }
            } else {
                mTimeLowerBoundary = getTimeFrom(getScrollX());
                mTimeUpperBoundary = getTimeFrom(getScrollX() + getWidth());
    
                Rect drawingRect = mDrawingRect;
                drawingRect.left = getScrollX();
                drawingRect.top = getScrollY();
                drawingRect.right = drawingRect.left + getWidth();
                drawingRect.bottom = drawingRect.top + getHeight();
    
                drawBlankEvents(canvas, drawingRect);
                drawTimebar(canvas, drawingRect);
            }
        }
    
        /**
         * This will recalculate boundaries, maximal scroll and scroll to start position which is current time.
         * To be used on device rotation etc since the device height and width will change.
         *
         * @param withAnimation true if scroll to current position should be animated.
         */
        public void recalculateAndRedraw(boolean withAnimation, boolean needDrawSelectedProgram) {
            if (epgData != null && epgData.hasData()) {
                Log.d("wujiang", "recalculateAndRedraw: needDrawSelectedProgram = " + needDrawSelectedProgram);
                mEventNeedSelectedStatus = needDrawSelectedProgram;
                resetBoundaries();
                calculateMaxVerticalScroll();
                calculateMaxHorizontalScroll();
    
                mScroller.startScroll(getScrollX(), getScrollY(), getXPositionStart() - getScrollX(), 0, withAnimation ? 0 : 0);
    
                if (currentProgram == null) {
                    Log.d("wujiang", "recalculateAndRedraw: 11111111111");
                    if (needDrawSelectedProgram == false) {
                        referenceEvent = gotoProgramNotSelect(currentChannelPosition, Calendar.getInstance().getTimeInMillis());
                    } else {
                        referenceEvent = gotoProgram(currentChannelPosition, Calendar.getInstance().getTimeInMillis());
                    }
                } else {
                    Log.d("wujiang", "recalculateAndRedraw: 2222222222");
                    if ((currentProgram.getIntStartTime() > EPGUtil.getCurrentTimeInMillis()) || (currentProgram.getIntStartTime() < EPGUtil.getCurrentTimeInMillis())) {
                        int progPos = getProgramPosition(currentChannelPosition, EPGUtil.getCurrentTimeInMillis());
                        Log.d("wujiang", "recalculateAndRedraw: progPos = " + progPos);
                        EnhancedScheduleGridBean.ScheduleGridBean.ChannelBean.ProgrammeBean event = epgData.getEvent(currentChannelPosition, progPos);
                        if (needDrawSelectedProgram == false) {
                            referenceEvent = gotoProgramNotSelect(currentChannelPosition, event.getIntStartTime());
                        } else {
                            referenceEvent = gotoProgram(currentChannelPosition, event.getIntStartTime());
                        }
                    }
                }
                redraw();
            } else {
                Log.d("wujiang", "recalculateAndRedraw: epgData == null || !epgData.hasData()");
                resetBoundaries();
                redraw();
            }
        }
    
        public void redraw() {
            Log.d("wujiang", "redraw: call this fun");
            invalidate();
            requestLayout();
        }
    
        private EnhancedScheduleGridBean.ScheduleGridBean.ChannelBean.ProgrammeBean gotoProgram(int channelPosition, long time) {
            Log.d("wujiang", "gotoProgram: call this fun, channelPosition = " + channelPosition);
            if (channelPosition > -1 && channelPosition < epgData.getChannelCount()) {
                int programPosition = getProgramPosition(channelPosition, time);
    
                //Log.d("wujiang", "gotoProgram: programPosition = " + programPosition);
    
                if (programPosition != -1) {
                    //Log.d("wujiang", "gotoProgram: 111111111111");
                    epgData.cleanSelection();
                    EnhancedScheduleGridBean.ScheduleGridBean.ChannelBean.ProgrammeBean event = epgData.getEvent(channelPosition, programPosition);
                    event.setSelected(true);
                    currentProgram = event;
                    /*if (epgActivity != null) {
                        //epgActivity.loadEventPosterFromServer(currentProgram);
                        update(currentProgram);
                    } else {
                        Log.e(TAG, "NULLLLLLLLLLLLLLLLLLL");
                    }*/
                    currentChannelPosition = channelPosition;
                    if (isMoveLeft || isMoveRight) {
                        referenceEvent = event;
                    } else {
                        referenceEventPosition = programPosition;
                    }
    
                    ((AndroidNineMainMenu)contextObj).showEpgDetailInfo(currentProgram);
                    return event;
                } else {
                    //Log.d("wujiang", "gotoProgram: 222222222222");
                    //没有EPG信息
                    EnhancedScheduleGridBean.ScheduleGridBean.ChannelBean.ProgrammeBean event = new EnhancedScheduleGridBean.ScheduleGridBean.ChannelBean.ProgrammeBean();
                    epgData.cleanSelection();
    
                    event.setTitle("No Information");
                    event.setIntStartTime(mTimeLowerBoundary);
                    event.setIntStopTime(mTimeUpperBoundary);
                    //Log.d("wujiang", "gotoProgram: mTimeLowerBoundary = " + mTimeLowerBoundary);
                    //Log.d("wujiang", "gotoProgram: mTimeUpperBoundary = " + mTimeUpperBoundary);
                    event.setSelected(true);
                    currentProgram = event;
                    currentChannelPosition = channelPosition;
                    if (isMoveLeft || isMoveRight) {
                        referenceEvent = event;
                    } else {
                        referenceEventPosition = programPosition;
                    }
    
                    ((AndroidNineMainMenu)contextObj).showEpgDetailInfo(currentProgram);
                    return event;
                }
            }
    
            return null;
        }
    
        private EnhancedScheduleGridBean.ScheduleGridBean.ChannelBean.ProgrammeBean gotoProgramNotSelect(int channelPosition, long time) {
            Log.d("wujiang", "gotoProgramNotSelect: call this fun, channelPosition = " + channelPosition);
            if (channelPosition > -1 && channelPosition < epgData.getChannelCount()) {
                int programPosition = getProgramPosition(channelPosition, time);
    
                Log.d("wujiang", "gotoProgramNotSelect: programPosition = " + programPosition);
    
                if (programPosition != -1) {
                    epgData.cleanSelection();
                    EnhancedScheduleGridBean.ScheduleGridBean.ChannelBean.ProgrammeBean event = epgData.getEvent(channelPosition, programPosition);
                    //event.setSelected(true);
                    currentProgram = event;
                    /*if (epgActivity != null) {
                        //epgActivity.loadEventPosterFromServer(currentProgram);
                        update(currentProgram);
                    } else {
                        Log.e(TAG, "NULLLLLLLLLLLLLLLLLLL");
                    }*/
                    currentChannelPosition = channelPosition;
                    if (isMoveLeft || isMoveRight) {
                        referenceEvent = event;
                    } else {
                        referenceEventPosition = programPosition;
                    }
                    return event;
                }
            }
    
            return null;
        }
    
        private int getProgramPosition(int channelPosition, long time) {
            List<EnhancedScheduleGridBean.ScheduleGridBean.ChannelBean.ProgrammeBean> events = epgData.getEvents(channelPosition);
            Log.d("wujiang", "getProgramPosition: events size = " + events.size());
            //Log.d("wujiang", "getProgramPosition: time = " + time);
    
            if (events != null) {
                for (int eventPos = 0; eventPos < events.size(); eventPos++) {
                    EnhancedScheduleGridBean.ScheduleGridBean.ChannelBean.ProgrammeBean event = events.get(eventPos);
                    //Log.d("wujiang", "getProgramPosition: event getIntStartTime = " + event.getIntStartTime());
                    //Log.d("wujiang", "getProgramPosition: event getIntStopTime = " + event.getIntStopTime());
    
                    if ((event.getIntStartTime()) <= time && ((event.getIntStopTime()) > time)) {
                        return eventPos;
                    }
                }
            }
            return -1;
        }
    
        private void calculateMaxVerticalScroll() {
            final int maxVerticalScroll = getTopFrom(epgData.getChannelCount() - 2) + mChannelLayoutHeight;
            mMaxVerticalScroll = maxVerticalScroll < getHeight() ? 0 : maxVerticalScroll - getHeight();
        }
    
        private void calculateMaxHorizontalScroll() {
            long currentFWDMillis = ((LocalDateTime.now().toDateTime().getMillis() + HOURS_IN_VIEWPORT_MILLIS));
            mMaxHorizontalScroll = (int) (mChannelLayoutMargin + mChannelLayoutWidth + (DAYS_BACK_MILLIS + EPGUtil.roundOfTimeToLowerBound(LocalDateTime.now().toDateTime().getMillis()) + HOURS_IN_VIEWPORT_MILLIS + ((LocalDateTime.now().toDateTime().withTime(23, 59, 59, 999).getMillis())) + DAYS_FORWARD_MILLIS) / mMillisPerPixel);
        }
    
        private void drawTimeLine(Canvas canvas, Rect drawingRect) {
            //long now = System.currentTimeMillis();
            long now = EPGUtil.getCurrentTimeInMillis();
    
            if (shouldDrawTimeLine(now)) {
                drawingRect.left = getXFrom(now);
                drawingRect.top = getScrollY();
                drawingRect.right = drawingRect.left + mTimeBarLineWidth;
                drawingRect.bottom = drawingRect.top + mTimeBarHeight;
                mPaint.setColor(mTimeBarLineColor);
                canvas.drawRect(drawingRect, mPaint);
            }
        }
    
        private boolean shouldDrawTimeLine(long now) {
            return now >= mTimeLowerBoundary && now < mTimeUpperBoundary;
        }
    
        private void drawTimebar(Canvas canvas, Rect drawingRect) {
            //drawingRect.left = getScrollX() + mChannelLayoutWidth + mChannelLayoutMargin;
            drawingRect.left = getScrollX() + mChannelLayoutWidth;
            drawingRect.top = getScrollY();
            drawingRect.right = drawingRect.left + getWidth();
            drawingRect.bottom = drawingRect.top + mTimeBarHeight;
    
            //Log.d("wujiang", "drawTimebar: getScrollX = " + getScrollX());
            //Log.d("wujiang", "drawTimebar: drawingRect.left = " + drawingRect.left);
    
            //mClipRect.left = getScrollX() + mChannelLayoutWidth + mChannelLayoutMargin;
            mClipRect.left = getScrollX() + mChannelLayoutWidth;
            mClipRect.top = getScrollY();
            mClipRect.right = drawingRect.left + getWidth();//getScrollX() + getWidth();
            mClipRect.bottom = mClipRect.top + mTimeBarHeight;
    
            //Log.d("wujiang", "drawTimebar: mClipRect.left = " + mClipRect.left);
    
            canvas.save();
            canvas.clipRect(mClipRect);
    
            // Background
            mPaint.setColor(mTimerBarBackground);
            canvas.drawRect(drawingRect, mPaint);
    
            // Time stamps
            mPaint.setColor(mEventLayoutTextColor);
            mPaint.setTextSize(mTimeBarTextSize);
    
            for (int i = 0; i < HOURS_IN_VIEWPORT_MILLIS / TIME_LABEL_SPACING_MILLIS; i++) {
                // Get time and round to nearest half hour
                final long time = TIME_LABEL_SPACING_MILLIS *
                        (((mTimeLowerBoundary + (TIME_LABEL_SPACING_MILLIS * i)) +
                                (TIME_LABEL_SPACING_MILLIS / 2)) / TIME_LABEL_SPACING_MILLIS);
    
                mPaint.setColor(mEventLayoutTextColor);
    
                canvas.drawText(EPGUtil.getShortTime(time), getXFrom(time),
                        drawingRect.top + (((drawingRect.bottom - drawingRect.top) / 2) + (mTimeBarTextSize / 2)), mPaint);
    
    //                  mPaint.setColor(mEPGBackground);
    //                  canvas.drawLine(getXFrom(time), drawingRect.top, getXFrom(time), drawingRect.bottom, mPaint);
            }
    
            canvas.restore();
            //drawTimebarDayIndicator(canvas, drawingRect);
            drawTime();
            drawTimebarBottomStroke(canvas, drawingRect);
        }
    
        private void drawTime() {
            ((AndroidNineMainMenu) contextObj).setEpgDateTextViewString(EPGUtil.getWeekdayName(mTimeLowerBoundary));
        }
    
        private void drawTimebarDayIndicator(Canvas canvas, Rect drawingRect) {
            drawingRect.left = getScrollX();
            drawingRect.top = getScrollY();
            drawingRect.right = drawingRect.left + mChannelLayoutWidth;
            drawingRect.bottom = drawingRect.top + mTimeBarHeight;
    
            // Background
            mPaint.setColor(mChannelLayoutBackground);
            canvas.drawRect(drawingRect, mPaint);
    
            // Text
            mPaint.setColor(mEventLayoutTextColor);
            mPaint.setTextSize(mTimeBarTextSize);
            mPaint.setTextAlign(Paint.Align.CENTER);
    
            if (EPGUtil.getWeekdayName(mTimeLowerBoundary).equals("Today")) {
                canvas.drawText(EPGUtil.getWeekdayName(mTimeLowerBoundary),
                        drawingRect.left + ((drawingRect.right - drawingRect.left) / 2),
                        drawingRect.top + (((drawingRect.bottom - drawingRect.top) / 2) + (mTimeBarTextSize / 2)), mPaint);
            } else {
                // java.lang.ArrayIndexOutOfBoundsException: length=1; index=1  canvas.drawText(tmpStr[1],
                String tmpStr[] = EPGUtil.getWeekdayName(mTimeLowerBoundary).split("\n");
                canvas.drawText(tmpStr[0],
                        drawingRect.left + ((drawingRect.right - drawingRect.left) / 2),
                        drawingRect.top + (((drawingRect.bottom - drawingRect.top) / 4)) + (mTimeBarTextSize / 2), mPaint);
    
                canvas.drawText(tmpStr[1],
                        drawingRect.left + ((drawingRect.right - drawingRect.left) / 2),
                        drawingRect.top + (((drawingRect.bottom - drawingRect.top) / 2) + (mTimeBarTextSize)), mPaint);
                tmpStr = null;
            }
            mPaint.setTextAlign(Paint.Align.LEFT);
        }
    
        private void drawTimebarBottomStroke(Canvas canvas, Rect drawingRect) {
            drawingRect.left = getScrollX();
            drawingRect.top = getScrollY() + mTimeBarHeight;
            drawingRect.right = drawingRect.left + getWidth();
            drawingRect.bottom = drawingRect.top + mChannelLayoutMargin;
            // Bottom stroke
            mPaint.setColor(mEPGBackground);
            canvas.drawRect(drawingRect, mPaint);
        }
    
        private void drawChannelListItems(Canvas canvas, Rect drawingRect) {
            //Log.d("wujiang", "drawChannelListItems: call this fun");
            mMeasuringRect.left = getScrollX();
            mMeasuringRect.top = getScrollY();
            mMeasuringRect.right = drawingRect.left + mChannelLayoutWidth;
            mMeasuringRect.bottom = mMeasuringRect.top + getHeight();
    
            final int firstPos = getFirstVisibleChannelPosition();
            final int lastPos = getLastVisibleChannelPosition();
    
            for (int pos = firstPos; pos <= lastPos; pos++) {
                drawChannelItem(canvas, pos, drawingRect);
            }
        }
    
        private void drawEvents(Canvas canvas, Rect drawingRect) {
            //Log.d("wujiang", "drawEvents: call this fun");
            final int firstPos = getFirstVisibleChannelPosition();
            final int lastPos = getLastVisibleChannelPosition();
    
            for (int pos = firstPos; pos <= lastPos; pos++) {
                // Set clip rectangle
                mClipRect.left = getScrollX() + mChannelLayoutWidth + mChannelLayoutMargin;
                mClipRect.top = getTopFrom(pos);
                mClipRect.right = getScrollX() + getWidth();
                mClipRect.bottom = mClipRect.top + mChannelLayoutHeight;
    
                canvas.save();
                canvas.clipRect(mClipRect);
    
                // Draw each event
                boolean foundFirst = false;
    
                List<EnhancedScheduleGridBean.ScheduleGridBean.ChannelBean.ProgrammeBean> epgEvents = epgData.getEvents(pos);
                //Log.d("wujiang", "drawEvents: epgEvents size = " + epgEvents.size());
                if (epgEvents.size() <= 0) {
                    //该频道没有EPG信息
                    //Log.d("wujiang", "drawEvents: 11111111");
                    drawNoInforEvent(canvas, pos, drawingRect);
                } else {
                    //Log.d("wujiang", "drawEvents: 222222222");
                    for (EnhancedScheduleGridBean.ScheduleGridBean.ChannelBean.ProgrammeBean event : epgEvents) {
                        if (isEventVisible(event.getIntStartTime(), event.getIntStopTime())) {
                            //Log.d("wujiang", "drawEvents: 3333333");
                            drawEvent(canvas, pos, event, drawingRect);
                            foundFirst = true;
                        } else if (foundFirst) {
                            break;
                        }
                    }
    
                    if (foundFirst == false) {
                        //Log.d("wujiang", "drawEvents: 44444444");
                        drawNoInforEvent(canvas, pos, drawingRect);
                    }
                }
    
                canvas.restore();
            }
        }
    
        private void drawBlankEvents(Canvas canvas, Rect drawingRect) {
            final int firstPos = getFirstVisibleChannelPosition();
            final int lastPos = getLastBlankLineChannelPosition();
    
            for (int pos = firstPos; pos <= lastPos; pos++) {
                mClipRect.left = getScrollX() + mChannelLayoutWidth + mChannelLayoutMargin;
                mClipRect.top = getTopFrom(pos);
                mClipRect.right = getScrollX() + getWidth();
                mClipRect.bottom = mClipRect.top + mChannelLayoutHeight;
    
                canvas.save();
                canvas.clipRect(mClipRect);
    
                mPaint.setColor(mEventLayoutBackground);
                canvas.drawRect(mClipRect, mPaint);
    
                canvas.restore();
            }
        }
    
        private void drawNoInforEvent(final Canvas canvas, final int channelPosition, final Rect drawingRect) {
            //Log.d("wujiang", "drawNoInforEvent: call this function");
    
            String title = "No Information";
            setEventDrawingRectangle(channelPosition, mTimeLowerBoundary, mTimeUpperBoundary, drawingRect, title);
    
            // Background
            mPaint.setColor(drawCurrentTimeLine ? mEventLayoutBackgroundCurrent : mEventLayoutBackground);
    
            if (currentChannelPosition == channelPosition && mEventNeedSelectedStatus == true) {
                mPaint.setColor(mEventLayoutSelected);
            }
            canvas.drawRect(drawingRect, mPaint);
    
            // Add left and right inner padding
            drawingRect.left += mChannelLayoutPadding;
            drawingRect.right -= mChannelLayoutPadding;
    
            // Text
            mPaint.setColor(mEventLayoutTextColor);
            mPaint.setTextSize(mEventLayoutTextSize);
    
            // Move drawing.top so text will be centered (text is drawn bottom>up)
            mPaint.getTextBounds(title, 0, title.length(), mMeasuringRect);
            drawingRect.top += (((drawingRect.bottom - drawingRect.top) / 2) + (mMeasuringRect.height() / 2));
    
            // Text
            if (currentChannelPosition == channelPosition && mEventNeedSelectedStatus == true) {
                mPaint.setColor(Color.YELLOW);
                mPaint.setTextSize(mEventLayoutTextSize);
            } else {
                mPaint.setColor(mEventLayoutTextColor);
                mPaint.setTextSize(mEventLayoutTextSize);
            }
    
            //NEW CHANGES USING SHOW_TYPE of EVENT
            title = title.substring(0, mPaint.breakText(title, true, drawingRect.right - drawingRect.left, null));
    
            TextPaint textPaint = new TextPaint(Paint.LINEAR_TEXT_FLAG | Paint.ANTI_ALIAS_FLAG);
            textPaint.setColor(mPaint.getColor());
            textPaint.setTextSize(mPaint.getTextSize());
            textPaint.setStyle(mPaint.getStyle());
    
            CharSequence txt = null;
            txt = TextUtils.ellipsize(title, textPaint, (drawingRect.right - drawingRect.left) - 10, TextUtils.TruncateAt.END);
            canvas.drawText(txt, 0, txt.length(), drawingRect.left, drawingRect.top, textPaint);
        }
    
        private void drawEvent(final Canvas canvas, final int channelPosition, final EnhancedScheduleGridBean.ScheduleGridBean.ChannelBean.ProgrammeBean event, final Rect drawingRect) {
            setEventDrawingRectangle(channelPosition, event.getIntStartTime(), event.getIntStopTime(), drawingRect, event.getTitle());
    
            // Background
            mPaint.setColor(event.isCurrent() && drawCurrentTimeLine ? mEventLayoutBackgroundCurrent : mEventLayoutBackground);
    
            if (event.isSelected()) {
                mPaint.setColor(mEventLayoutSelected);
            }
    
            canvas.drawRect(drawingRect, mPaint);
    
            // Add left and right inner padding
            drawingRect.left += mChannelLayoutPadding;
            drawingRect.right -= mChannelLayoutPadding;
    
            // Text
            mPaint.setColor(mEventLayoutTextColor);
            mPaint.setTextSize(mEventLayoutTextSize);
    
            //Log.e("TAG", " @ @ @ @ " + event.getGenres());
            // Set Genre
            Rect genreBackgroundRect = null;
            ServiceInfoEntity serviceInfoEntity = serviceList.get(getServiceIndexInList((int) event.getChannelNumber()));
    
            if (genreBackgroundRect == null) {
                genreBackgroundRect = new Rect();
                genreBackgroundRect.set(drawingRect.left, drawingRect.top + mTimeBarHeight + 10, (int) (drawingRect.left), drawingRect.bottom - 5);
            }
    
            // Move drawing.top so text will be centered (text is drawn bottom>up)
            mPaint.getTextBounds(event.getTitle(), 0, event.getTitle().length(), mMeasuringRect);
            drawingRect.top += (((drawingRect.bottom - drawingRect.top) / 2) + (mMeasuringRect.height() / 2));
            // Text
            if (event.isSelected()) {
                mPaint.setColor(Color.YELLOW);
                mPaint.setTextSize(mEventLayoutTextSize);
            } else {
                mPaint.setColor(mEventLayoutTextColor);
                mPaint.setTextSize(mEventLayoutTextSize);
            }
    
            //NEW CHANGES USING SHOW_TYPE of EVENT
            String title = null;
    
            title = event.getTitle();
    
            title = title.substring(0, mPaint.breakText(title, true, drawingRect.right - drawingRect.left, null));
    
            TextPaint textPaint = new TextPaint(Paint.LINEAR_TEXT_FLAG | Paint.ANTI_ALIAS_FLAG);
            textPaint.setColor(mPaint.getColor());
            textPaint.setTextSize(mPaint.getTextSize());
            textPaint.setStyle(mPaint.getStyle());
    
            CharSequence txt = null;
    
            if (event.getIntStartTime() < mTimeLowerBoundary) {
                //canvas.drawText(title, getXFrom(mTimeLowerBoundary) + 10, drawingRect.top - 5, mPaint);
                txt = TextUtils.ellipsize(title, textPaint, (drawingRect.right - getXFrom(mTimeLowerBoundary)) - 10, TextUtils.TruncateAt.END);
                canvas.drawText(txt, 0, txt.length(), getXFrom(mTimeLowerBoundary) + 10, drawingRect.top, textPaint);
            } else {
                //canvas.drawText(title, drawingRect.left, drawingRect.top - 5, mPaint);
                txt = TextUtils.ellipsize(title, textPaint, (drawingRect.right - drawingRect.left) - 10, TextUtils.TruncateAt.END);
                canvas.drawText(txt, 0, txt.length(), drawingRect.left, drawingRect.top, textPaint);
            }
        }
    
        private void setEventDrawingRectangle(final int channelPosition, final long start, final long end, final Rect drawingRect, String eventName) {
            if (start < mTimeOffset) {
                drawingRect.left = getXFrom(mTimeOffset);
            } else {
                drawingRect.left = getXFrom(start);
            }
    
            drawingRect.top = getTopFrom(channelPosition);
            drawingRect.right = getXFrom(end) - mChannelLayoutMargin;
    
            drawingRect.bottom = drawingRect.top + mChannelLayoutHeight;
        }
    
        private int getFirstVisibleChannelPosition() {
            final int y = getScrollY();
            int position = (y - mChannelLayoutMargin - mTimeBarHeight) / (mChannelLayoutHeight + mChannelLayoutMargin);
    
            if (position < 0) {
                position = 0;
            }
            return position;
        }
    
        private int getLastVisibleChannelPosition() {
            final int y = getScrollY();
            final int totalChannelCount = epgData.getChannelCount();
            final int screenHeight = getHeight();
            int position = (y + screenHeight + mTimeBarHeight - mChannelLayoutMargin) / (mChannelLayoutHeight + mChannelLayoutMargin);
    
            if (position > totalChannelCount - 1) {
                position = totalChannelCount - 1;
            }
    
            // Add one extra row if we don't fill screen with current..
            return (y + screenHeight) > (position * mChannelLayoutHeight) && position < totalChannelCount - 1 ? position + 1 : position;
        }
    
        private int getLastBlankLineChannelPosition() {
            final int y = getScrollY();
            final int totalChannelCount = 6;
            final int screenHeight = getHeight();
            int position = (y + screenHeight + mTimeBarHeight - mChannelLayoutMargin) / (mChannelLayoutHeight + mChannelLayoutMargin);
    
            if (position > totalChannelCount - 1) {
                position = totalChannelCount - 1;
            }
    
            // Add one extra row if we don't fill screen with current..
            return (y + screenHeight) > (position * mChannelLayoutHeight) && position < totalChannelCount - 1 ? position + 1 : position;
        }
    
        private boolean isEventVisible(final long start, final long end) {
            return (start >= mTimeLowerBoundary && start <= mTimeUpperBoundary)
                    || (end >= mTimeLowerBoundary && end <= mTimeUpperBoundary)
                    || (start <= mTimeLowerBoundary && end >= mTimeUpperBoundary);
        }
    
        private void drawChannelItem(final Canvas canvas, int position, Rect drawingRect) {
            Rect drawingRect1 = new Rect();
            drawingRect.left = getScrollX();
            drawingRect.top = getTopFrom(position);
            drawingRect.right = drawingRect.left + mChannelLayoutWidth / 2;
            drawingRect.bottom = drawingRect.top + mChannelLayoutHeight;
    
            //mPaint.setColor(mChannelLayoutBackground);
            mPaint.setColor(mRedColor);
    
            canvas.drawRect(drawingRect, mPaint);
    
            mPaint.setTextAlign(Paint.Align.CENTER);
            //Channel-no
            //mPaint.setColor(mEventLayoutTextColor);
            mPaint.setColor(mColorPrimaryDark);
            mPaint.setTextSize(mEventLayoutTextSize - 2);
            canvas.drawText(Long.toString(epgData.getChannel(position).getChannelNumber()), drawingRect.centerX(), drawingRect.centerY() + 10, mPaint);
    
            drawingRect1.left = getScrollX() + mChannelLayoutWidth / 2;
            drawingRect1.top = getTopFrom(position);
            drawingRect1.right = drawingRect1.left + mChannelLayoutWidth / 2;
            drawingRect1.bottom = drawingRect1.top + mChannelLayoutHeight;
    
            mPaint.setColor(mTimeBarLineColor);
            canvas.drawRect(drawingRect1, mPaint);
    
            mPaint.setTextAlign(Paint.Align.CENTER);
            mPaint.setColor(mColorPrimaryDark);
            mPaint.setTextSize(mEventLayoutTextSize - 2);
            canvas.drawText(epgData.getChannel(position).getName(), drawingRect1.centerX(), drawingRect1.centerY() + 10, mPaint);
        }
    
        void resetBoundaries() {
            mMillisPerPixel = calculateMillisPerPixel();
            mTimeOffset = calculatedBaseLine();
            mTimeLowerBoundary = getTimeFrom(0);
            mTimeUpperBoundary = getTimeFrom(getWidth());
        }
    
        private long calculateMillisPerPixel() {
            return HOURS_IN_VIEWPORT_MILLIS / (getResources().getDisplayMetrics().widthPixels - mChannelLayoutWidth - mChannelLayoutMargin);
        }
    
        private long calculatedBaseLine() {
            DateTime dateTime = new DateTime(LocalDateTime.now().toDateTime().getMillis()).minusMillis(DAYS_BACK_MILLIS);
            if (DAYS_BACK_MILLIS > 0) {
                //Log.e(TAG, " @ calculatedBaseLine with CU/SO @ " + dateTime.withTimeAtStartOfDay().toString());
                return dateTime.withTimeAtStartOfDay().getMillis();
            } else {
                //Log.e(TAG, " @ calculatedBaseLine @ " + new Date(EPGUtils.roundOfTimeToLowerBound(dateTime.getMillis())));
                return EPGUtil.roundOfTimeToLowerBound(dateTime.getMillis());
            }
        }
    
        /**
         * @param x 像素值(某个地方距epg起始地方的偏移值)
         * @return 得到x地方的时刻,单位毫秒
         */
        private long getTimeFrom(int x) {
            return (x * mMillisPerPixel) + mTimeOffset;
        }
    
        /**
         * @param position 可以理解成第几个节目
         * @return 第position节目显示区域顶部位置像素值
         */
        private int getTopFrom(int position) {
            int y = position * (mChannelLayoutHeight + mChannelLayoutMargin) + mChannelLayoutMargin + mTimeBarHeight;
            return y;
        }
    
        private int getXFrom(long time) {
            return (int) ((time - mTimeOffset) / mMillisPerPixel) + mChannelLayoutMargin + mChannelLayoutWidth + mChannelLayoutMargin;
        }
    
        public int getServiceIndexInList(int channelNo) {
            for (int i = 0; i < serviceList.size(); ++i) {
                if (serviceList.get(i).getChannelNumber() == channelNo)
                    return i;
            }
            return 0;
        }
    
        private int getXPositionStart() {
            //Log.e(TAG, " @ @ getXPositionStart @ @ " + new Date(EPGUtils.roundOfTimeToLowerBound(System.currentTimeMillis())));
            if (DAYS_BACK_MILLIS > 0) {
                int temp = getXFrom(EPGUtil.roundOfTimeToLowerBound(System.currentTimeMillis())) - mChannelLayoutMargin - mChannelLayoutWidth;
                //Log.e(TAG, " @ @ getXPositionStart @ @ " + temp);
                return temp;
            } else {
                return 0;
            }
        }
    
        private boolean isEventStartTimeVisible(final long start) {
            return (start >= mTimeLowerBoundary || start <= mTimeUpperBoundary);
        }
    
        private Rect calculateProgramsHitArea() {
            mMeasuringRect.top = mTimeBarHeight;
            int visibleChannelsHeight = epgData.getChannelCount() * (mChannelLayoutHeight + mChannelLayoutMargin);
            mMeasuringRect.bottom = visibleChannelsHeight < getHeight() ? visibleChannelsHeight : getHeight();
            mMeasuringRect.left = mChannelLayoutWidth;
            mMeasuringRect.right = getWidth();
            return mMeasuringRect;
        }
    
        public void moveRight() {
            if (currentProgram != null) {
                List<EnhancedScheduleGridBean.ScheduleGridBean.ChannelBean.ProgrammeBean> events = epgData.getEvents(currentChannelPosition);
                if (events != null && events.size() > 0 && (currentProgram.getIntStartTime() == events.get(events.size() - 1).getIntStartTime())) {
                    //Log.d("wujiang", "moveRight: it is last event");
                    return;
                }
    
                isMoveRight = true;
                isMoveLeft = false;
                gotoProgram(currentChannelPosition, currentProgram.getIntStopTime() + 1);
                invalidate();
    
                int x = 0;
    
                long dur = currentProgram.getIntStopTime() - currentProgram.getIntStartTime();
                long currentUpperBound = EPGUtil.roundOfTimeToLowerBound(currentProgram.getIntStartTime()) + HOURS_IN_VIEWPORT_MILLIS;
                if (dur > HOURS_IN_VIEWPORT_MILLIS && !isEventStartTimeVisible(currentProgram.getIntStartTime())) {
                    //Log.d("wujiang", "moveRight: 1111111111111111");
                    if (EPGUtil.roundOfTimeToLowerBound(currentProgram.getIntStartTime()) != currentProgram.getIntStartTime()) {
                        x = getXFrom(currentProgram.getIntStartTime() + ((30 * 60 * 1000) - (currentProgram.getIntStartTime() - EPGUtil.roundOfTimeToLowerBound(currentProgram.getIntStartTime()))));
                    } else {
                        x = getXFrom(currentProgram.getIntStartTime() + (HOURS_IN_VIEWPORT_MILLIS - 30 * 60 * 1000));
                    }
                    //x = getXFrom((currentProgram.getStart() - EPGUtils.roundOfTimeToLowerBound(currentProgram.getStart())) + HOURS_IN_VIEWPORT_MILLIS);
                } else if (dur > HOURS_IN_VIEWPORT_MILLIS) {
                    //Log.d("wujiang", "moveRight: 22222222222");
                    if (EPGUtil.roundOfTimeToLowerBound(currentProgram.getIntStartTime()) != currentProgram.getIntStartTime()) {
                        x = getXFrom(currentProgram.getIntStartTime() + ((60 * 60 * 1000) - ((currentProgram.getIntStartTime() - EPGUtil.roundOfTimeToLowerBound(currentProgram.getIntStartTime())))));
                    } else {
                        x = getXFrom(currentProgram.getIntStartTime() + (HOURS_IN_VIEWPORT_MILLIS - 60 * 60 * 1000));
                    }
                } else if (EPGUtil.roundOfTimeToLowerBound(currentProgram.getIntStartTime()) != currentProgram.getIntStartTime()) {
                    //Log.d("wujiang", "moveRight: 33333333333333");
                    x = getXFrom(currentProgram.getIntStartTime() + ((30 * 60 * 1000) - (currentProgram.getIntStartTime() - EPGUtil.roundOfTimeToLowerBound(currentProgram.getIntStartTime()))));
                } else {
                    //Log.d("wujiang", "moveRight: 444444444444444");
                    x = getXFrom(currentProgram.getIntStartTime() + (30 * 60 * 1000));
                }
    
                //EPGUtils.printTime("MoveRight", mTimeUpperBoundary);
                //int x = getXFrom(currentProgram.getEndTime());
    
                //Log.d("wujiang", "moveRight: x = " + x);
                //Log.d("wujiang", "moveRight: getScrollX() = " + getScrollX());
                //Log.d("wujiang", "moveRight: getWidth() = " + getWidth());
                int programAreaX = calculateProgramsHitArea().right + getScrollX();
    
                //Log.d("wujiang", "moveRight: calculateProgramsHitArea().right = " + calculateProgramsHitArea().right);
    
                if (x > programAreaX) {
                    scrollBy(x - programAreaX - 30, 0);
                }
            }
        }
    
        public void moveLeft() {
            if (currentProgram != null) {
                if (currentProgram.getIntStartTime() <= mTimeOffset) {
                    //Log.d("wujiang", "moveLeft: 1111111");
                    return;
                }
    
                isMoveRight = false;
                isMoveLeft = true;
                gotoProgram(currentChannelPosition, currentProgram.getIntStartTime() - 1);
                invalidate();
                int x = 0;//getXFrom(currentProgram.getStartTime());
                if (currentProgram.getIntStartTime() < mTimeOffset) {
                    x = getXFrom(mTimeOffset);
                } else {
                    x = getXFrom(EPGUtil.roundOfTimeToLowerBound(currentProgram.getIntStartTime()));
                }
    
                int programAreaX = calculateProgramsHitArea().left + getScrollX();
                if (x < programAreaX) {
                    scrollBy(x - programAreaX, 0);
                }
            } else {
                Log.e("wujiang", " @ MoveLeft @ I think CatchUp is enabled");
            }
        }
    
        public boolean moveDown() {
            if (currentProgram != null) {
                isMoveRight = false;
                isMoveLeft = false;
                long time = 0;
    
                if (referenceEvent.getIntStartTime() < mTimeOffset) {
                    time = mTimeOffset + 1;
                } else if (referenceEvent.isCurrent() && referenceEvent.getIntStartTime() < EPGUtil.roundOfTimeToLowerBound(System.currentTimeMillis())) {
                    time = EPGUtil.roundOfTimeToLowerBound(System.currentTimeMillis()) + 1;
                } else {
                    time = EPGUtil.roundOfTimeToLowerBound(referenceEvent.getIntStartTime()) + 1;
                }
                //Log.e("wujiang", " moveDown: mTimeOffset = " + mTimeOffset);
                //Log.e("wujiang", " moveDown: currentChannelPosition = " + currentChannelPosition);
                //Log.e("wujiang", " moveDown: time = " + time);
    
                gotoProgram(currentChannelPosition + 1, time);
                invalidate();
                int y = getTopFrom(currentChannelPosition);
                int programAreaY = calculateProgramsHitArea().bottom + getScrollY() - mChannelLayoutHeight;
                if (y > programAreaY) {
                    scrollBy(0, y - programAreaY);
                }
    
                if (currentChannelPosition >= (epgData.getChannelCount() - 1)) {
                    //Log.d("wujiang", "moveDown: 11111111111");
                    return true;
                }
            }
    
            //Log.d("wujiang", "moveDown: 2222222222");
            return false;
        }
    
        public void moveUp() {
            if (currentProgram != null) {
                isMoveRight = false;
                isMoveLeft = false;
                //ORG
                //long time = (currentProgram.getStartTime() + currentProgram.getEndTime()) / 2;
                long time = 0;
    
                if (referenceEvent.getIntStartTime() < mTimeOffset) {
                    time = mTimeOffset + 1;
                } else if (referenceEvent.isCurrent() && referenceEvent.getIntStartTime() < EPGUtil.roundOfTimeToLowerBound(System.currentTimeMillis())) {
                    time = EPGUtil.roundOfTimeToLowerBound(System.currentTimeMillis()) + 1;
                } else {
                    time = EPGUtil.roundOfTimeToLowerBound(referenceEvent.getIntStartTime()) + 1;
                }
                gotoProgram(currentChannelPosition - 1, time);
                invalidate();
                int y = getTopFrom(currentChannelPosition);
                int programAreaY = calculateProgramsHitArea().top + getScrollY();
                if (y < programAreaY) {
                    scrollBy(0, y - programAreaY);
                }
            }
        }
    
        public void moveToDestPosition(int position, int direction) {
            if (currentProgram != null) {
                isMoveRight = false;
                isMoveLeft = false;
                long time = 0;
    
                if (referenceEvent.getIntStartTime() < mTimeOffset) {
                    time = mTimeOffset + 1;
                } else if (referenceEvent.isCurrent() && referenceEvent.getIntStartTime() < EPGUtil.roundOfTimeToLowerBound(System.currentTimeMillis())) {
                    time = EPGUtil.roundOfTimeToLowerBound(System.currentTimeMillis()) + 1;
                } else {
                    time = EPGUtil.roundOfTimeToLowerBound(referenceEvent.getIntStartTime()) + 1;
                }
    
                gotoProgram(position, time);
                invalidate();
                int y = getTopFrom(position);
    
                if (direction == UP_DIRECTION) {
                    int programAreaY = calculateProgramsHitArea().top + getScrollY();
                    if (y < programAreaY) {
                        scrollBy(0, y - programAreaY);
                    }
                } else {
                    int programAreaY = calculateProgramsHitArea().bottom + getScrollY() - mChannelLayoutHeight;
                    if (y > programAreaY) {
                        scrollBy(0, y - programAreaY);
                    }
                }
            }
        }
    }

     这里重点是如下几个函数:drawEvents,drawTimebar,drawTimeLine,moveToDestPosition。

    2、在显示epg信息的activity里的布局文件中使用自定义EPG View,代码如下:

    <!-- 时刻表、节目列表和7天epg -->
    <RelativeLayout
        android:id="@+id/epg_view_area"
        android:layout_width="match_parent"
        android:layout_height="235dp"
        android:layout_alignParentBottom="true"
        android:background="@android:color/transparent"
        android:visibility="gone">
    
        <!-- epg 信息的当前时间、节目列表 -->
        <LinearLayout
            android:id="@+id/recyclerView_channel_list_area"
            android:layout_width="272dp"
            android:layout_height="match_parent"
            android:orientation="vertical">
    
            <!-- epg 信息的当前时间 -->
            <TextView
                android:id="@+id/epg_date"
                android:layout_width="match_parent"
                android:layout_height="31dp"
                android:background="@color/color_epg_focus"
                android:gravity="center"
                android:textColor="@color/epg_event_layout_text" />
    
            <!-- 节目列表 -->
            <ListView
                android:id="@+id/listview_channel_list"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:background="@color/translucent_black"
                android:dividerHeight="1dp"
                android:listSelector="@drawable/epg_channel_recyclerview_item_selector">
            </ListView>
        </LinearLayout>
    
        <!-- 7天EPG信息 -->
        <com.amlogic.dvb_custom_view.EpgView
            android:id="@+id/epg_view"
            android:layout_width="700dp"
            android:layout_height="match_parent"
            android:layout_toRightOf="@+id/recyclerView_channel_list_area">
        </com.amlogic.dvb_custom_view.EpgView>
    
    </RelativeLayout>
    listview_channel_list是显示节目名称的listview,在它的上方显示的是当前EPG信息所属的时间。

    3、进入DVB时加载所有节目的EPG信息,一般是7天的EPG。这个时候显示EPG信息的那个activity还没有显示。

    public static HashMap<ServiceInfoEntity, List<EnhancedScheduleGridBean.ScheduleGridBean.ChannelBean.ProgrammeBean>> result;

      这是一个哈希列表,Key对应的是节目,Value对应的是这个节目7天EPG的链表。

    for (int i = 0; i < channel_list.size(); i++) {
        ServiceInfoEntity serviceObj = channel_list.get(i);
        result.put(serviceObj, loadEpgFromDB(serviceObj, i));
    }

      把所有节目节目的epg信息存放到result里。

    4、在显示EPG信息的activity里加载epg信息,并可以上下左右切换。

    public static HashMap<ServiceInfoEntity, List<EnhancedScheduleGridBean.ScheduleGridBean.ChannelBean.ProgrammeBean>> mResult;
    public static EPGData mEpgData;

      //节目一般情况下会有分组,下面的代码是根据组的index过滤出对应的节目

    List<ServiceInfoEntity> serviceInfoEntities = ChannelListUtils.getServicesFromCachedAndDb(AndroidNineMainMenu.this, mChannelGruopInfoList.get(position));

      //加载组里的节目对用的EPG信息

    mResult.clear();
    
    for (int i = 0; i < serviceInfoEntities.size(); i++) {
        ServiceInfoEntity serviceInfoEntity = serviceInfoEntities.get(i);
    
        //DVBPlayer.result就是第3步那里的result
        if (DVBPlayer.result.get(serviceInfoEntity) != null) {
            mResult.put(serviceInfoEntity, DVBPlayer.result.get(serviceInfoEntity));
        }
    }
    
    mEpgData = new EPGDataImpl(mResult);
    mEpgData.cleanSelection();
    mChannelListviewAdapter.setEpgData(mEpgData);
    mEpgView.setEPGData(AndroidNineMainMenu.this, mEpgData);
    mEpgView.recalculateAndRedraw(false, false);

      相关类的代码

    public interface EPGData {
        ServiceInfoEntity getChannel(int position);
    
        List<EnhancedScheduleGridBean.ScheduleGridBean.ChannelBean.ProgrammeBean> getEvents(int channelPosition);
    
        List<ServiceInfoEntity> getChannels();
    
        //CircularArray<Event> getEventsC(int channelPosition);
    
        EnhancedScheduleGridBean.ScheduleGridBean.ChannelBean.ProgrammeBean getEvent(int channelPosition, int programPosition);
    
        String getStartOverStatus(EnhancedScheduleGridBean.ScheduleGridBean.ChannelBean.ProgrammeBean event);
    
        String getCatchUpStatus(EnhancedScheduleGridBean.ScheduleGridBean.ChannelBean.ProgrammeBean event);
    
        int getChannelCount();
    
        boolean hasData();
    
        void cleanSelection();
    }
    
    public class EPGDataImpl implements EPGData {
        private List<ServiceInfoEntity> channels = Lists.newArrayList();
        private List<List<EnhancedScheduleGridBean.ScheduleGridBean.ChannelBean.ProgrammeBean>> events = Lists.newArrayList();
    
    
        public EPGDataImpl(Map<ServiceInfoEntity, List<EnhancedScheduleGridBean.ScheduleGridBean.ChannelBean.ProgrammeBean>> data) {
    
            if (data == null || data.isEmpty()) {
                Log.d("wujiang", "EPGDataImpl: data == null || data.isEmpty()");
                return;
            }
            channels = Lists.newArrayList(data.keySet());
            events = Lists.newArrayList(data.values());
    
            Log.d("wujiang", "EPGDataImpl: channels size = " + channels.size());
            Log.d("wujiang", "EPGDataImpl: events size = " + events.size());
        }
    
        public List<ServiceInfoEntity> getChannels() {
            return channels;
        }
    
        public ServiceInfoEntity getChannel(int position) {
            if (channels == null || channels.size() < 1) {
                return null;
            } else {
                return channels.get(position);
            }
    
        }
    
        public List<EnhancedScheduleGridBean.ScheduleGridBean.ChannelBean.ProgrammeBean> getEvents(int channelPosition) {
            if (events == null || events.size() < 1) {
                return null;
            } else {
                return events.get(channelPosition);
            }
        }
    
        public EnhancedScheduleGridBean.ScheduleGridBean.ChannelBean.ProgrammeBean getEvent(int channelPosition, int programPosition) {
            EnhancedScheduleGridBean.ScheduleGridBean.ChannelBean.ProgrammeBean e = null;
    
            try {
                e = events.get(channelPosition).get(programPosition);
            } catch (Exception ex) {
                Log.e("EPGImpl", "" + Log.getStackTraceString(ex));
                Log.e("EPGImpl", "channelPosition " + channelPosition + " programPosition " + programPosition);
            }
            return e;
        }
    
        @Override
        public String getCatchUpStatus(EnhancedScheduleGridBean.ScheduleGridBean.ChannelBean.ProgrammeBean event) {
            /*ServiceInfoEntity tmp = null;
            long chNo = event.getChannelNumber();
            for(ServiceInfoEntity s : channels) {
                if(s.getChannelNumber() == chNo) {
                    tmp = s;
                } else {
                    tmp = channels.get(0);
                }
            }
    
            if(tmp == null)
                tmp = channels.get(0);
    
            return tmp.getCatchup();*/
    
            return null;
        }
    
        @Override
        public String getStartOverStatus(EnhancedScheduleGridBean.ScheduleGridBean.ChannelBean.ProgrammeBean event) {
           /* ServiceInfoEntity tmp = null;
            long chNo = event.getChannelNumber();
            for(ServiceInfoEntity s : channels) {
                if(s.getChannelNumber() == chNo) {
                    tmp = s;
                } else {
                    tmp = channels.get(0);
                }
            }
    
            if(tmp == null)
                tmp = channels.get(0);
    
            return tmp.getStartover();*/
            return null;
        }
    
        public int getChannelCount() {
            return channels.size();
    
        }
    
        @Override
        public boolean hasData() {
            return !channels.isEmpty();
        }
    
        @Override
        public void cleanSelection() {
            for (List<EnhancedScheduleGridBean.ScheduleGridBean.ChannelBean.ProgrammeBean> channelEvents : this.events) {
                for (EnhancedScheduleGridBean.ScheduleGridBean.ChannelBean.ProgrammeBean event : channelEvents) {
                    if (event.isSelected()) event.setSelected(false);
                }
            }
        }
    }

      当焦点在listview_channel_list时按上下切换epg信息。

    /* 显示节目名的ListView Item Selected响应函数 */
    mChannelListView.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
        @Override
        public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
            mChannelListRecyclerViewCurrentPosition = position;
            Log.d("wujiang", "mChannelListView->onItemSelected: mChannelListRecyclerViewCurrentPosition = " + mChannelListRecyclerViewCurrentPosition);
            Log.d("wujiang", "mChannelListView->onItemSelected: mEpgView.currentChannelPosition = " + mEpgView.currentChannelPosition);
    
            if (mEpgView.currentChannelPosition >= 0) {
                if (position > mEpgView.currentChannelPosition) {
                    mEpgView.moveToDestPosition(position, EpgView.DOWN_DIRECTION);
                } else if (position < mEpgView.currentChannelPosition) {
                    mEpgView.moveToDestPosition(position, EpgView.UP_DIRECTION);
                }
            }
        }
    
        @Override
        public void onNothingSelected(AdapterView<?> parent) {
    
        }
    });
    

      //左右键切换epg信息

    mEpgView.moveLeft();
    
    mEpgView.moveRight();

    我这里贴出的都是关键性的代码,如果你确实有需求,那你得好好研究这些代码,肯定对你是有用的。

                                                                         The             End

    展开全文
  • 【框架】?...【文档】EPG 的全业务解决方案,拥有最新的 ES6\ES7 API、Preact、Mobx 而无需考虑其兼容性。同时包含所有常规功能、业务最佳实践示例 转载于:https://www.cnblogs.com/menu/p/7500428.html
    展开全文
  • 【框架】?...【文档】EPG 的全业务解决方案,拥有最新的 ES6\ES7 API、Preact、Mobx 而无需考虑其兼容性。同时包含所有常规功能、业务最佳实践示例 转载于:https://www.cnblogs.com/menu/p/7500432.html
    展开全文
  • 【框架】?...【文档】EPG 的全业务解决方案,拥有最新的 ES6\ES7 API、Preact、Mobx 而无需考虑其兼容性。同时包含所有常规功能、业务最佳实践示例 转载于:https://www.cnblogs.com/menu/p/7500434.html
  • 【框架】?...【文档】EPG 的全业务解决方案,拥有最新的 ES6\ES7 API、Preact、Mobx 而无需考虑其兼容性。同时包含所有常规功能、业务最佳实践示例 转载于:https://www.cnblogs.com/menu/p/7500438.html
  • EPG规范 机顶盒

    2012-03-22 15:19:33
    描述机顶盒EPG的一些规范,简略的一些EPG描述符信息。
  • 一种电子节目指南EPG系统在机顶盒上的优化设计方案、电子技术,开发板制作交流
  • en_300468v010601o.pdf ETSI TS101154.v1.8.1.pdf 中文SI版本1.0.doc ets_300715e01p.pdf 里面包括了十几本pdf文档,国际标准的DVB文档。...机顶盒从业者必须。 非常实用!!!!! 五分绝对划算!!!!
  • EPG机顶盒上对< meta name=“page-view-size” content=“1280*720”>的理解 一、前言 现在机顶盒开发规范中涉及到的高清业务一般需要设置meta标签: <meta name="page-view-size" content="1280*720"> ...
  • 很好地阐述了机顶盒如何获取EPG信息的过程
  •  电子节目指南(Electronic Program Guide,EPG),是指在符合MPEG-2 (13818-1)的TS传输流中插入DVB标准定义的业务信息(Service Information,SI),使机顶盒(Set-Top-Box)的综合接收解码器(IRD)可以从TS流中提取出...
  • 机顶盒遥控键值

    2013-11-13 14:33:50
    机顶盒遥控键值,EPG开发者非常有用 IPTV
  • 机顶盒高级安全

    千次阅读 2015-05-29 13:41:05
     机顶盒(STB)是提供数字电视服务的关键设备,终端用户可通过其使用包括电子节目菜单(EPG)、数字视频录像机(DVR/PVR)、点播服务 (On-Demand Service)与家庭联网 (Home Networking)等在内的多种应用。同时,通过...
  • 【摘 要】本文介绍了一种电子节目指南(EPG)系统在机顶盒上的优化设计方案。该方案的创新点在于针对简单EPGEPG的特点设计不同的SI引擎流程,从而提高了各自执行效率;同时提出一种新的节目索引和节目信息两者...
  •  目前的高清机顶盒基本沿用了标清机顶盒的操作系统,然而数字电视总频道数已达到140 多套,后入网的高清频道在EPG 频道列表中都已排在130 以外,用户选择收看高清频道时操作不方便,这对高清频道的市场推广是个不利...

空空如也

空空如也

1 2 3 4 5 6
收藏数 106
精华内容 42
关键字:

机顶盒epg