2265 lines
		
	
	
		
			84 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
		
		
			
		
	
	
			2265 lines
		
	
	
		
			84 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
|  | package com.novelbook.android.utils; | |||
|  | 
 | |||
|  | import android.app.ProgressDialog; | |||
|  | import android.content.ContentValues; | |||
|  | import android.content.Context; | |||
|  | import android.content.Intent; | |||
|  | import android.content.IntentFilter; | |||
|  | import android.content.SyncAdapterType; | |||
|  | import android.graphics.Bitmap; | |||
|  | import android.graphics.Canvas; | |||
|  | import android.graphics.Color; | |||
|  | import android.graphics.Paint; | |||
|  | import android.graphics.Rect; | |||
|  | import android.graphics.RectF; | |||
|  | import android.graphics.Region; | |||
|  | import android.graphics.Typeface; | |||
|  | import android.opengl.Visibility; | |||
|  | import android.os.AsyncTask; | |||
|  | import android.os.Handler; | |||
|  | import android.os.Message; | |||
|  | import android.text.Layout; | |||
|  | import android.text.StaticLayout; | |||
|  | import android.text.TextPaint; | |||
|  | import android.text.TextUtils; | |||
|  | import android.util.DisplayMetrics; | |||
|  | import android.util.Log; | |||
|  | import android.view.View; | |||
|  | import android.view.WindowManager; | |||
|  | import android.widget.Toast; | |||
|  | 
 | |||
|  | import com.novelbook.android.MyApp; | |||
|  | import com.novelbook.android.R; | |||
|  | import com.novelbook.android.bean.NovelSites; | |||
|  | import com.novelbook.android.bean.Site; | |||
|  | import com.novelbook.android.db.Chapter; | |||
|  | import com.novelbook.android.db.Novel; | |||
|  | import com.novelbook.android.netutils.NetUtil; | |||
|  | import com.novelbook.android.view.PageWidget; | |||
|  | import com.umeng.analytics.MobclickAgent; | |||
|  | 
 | |||
|  | import org.litepal.LitePal; | |||
|  | import org.litepal.util.Const; | |||
|  | 
 | |||
|  | import java.io.File; | |||
|  | import java.io.IOException; | |||
|  | import java.text.DecimalFormat; | |||
|  | import java.text.SimpleDateFormat; | |||
|  | import java.util.ArrayList; | |||
|  | import java.util.Date; | |||
|  | import java.util.HashMap; | |||
|  | import java.util.List; | |||
|  | import java.util.Map; | |||
|  | import java.util.Random; | |||
|  | import java.util.concurrent.ConcurrentHashMap; | |||
|  | 
 | |||
|  | import static com.novelbook.android.utils.Constants.AD_BANNER_TOP; | |||
|  | 
 | |||
|  | //import static com.baidu.tts.loopj.AsyncHttpClient.log; | |||
|  | 
 | |||
|  | 
 | |||
|  | public class PageFactory implements ChangeSource{ | |||
|  |     private static final String TAG = "PageFactory"; | |||
|  |     private static PageFactory pageFactory; | |||
|  |     private float mBannerNaviHeight; | |||
|  |     private float mBannerTopHeight; | |||
|  |     private Context mContext; | |||
|  |     private Config config; | |||
|  |     //当前的书本 | |||
|  | //    private File book_file = null; | |||
|  |     // 默认背景颜色 | |||
|  |     private int m_backColor = 0xffff9e85; | |||
|  |     //页面宽 | |||
|  |     private int mWidth; | |||
|  |     //页面高 | |||
|  |     private int mHeight; | |||
|  |     //文字字体大小 | |||
|  |     private float m_fontSize ; | |||
|  |     //时间格式 | |||
|  |     private SimpleDateFormat sdf; | |||
|  |     //时间 | |||
|  |     private String date; | |||
|  |     //进度格式 | |||
|  |     private DecimalFormat df ; | |||
|  |     //电池边界宽度 | |||
|  |     private float mBorderWidth; | |||
|  |     // 上下与边缘的距离 | |||
|  |     private float marginHeight ; | |||
|  |     //满屏 差异 | |||
|  |     private float screenHeihtDiff ; | |||
|  |     // 左右与边缘的距离 | |||
|  |     private float measureMarginWidth ; | |||
|  |     // 左右与边缘的距离 | |||
|  |     private float marginWidth ; | |||
|  |     //状态栏距离底部高度 | |||
|  |     private float statusMarginBottom; | |||
|  |     //行间距 | |||
|  |     private float lineSpace; | |||
|  |     //段间距 | |||
|  |     private float paragraphSpace; | |||
|  |     //段间距相对行间距的倍数 | |||
|  |     private final float prate = 1.8f; | |||
|  |     //字高度 | |||
|  |     private float fontHeight; | |||
|  |     //字体 | |||
|  |     private Typeface typeface; | |||
|  |     //文字画笔 | |||
|  |     private Paint mPaint; | |||
|  |     //加载画笔 | |||
|  |     private Paint waitPaint; | |||
|  |     //文字颜色 | |||
|  |     private int m_textColor = Color.rgb(50, 65, 78); | |||
|  |     // 绘制内容的宽 | |||
|  |     private float mVisibleHeight; | |||
|  |     // 绘制内容的宽 | |||
|  |     private float mVisibleWidth; | |||
|  |     // 每页可以显示的行数 | |||
|  |     private int mLineCount; | |||
|  |     //电池画笔 | |||
|  |     private Paint mBatterryPaint ; | |||
|  |     //电池字体大小 | |||
|  |     private float mBatterryFontSize; | |||
|  |     //背景图片 | |||
|  |     private Bitmap m_book_bg = null; | |||
|  |     //当前显示的文字 | |||
|  | //    private StringBuilder word = new StringBuilder(); | |||
|  |     //当前总共的行 | |||
|  | //    private Vector<String> m_lines = new Vector<>(); | |||
|  | //    // 当前页起始位置 | |||
|  | //    private long m_mbBufBegin = 0; | |||
|  | //    // 当前页终点位置 | |||
|  | //    private long m_mbBufEnd = 0; | |||
|  | //    // 之前页起始位置 | |||
|  | //    private long m_preBegin = 0; | |||
|  | //    // 之前页终点位置 | |||
|  | //    private long m_preEnd = 0; | |||
|  |     // 图书总长度 | |||
|  | //    private long m_mbBufLen = 0; | |||
|  |     private Intent batteryInfoIntent; | |||
|  |     //电池电量百分比 | |||
|  |     private float mBatteryPercentage; | |||
|  |     //电池外边框 | |||
|  |     private RectF rect1 = new RectF(); | |||
|  |     //电池内边框 | |||
|  |     private RectF rect2 = new RectF(); | |||
|  |     //文件编码 | |||
|  | //    private String m_strCharsetName = "GBK"; | |||
|  |     //当前是否为第一页 | |||
|  |     private boolean m_isfirstPage; | |||
|  |     //当前是否为最后一页 | |||
|  |     private boolean m_islastPage; | |||
|  |     //书本widget | |||
|  |     private PageWidget mBookPageWidget; | |||
|  | //    //书本所有段 | |||
|  | //    List<String> allParagraph; | |||
|  | //    //书本所有行 | |||
|  | //    List<String> allLines = new ArrayList<>(); | |||
|  |     //现在的进度 | |||
|  |     private float currentProgress; | |||
|  |     //目录 | |||
|  | //    private List<Chapter> directoryList = new ArrayList<>(); | |||
|  |     //书本路径 | |||
|  |     private String bookPath = ""; | |||
|  |     //书本名字 | |||
|  |     private String bookName = ""; | |||
|  |    // private Novel mBook; | |||
|  |     //书的目录列表 | |||
|  |     private List<Chapter> mChapters; | |||
|  |     //当前章节 | |||
|  |    // private Chapter  mCurrentChapter; | |||
|  |     //书本章节 | |||
|  |     private int currentChapter = 0; | |||
|  | 
 | |||
|  | 
 | |||
|  |     //当前电量 | |||
|  |     private int level = 0; | |||
|  |     private BookUtil mBookUtil; | |||
|  |     private PageEvent mPageEvent; | |||
|  |     private TRPage currentPage; | |||
|  |     private TRPage prePage; | |||
|  |     private TRPage cancelPage; | |||
|  | 
 | |||
|  |     ContentValues values = new ContentValues(); | |||
|  | 
 | |||
|  |     ConcurrentHashMap<Integer,List<TRPage>> chaptMap; | |||
|  |     private List<TRPage> currentChaptPages; | |||
|  |     private List<TRPage>  nextChaptPages; | |||
|  |     private List<TRPage>  preChaptPages; | |||
|  | 
 | |||
|  |     private AdInterface mAd; | |||
|  |     private BookTask bookTask; | |||
|  |     private final int MSG_CHANGECHAPTER =1; | |||
|  |     private final int MSG_NEXTPAGE=2; | |||
|  |     private final int MSG_HIDEPROGRESS=3; | |||
|  |     private final int MSG_NEXTPAGE_FAIL=4; | |||
|  |     private final int MSG_HID_AD=5; | |||
|  |     private final int MSG_SHOW_LOADING=5; | |||
|  | 
 | |||
|  |     public AdInterface getmAd() { | |||
|  |         return mAd; | |||
|  |     } | |||
|  | 
 | |||
|  |     private static int mNavtiveBannerPlusCnt =0; | |||
|  |     private int mSmallBannerPlusCnt =0; | |||
|  |     private int mSmallBannerMinusCnt =0; | |||
|  |     //页面宽 | |||
|  |     private int mAdHeight; | |||
|  |     //页面高 | |||
|  |     private int mAdY; | |||
|  |     private enum AdTpye  {BANNER,NATIVEINLINES,CHAPTEREND;}; | |||
|  |     private AdTpye mAdType = AdTpye.BANNER; | |||
|  |     public void setAd(AdInterface ad){ | |||
|  |         mAd =ad; | |||
|  |     } | |||
|  |     Handler handler = new Handler() { | |||
|  |         @Override | |||
|  |         public void handleMessage(Message msg) { | |||
|  | 
 | |||
|  |            // Log.d(TAG, "prepare book get handler msg:" +msg); | |||
|  | 
 | |||
|  |             handlerMsg(msg); | |||
|  | 
 | |||
|  |            // dismissProgressDialog(); | |||
|  | 
 | |||
|  |         } | |||
|  |     }; | |||
|  | 
 | |||
|  | 
 | |||
|  |     void handlerMsg(Message msg) { | |||
|  |         if (msg.what == 1) { | |||
|  |             Log.d(TAG, String.format("prepare book handler get notic to download chapter %s , getNovel() is null? %s", currentChapter, getNovel() == null)); | |||
|  |             if (getNovel() != null) { | |||
|  |                 changeChapter(currentChapter); | |||
|  |             } else { | |||
|  |                /* mStatus = Status.FAIL;      // unknow error null Attempt to invoke virtual method 'android.graphics.Bitmap com.novelbook.android.view.PageWidget.getCurPage()' on a null object reference | |||
|  |                 drawStatus(); | |||
|  |                 */ | |||
|  |             } | |||
|  |         } else if (msg.what == MSG_NEXTPAGE) { | |||
|  | 
 | |||
|  |             mStatus =Status.FINISH; | |||
|  |           //  drawStatus(); | |||
|  |             Log.d(TAG, "prepare book to load next page"); | |||
|  |             nextPage(); | |||
|  |         } else if (msg.what == MSG_NEXTPAGE_FAIL) { | |||
|  | 
 | |||
|  |             mStatus =Status.FAIL; | |||
|  |             drawStatus(); | |||
|  | 
 | |||
|  |         } else if (msg.what == MSG_HIDEPROGRESS) { | |||
|  |             dismissProgressDialog(); | |||
|  |             if(mAd!=null) { | |||
|  |                 mAd.showRefresh(View.GONE); | |||
|  |             //    mAd.hideProgressbar(); | |||
|  | 
 | |||
|  |                mAd.showLoading(false); | |||
|  |               //  Log.d(TAG, "showloading: case MSG_HIDEPROGRESS: false"  ); | |||
|  |             } | |||
|  |         }else if (msg.what == MSG_HID_AD) { | |||
|  | 
 | |||
|  |           //  Log.d(TAG, "loadBannerAd: set banner gone 0, showingStatusAd " +showingStatusAd); | |||
|  |                 if(showingStatusAd) { | |||
|  |                     if (mAd != null) { | |||
|  |                        mAd.hideStatusAds(); | |||
|  |                  //       Log.d(TAG, "loadBannerAd: set banner gone 1"); | |||
|  |                     } | |||
|  |                 } | |||
|  |         }else if (msg.what == MSG_SHOW_LOADING) { | |||
|  | 
 | |||
|  | 
 | |||
|  |             if(mAd!=null) { | |||
|  | 
 | |||
|  |                 mAd.showLoading(true); | |||
|  |                 Log.d(TAG, "showloading: case MSG_SHOW_LOADING: true"  ); | |||
|  | 
 | |||
|  |             } | |||
|  | 
 | |||
|  |         } | |||
|  |     } | |||
|  |     Map<Integer,Integer> fileRetryCnt = new HashMap<Integer,Integer>(); | |||
|  |     private  List<TRPage>  loadCurrentChapt(int chaptId){ | |||
|  |         Log.d(TAG, String.format("prepare book,  loadCurrentChapt chaptId %s, getChapters().size() %s ,currentChapter %s",chaptId,getChapters().size()  ,currentChapter) ); | |||
|  | 
 | |||
|  |         if ( getChapters().size()>0) { //待下载 | |||
|  |             chaptId = chaptId > getChapters().size() ? getChapters().size() : chaptId; | |||
|  | 
 | |||
|  |             chaptId = chaptId > 0 ? chaptId : 1; | |||
|  | 
 | |||
|  |         } | |||
|  | 
 | |||
|  |         List<TRPage> chaptPages = new ArrayList<TRPage>(); | |||
|  |         chaptPages.add(new TRPage()); | |||
|  | 
 | |||
|  |         long starttime = new Date().getTime(); | |||
|  | 
 | |||
|  |         if(chaptMap==null) { | |||
|  |             chaptMap = new ConcurrentHashMap<Integer, List<TRPage>>(); | |||
|  |         } | |||
|  |         if(chaptMap.containsKey(chaptId)){ | |||
|  |             chaptPages =chaptMap.get(chaptId); | |||
|  |             mBookUtil.setChapterLen( chaptPages.get(chaptPages.size()-1).getEnd()); | |||
|  |             mBookUtil.setChapterNo(chaptId); | |||
|  |             Log.d(TAG, String.format("prepare book to load chapt %s,  cost %s ",chaptId ,new Date().getTime() -starttime) ); | |||
|  |             return chaptMap.get(chaptId); | |||
|  |         } | |||
|  | 
 | |||
|  |         chaptId = chaptId > 0 ? chaptId : 1; | |||
|  |           File file = new File(getChapterFileName(chaptId)); | |||
|  | 
 | |||
|  |         if (!file.exists() && getChapters().size()>0) { //待下载 | |||
|  |             chaptId = chaptId > getChapters().size() ? getChapters().size() : chaptId; | |||
|  | 
 | |||
|  |             chaptId = chaptId > 0 ? chaptId : 1; | |||
|  |             file = new File(getChapterFileName(chaptId)); | |||
|  |         } | |||
|  | 
 | |||
|  | 
 | |||
|  |          if(!getNovel().isLocalBook()) { | |||
|  | 
 | |||
|  |              mStatus = Status.OPENING; | |||
|  |             final int maxSleep = Constants.MAX_SLEEP_4_CHAPT_DOWNLOAD; | |||
|  | 
 | |||
|  |           // final File file = new File(getChapterFileName(chaptId)); | |||
|  | 
 | |||
|  |            Log.d(TAG, String.format("prepare book to open chapter %s ,file is exist ? %s",chaptId,file.exists()  ) ); | |||
|  | 
 | |||
|  |             if (!file.exists()) { | |||
|  | 
 | |||
|  |                 if (fileRetryCnt.containsKey(chaptId)) { | |||
|  |                     fileRetryCnt.put(chaptId, fileRetryCnt.get(chaptId) + 1); | |||
|  |                     loadingTxt+="."; | |||
|  |                 } else { | |||
|  |                     fileRetryCnt.clear();//只保留一个章节数据 | |||
|  |                     fileRetryCnt.put(chaptId, 1); | |||
|  |                     loadingTxt=""; | |||
|  |                     mBookUtil.fileRetryCnt.clear(); | |||
|  |                 } | |||
|  | 
 | |||
|  |                 Log.d(TAG, String.format("prepare book loadCurrentChapt %s, rertying count %s  ",chaptId, fileRetryCnt.get(chaptId))); | |||
|  | 
 | |||
|  |                 if(fileRetryCnt.get(chaptId) > Constants.retryCnt){ | |||
|  |                     mStatus = Status.FAIL; | |||
|  |                     drawStatus(); | |||
|  |                      | |||
|  |                     return chaptPages; | |||
|  |                 } | |||
|  | 
 | |||
|  |                 drawStatus(); | |||
|  |                  | |||
|  | 
 | |||
|  |                 if( !NetUtil.isNetworkConnected()){  //TODO: 500错误处理 | |||
|  |                     mStatus = Status.NETWORKFAILE; | |||
|  |                     drawStatus(); | |||
|  |                      | |||
|  |                     return chaptPages; | |||
|  |                 } | |||
|  |                 if(getChapters().size()==0 && mBookUtil.muluRetryCount>=Constants.retryCnt) { | |||
|  |                     Log.d(TAG, String.format("prepare book download mulu 失败,重试次数: %s ,thread.name %s",mBookUtil.muluRetryCount,Thread.currentThread().getName()  ) ); | |||
|  |                     mBookUtil.muluRetryCount=0; | |||
|  |                     mStatus = Status.FAIL; | |||
|  |                     drawStatus(); | |||
|  |                      | |||
|  |                     return chaptPages; | |||
|  |                 } | |||
|  |               //  showProgressDialog(); | |||
|  |                 final int chid = chaptId; | |||
|  |                 new Thread() { | |||
|  |                     @Override | |||
|  |                     public void run() { | |||
|  |                         Log.d(TAG, String.format("prepare book to download chapter %s ,thread.name %s",chid,Thread.currentThread().getName()  ) ); | |||
|  |                         mBookUtil.chaptChars(chid); | |||
|  | 
 | |||
|  |                         super.run(); | |||
|  |                     }}.start(); | |||
|  | 
 | |||
|  |                 new Thread() { | |||
|  |                     @Override | |||
|  |                     public void run() { | |||
|  |                         int slepttime =0; | |||
|  |                        File file = new File(getChapterFileName(chid)); | |||
|  |                       while( !file.exists() && slepttime <maxSleep && mBookUtil.muluRetryCount<Constants.retryCnt ||showingStatusAd &&(new Date().getTime() - showStatusAdTime <2200) ){ | |||
|  |                           try { | |||
|  |                               sleep(50); | |||
|  |                               slepttime+=50; | |||
|  |                           } catch (InterruptedException e) { | |||
|  |                               e.printStackTrace(); | |||
|  |                           } | |||
|  |                       } | |||
|  |                       Log.d(TAG, String.format("prepare book to download chapter %s ,slepted %s ,thread.name %s",chid,slepttime*50 ,Thread.currentThread().getName()  ) ); | |||
|  | 
 | |||
|  |                         mStatus = Status.FINISH; | |||
|  |                      if( mBookUtil.muluRetryCount>=Constants.retryCnt){ | |||
|  |                          mStatus = Status.FAIL; | |||
|  |                      } | |||
|  |                         Log.d(TAG, String.format("prepare book to download chapter %s ,handler notice changeChapter  %s",chid, currentChapter  ) ); | |||
|  |                       //notice file done | |||
|  |                        handler.sendEmptyMessage(MSG_CHANGECHAPTER); | |||
|  | 
 | |||
|  | 
 | |||
|  |                         super.run(); | |||
|  |                     }}.start(); | |||
|  | 
 | |||
|  |                 drawStatus(); | |||
|  |                  | |||
|  | 
 | |||
|  |                 return chaptPages; | |||
|  |             } | |||
|  | 
 | |||
|  |          } | |||
|  | 
 | |||
|  |         chaptPages =readChaptCache(chaptId); | |||
|  |          if(chaptPages.size()>0) { | |||
|  |              chaptMap.put(chaptId, chaptPages); | |||
|  |              mBookUtil.setChapterLen(chaptPages.get(chaptPages.size() - 1).getEnd()); | |||
|  |              mBookUtil.setChapterNo(chaptId); | |||
|  | 
 | |||
|  | 
 | |||
|  |         Log.d(TAG, String.format("prepare book to load chapt %s,  cost %s ",chaptId ,new Date().getTime() -starttime) ); | |||
|  |         mStatus = Status.FINISH; | |||
|  |         Log.d(TAG, String.format("changing Source prepare book to draw chapter %s,  currentChapter %s ",chaptId ,currentChapter ) ); | |||
|  |       //  drawStatus(); | |||
|  |         }else{ | |||
|  | 
 | |||
|  |              mStatus = Status.FAIL; | |||
|  | 
 | |||
|  |              if(getNovle().isLocalBook()){ | |||
|  |                  mStatus=Status.LOCALFAIL; | |||
|  |              } | |||
|  |              drawStatus(); | |||
|  |          } | |||
|  |         return  chaptPages; | |||
|  |     } | |||
|  | 
 | |||
|  |     void preReadChaptCache(final int chaptId){ | |||
|  | 
 | |||
|  |         if(!Constants.PRE_LOAD_CHAPT){ | |||
|  |             return; | |||
|  |         } | |||
|  |         if(chaptMap==null) { | |||
|  |             chaptMap = new ConcurrentHashMap<Integer, List<TRPage>>(); | |||
|  |         } | |||
|  |         if(chaptMap.containsKey(chaptId)){ | |||
|  |             return; | |||
|  |         } | |||
|  |         Log.d(TAG, String.format("prepare book to preLoad chapt %s,  current chapt %s --->",chaptId ,currentChapter) ); | |||
|  |         new Thread() { | |||
|  |             @Override | |||
|  |             public void run() { | |||
|  |                 super.run(); | |||
|  | 
 | |||
|  |                 Log.d(TAG, String.format("prepare book to preRead chapter %s ,thread.name %s",chaptId,Thread.currentThread().getName()  ) ); | |||
|  |                 File file = new File(getChapterFileName(chaptId)); | |||
|  |                 if(file.exists()) { | |||
|  |                     chaptMap.put(chaptId, readChaptCache(chaptId)); | |||
|  | 
 | |||
|  |                     Log.d(TAG, String.format("prepare book to preLoad %s done <-----",chaptId ) ); | |||
|  |                 }else{ | |||
|  |                     Log.d(TAG, String.format("prepare book to trying download the chapt %s again........... ",chaptId ) ); | |||
|  |                     mBookUtil.retryDownLoadContent(chaptId) ; | |||
|  |                 } | |||
|  | 
 | |||
|  | 
 | |||
|  |             }}.start(); | |||
|  |     } | |||
|  | 
 | |||
|  | 
 | |||
|  |     /** | |||
|  |      * only read chapt that cached already | |||
|  |      * @param chaptId | |||
|  |      * @return | |||
|  |      */ | |||
|  |     List<TRPage> readChaptCache(int chaptId){ | |||
|  |         List<TRPage> chaptPages = new ArrayList<TRPage>(); | |||
|  | 
 | |||
|  |         Log.d(TAG, String.format("prepare book to open chapter %s,  currentChapter %s ",chaptId ,currentChapter ) ); | |||
|  |         char[] chars = mBookUtil.chaptChars(chaptId); | |||
|  |          mBookUtil.setTmpChaptLen(chars.length); | |||
|  | //        mBookUtil.setChapterNo(chaptId); | |||
|  |         // TRPage page = new TRPage(); | |||
|  |         long length =0; | |||
|  |         int pageNo =0; | |||
|  |         long starttime = new Date().getTime(); | |||
|  |         while(length <chars.length ) { | |||
|  |             //long starttime1 = new Date().getTime(); | |||
|  |             pageNo++; | |||
|  |             TRPage page  = getNextChapterPage(chaptId,length ,pageNo); | |||
|  | 
 | |||
|  |             // Log.d(TAG,"prepare book  page.getBegin :" + page.getBegin()+ ",chapter length "+ mBookUtil.getChapterLen()); | |||
|  | 
 | |||
|  |             // if(page.getBegin() == mBookUtil.getChapterLen() ){ //最后一页空白的情况。。。 | |||
|  | 
 | |||
|  |             //     break; | |||
|  |             //  } | |||
|  | 
 | |||
|  |             length=  page.getEnd(); | |||
|  |             if(page.getLines().size()==0){ | |||
|  |                 pageNo--; | |||
|  |                 continue; | |||
|  |             } | |||
|  |             page.setChapterNo(chaptId); | |||
|  |             page.setLastPage(page.getEnd()==chars.length); | |||
|  |             page.setFirstPage(pageNo==1); | |||
|  |             page.setPageNo(pageNo); | |||
|  | 
 | |||
|  |         /*    if(Constants.AD_SETTING.getChapterEndBanner().isShow()  && length >=chars.length ){ | |||
|  |                 if(page.getLines().size()< mLineCount/2) | |||
|  |                 page.setBannerHeight(0); | |||
|  |             }*/ | |||
|  | 
 | |||
|  |             chaptPages.add(page); | |||
|  |        //     Log.d(TAG, String.format("prepare book build page %s ready for chapter %s,cost %s",pageNo, chaptId,new Date().getTime()-starttime1)); | |||
|  |         } | |||
|  |        // Log.d(TAG, String.format("                  prepare book build pages ready for chapter %s,cost %s", chaptId,new Date().getTime()-starttime)); | |||
|  |         return chaptPages; | |||
|  |     } | |||
|  | 
 | |||
|  | 
 | |||
|  | 
 | |||
|  | 
 | |||
|  |     public TRPage getNextChapterPage(int chaptId,long position,int pageNo) { | |||
|  |         mBookUtil.setPostition(chaptId, position); | |||
|  | 
 | |||
|  |         TRPage trPage = new TRPage(); | |||
|  |        //  Constants.AD_CHAPT_NATIVE_BANNER_PER_PAGE_COUNT = 20; | |||
|  |         if (Constants.AD_SETTING.isShowAdsense() && pageNo > 1) { | |||
|  |             mNavtiveBannerPlusCnt++; | |||
|  |             //    Constants.AD_CHAPT_TOP_BANNER_PER_PAGE_COUNT = 1; | |||
|  | 
 | |||
|  | 
 | |||
|  |             int bannerPagecnt = Constants.AD_SETTING.getChapterBanner().getPageCount4Display(); | |||
|  |             int nativeBannerPageCnt = Constants.AD_SETTING.getChapterContentBanner().getPageCount4Display(); | |||
|  |             if (Constants.AD_SETTING.getChapterContentBanner().isShow() && | |||
|  |                     nativeBannerPageCnt > 0 && | |||
|  |                     mNavtiveBannerPlusCnt >= nativeBannerPageCnt) { | |||
|  |                 mNavtiveBannerPlusCnt = 0; | |||
|  |                 calculateLineCount(); | |||
|  |                 int adLines = (int) (mBannerNaviHeight / ((m_fontSize + lineSpace))); | |||
|  |                 if(mLineCount - adLines - 1>0) { | |||
|  | 
 | |||
|  | 
 | |||
|  |                     int adLine = new Random().nextInt(mLineCount - adLines - 1); | |||
|  | 
 | |||
|  |                     adLine = adLine < mLineCount ? adLine : mLineCount - 2; | |||
|  |                     if (adLine > 0) { | |||
|  |                         trPage.setNativeBannerStartLine(adLine); | |||
|  |                         //trPage.setNativeBannerHeight(Constants.AD_CHAPT_NATIVE_BANNER_HEIGHT); | |||
|  |                         trPage.setNativeBannerHeight((int) mBannerNaviHeight); | |||
|  |                     } | |||
|  |                     Log.d(TAG, String.format("getNextChapterPage: pageNo %s,  adLines %s,adLine %s, nativeBannerHeight %s", | |||
|  |                             pageNo, adLines, adLine, trPage.getNativeBannerHeight())); | |||
|  |                 } | |||
|  |             } | |||
|  |             if(trPage.getNativeBannerHeight()==0) | |||
|  |             if (Constants.AD_SETTING.getChapterBanner().isShow()) { | |||
|  |                 if (bannerPagecnt <=0 || mSmallBannerPlusCnt < bannerPagecnt) { | |||
|  |                     mSmallBannerPlusCnt++; | |||
|  |                     trPage.setBannerHeight((int) mBannerTopHeight); | |||
|  | 
 | |||
|  |                 } else { | |||
|  |                     mSmallBannerMinusCnt--; | |||
|  |                     if (mSmallBannerMinusCnt < 0) { | |||
|  |                         mSmallBannerMinusCnt = bannerPagecnt; | |||
|  |                     } | |||
|  |                     if (mSmallBannerMinusCnt == 0) { | |||
|  |                         mSmallBannerPlusCnt = 0; | |||
|  |                     } | |||
|  |                 } | |||
|  |                 Log.d(TAG, String.format("getNextChapterPage: pageNo %s, topBannerHeight %s,bannerPagecnt %s,mSmallBannerPlusCnt %s,mSmallBannerMinusCnt %s  ", pageNo, trPage.getBannerHeight() | |||
|  |                        , bannerPagecnt ,mSmallBannerPlusCnt  ,mSmallBannerMinusCnt )); | |||
|  |             } | |||
|  | 
 | |||
|  |         } | |||
|  |         trPage.setPageNo(pageNo); | |||
|  |         trPage.setBegin(position + 1); | |||
|  | 
 | |||
|  |         // Log.d(TAG,"page postion next begin:" +  (position + 1) + ""); | |||
|  |         trPage.setLines(getNextLines(chaptId, trPage)); | |||
|  |         if (trPage.getNativeBannerStartLine() > 0 && trPage.getNativeBannerStartLine() >= trPage.getLines().size()) { | |||
|  |             trPage.setNativeBannerStartLine(trPage.getLines().size() - 1); | |||
|  |         } | |||
|  |         //  Log.d(TAG,"page postion next end:" +mBookUtil.getPosition() + ""); | |||
|  |         trPage.setEnd(mBookUtil.getPosition(chaptId)); | |||
|  |         return trPage; | |||
|  |     } | |||
|  | 
 | |||
|  | 
 | |||
|  |     private static Status mStatus = Status.OPENING; | |||
|  | 
 | |||
|  |     public NovelSites  getNovelSites() { | |||
|  |         return  mBookUtil.getmNovelSites(); | |||
|  |     } | |||
|  |     private ProgressDialog progressDialog; | |||
|  |     private void showProgressDialog() { | |||
|  |         if (  null == progressDialog) { | |||
|  |             progressDialog =new ProgressDialog(mContext); | |||
|  |             progressDialog.setMessage("正在努力加载..."); | |||
|  |         } | |||
|  |         try { | |||
|  |             progressDialog.show(); | |||
|  |         }catch (Exception e) | |||
|  |         { | |||
|  |             Log.e(TAG, "prepare book: ", e); | |||
|  |         } | |||
|  |         //   progressDialog.show(mContext,"网络不给力","正努力加载",false,true); | |||
|  |     } | |||
|  | 
 | |||
|  | 
 | |||
|  |     private void dismissProgressDialog() { | |||
|  |         if ( null != progressDialog) { | |||
|  |             progressDialog.dismiss(); | |||
|  |         } | |||
|  |     } | |||
|  |     public void changeSource(String domainName,String domain,int chapId,String chapTitle) { | |||
|  |         hideSysUI(); | |||
|  |         fileRetryCnt.clear(); | |||
|  | 
 | |||
|  |         if(TextUtils.isEmpty(getSite().getDomain()) || TextUtils.isEmpty(domain)|| getSite().getDomain().equals(domain)){ //当前源 | |||
|  |             Log.d(TAG, "prepare book changing Source: same site with original " + domain); | |||
|  |             return; | |||
|  |         } | |||
|  |         if(chaptMap!=null){ | |||
|  |             chaptMap.clear(); | |||
|  |         } | |||
|  |         Log.d(TAG, String.format("prepare book changing Source:target site received: name %s, site domain %s ,chapterId %s " ,domainName, domain,chapId)); | |||
|  |         mStatus= Status.CHANGESOURCE; | |||
|  |         statusChangeSource="正在换源..."; | |||
|  |         if(!TextUtils.isEmpty(domainName)) { | |||
|  |             statusChangeSource = "前往 " + domainName.substring(0,domainName.length()>5?5:domainName.length()) + "..."; | |||
|  |         } | |||
|  | 
 | |||
|  |         drawStatus(); | |||
|  |         mBookUtil.pagefactory=this; | |||
|  |         mBookUtil.changeSource(domain,  chapId,  chapTitle); | |||
|  | 
 | |||
|  |     } | |||
|  | 
 | |||
|  |  /*   public String getChapterName() { | |||
|  |         return getChapters().get(currentChapter-1).getChapterName(); | |||
|  |     }*/ | |||
|  |     public Chapter getChapter(){ | |||
|  |         return mBookUtil.getChapter(mBookUtil.getChapterNo()); | |||
|  |     } | |||
|  | 
 | |||
|  |     private static boolean isBusy =false; | |||
|  |     public void setBusy(boolean isBusy) { | |||
|  |         this.isBusy = isBusy; | |||
|  |     } | |||
|  |     public static boolean busy(){ | |||
|  |         return isBusy; | |||
|  |     } | |||
|  | 
 | |||
|  |     public static boolean canTouch(){ | |||
|  |       switch (mStatus){ | |||
|  |           case FAIL: | |||
|  |               return true; | |||
|  |           case FINISH:return true; | |||
|  |           case OPENING:return false; | |||
|  |           case SERVERERROR:return true; | |||
|  |           case CHANGESOURCE:return false; | |||
|  |           case NETWORKFAILE:return true; | |||
|  |           case LASTPAGE:return true; | |||
|  |       } | |||
|  |         return  false; | |||
|  |     } | |||
|  |     public void refreshChapter() { | |||
|  | 
 | |||
|  |         fileRetryCnt.clear(); | |||
|  |         mBookUtil.fileRetryCnt.clear(); | |||
|  |        if( chaptMap.containsKey(getCurrentChapter())){ | |||
|  |            chaptMap.remove(getCurrentChapter()); | |||
|  |        } | |||
|  | 
 | |||
|  |         mBookUtil.refreshChapter(); | |||
|  | 
 | |||
|  |     } | |||
|  | 
 | |||
|  |     public void changeSourceForCate(String name, String domain) { | |||
|  |         if(getSite().getDomain().equals(domain)){ //当前源 | |||
|  |             Log.d(TAG, "prepare book changing Source: same site with original " + domain); | |||
|  |             return; | |||
|  |         } | |||
|  |         mBookUtil.changeSite(domain); | |||
|  |     } | |||
|  | 
 | |||
|  | 
 | |||
|  |     public enum Status { | |||
|  |         OPENING, | |||
|  |         FINISH, | |||
|  |         FAIL, | |||
|  |         NETWORKFAILE, | |||
|  |         SERVERERROR, | |||
|  |          CHANGESOURCE  , | |||
|  |         LOCALFAIL, | |||
|  |         LASTPAGE; | |||
|  |     } | |||
|  | private void hideSysUI(){ | |||
|  |         if(mAd!=null){ | |||
|  |             mAd.hideSystemUI(); | |||
|  |            // mAd.showRefresh(View.GONE); | |||
|  |         } | |||
|  | } | |||
|  |     public static synchronized PageFactory getInstance(Context context){ | |||
|  |         if(pageFactory==null){ | |||
|  |             createPageFactory(context); | |||
|  |         } | |||
|  |         return pageFactory; | |||
|  |     } | |||
|  | 
 | |||
|  |     public static synchronized PageFactory createPageFactory(Context context){ | |||
|  |         if (pageFactory == null){ | |||
|  |             pageFactory = new PageFactory(context); | |||
|  |         } | |||
|  |         return pageFactory; | |||
|  |     } | |||
|  | 
 | |||
|  |     private PageFactory(Context context) { | |||
|  |        // mBookUtil = new BookUtil(); | |||
|  |         mContext = context.getApplicationContext(); | |||
|  |         config = Config.getInstance(); | |||
|  |         //获取屏幕宽高 | |||
|  |     WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); | |||
|  |         DisplayMetrics metric = new DisplayMetrics(); | |||
|  |         wm.getDefaultDisplay().getMetrics(metric); | |||
|  |         mWidth = metric.widthPixels; | |||
|  |        // mHeight = metric.heightPixels; | |||
|  |        // mHeight = CommonUtil.getDpi(context); | |||
|  |         mHeight = CommonUtil.getScreenHeight(context) - CommonUtil.statusBarDiff(context); | |||
|  |         sdf = new SimpleDateFormat("HH:mm");//HH:mm为24小时制,hh:mm为12小时制 | |||
|  |         date = sdf.format(new java.util.Date()); | |||
|  |         df = new DecimalFormat("#0.0"); | |||
|  |         mBannerNaviHeight = mContext.getResources().getDimension(R.dimen.nativeBannerHeight) + 4 * Constants.ONE_DP_SIZE; | |||
|  |         mBannerTopHeight = mContext.getResources().getDimension(R.dimen.topBannerHeight) + 0 * Constants.ONE_DP_SIZE; | |||
|  |         marginWidth = mContext.getResources().getDimension(R.dimen.readingMarginWidth); | |||
|  |         marginHeight = mContext.getResources().getDimension(R.dimen.readingMarginHeight); | |||
|  |        // Log.d(TAG, "getNavigationBarSize: orignal marginHeight +" +marginHeight); | |||
|  |       //  marginHeight = CommonUtil. getStatusBarHeight(mContext); | |||
|  | 
 | |||
|  |         statusMarginBottom = mContext.getResources().getDimension(R.dimen.reading_status_margin_bottom); | |||
|  |         screenHeihtDiff =CommonUtil.statusBarDiff(mContext); | |||
|  |         Log.d(TAG, "getNavigationBarSize: screenHeihtDiff   " +screenHeihtDiff); | |||
|  |         lineSpace = context.getResources().getDimension(R.dimen.reading_line_spacing); | |||
|  |         paragraphSpace = context.getResources().getDimension(R.dimen.reading_paragraph_spacing); | |||
|  |         mVisibleWidth = mWidth - marginWidth * 2; | |||
|  |         mVisibleHeight = mHeight - marginHeight * 2   - CommonUtil.convertDpToPixel(mContext,10);; | |||
|  |         mHeight +=screenHeihtDiff; | |||
|  |         typeface = config.getTypeface(); | |||
|  |         m_fontSize = config.getFontSize(); | |||
|  |         lineSpace =config.getLineSpace(); | |||
|  |         paragraphSpace =  prate * lineSpace ; | |||
|  |         mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);// 画笔 | |||
|  |         mPaint.setTextAlign(Paint.Align.LEFT);// 左对齐 | |||
|  |         mPaint.setTextSize(m_fontSize);// 字体大小 | |||
|  |         mPaint.setColor(m_textColor);// 字体颜色 | |||
|  |         mPaint.setTypeface(typeface); | |||
|  |         mPaint.setSubpixelText(true);// 设置该项为true,将有助于文本在LCD屏幕上的显示效果 | |||
|  | 
 | |||
|  |         waitPaint = new Paint(Paint.ANTI_ALIAS_FLAG);// 画笔 | |||
|  |         waitPaint.setTextAlign(Paint.Align.LEFT);// 左对齐 | |||
|  |         waitPaint.setTextSize(mContext.getResources().getDimension(R.dimen.reading_max_text_size));// 字体大小 | |||
|  |         waitPaint.setColor(m_textColor);// 字体颜色 | |||
|  |         waitPaint.setTypeface(typeface); | |||
|  |         waitPaint.setSubpixelText(true);// 设置该项为true,将有助于文本在LCD屏幕上的显示效果 | |||
|  |         calculateLineCount(); | |||
|  | 
 | |||
|  |         mBorderWidth = mContext.getResources().getDimension(R.dimen.reading_board_battery_border_width); | |||
|  |         mBatterryPaint = new Paint(Paint.ANTI_ALIAS_FLAG); | |||
|  |         mBatterryFontSize = CommonUtil.sp2px(context, 12); | |||
|  |         mBatterryPaint.setTextSize(mBatterryFontSize); | |||
|  |         mBatterryPaint.setTypeface(typeface); | |||
|  |         mBatterryPaint.setTextAlign(Paint.Align.LEFT); | |||
|  |         mBatterryPaint.setColor(m_textColor); | |||
|  |         batteryInfoIntent = context.getApplicationContext().registerReceiver(null, | |||
|  |                 new IntentFilter(Intent.ACTION_BATTERY_CHANGED)) ;//注册广播,随时获取到电池电量信息 | |||
|  |         level = batteryInfoIntent.getIntExtra( "level" , 0 ); | |||
|  |         initBg(config.getDayOrNight()); | |||
|  |         measureMarginWidth(); | |||
|  |     } | |||
|  | 
 | |||
|  |     private void measureMarginWidth(){ | |||
|  |         float wordWidth =mPaint.measureText("\u3000"); | |||
|  |         float width = mVisibleWidth % wordWidth; | |||
|  |         measureMarginWidth = marginWidth + width / 2; | |||
|  | 
 | |||
|  | //        Rect rect = new Rect(); | |||
|  | //        mPaint.getTextBounds("好", 0, 1, rect); | |||
|  | //        float wordHeight = rect.height(); | |||
|  | //        float wordW = rect.width(); | |||
|  | //        Paint.FontMetrics fm = mPaint.getFontMetrics(); | |||
|  | //        float wrodH = (float) (Math.ceil(fm.top + fm.bottom + fm.leading)); | |||
|  | //        String a = ""; | |||
|  | 
 | |||
|  |     } | |||
|  | 
 | |||
|  |     //初始化背景 | |||
|  |     private void initBg(Boolean isNight){ | |||
|  |         if (isNight) { | |||
|  |             //设置背景 | |||
|  | //            setBgBitmap(BitmapUtil.decodeSampledBitmapFromResource( | |||
|  | //                    mContext.getResources(), R.drawable.main_bg, mWidth, mHeight)); | |||
|  |             Bitmap bitmap = Bitmap.createBitmap(mWidth,mHeight, Bitmap.Config.RGB_565); | |||
|  |             Canvas canvas = new Canvas(bitmap); | |||
|  |             canvas.drawColor(Color.BLACK); | |||
|  |             setBgBitmap(bitmap); | |||
|  |             //设置字体颜色 | |||
|  |             setM_textColor(Color.rgb(128, 128, 128)); | |||
|  |             setBookPageBg(Color.BLACK); | |||
|  |         } else { | |||
|  |             //设置背景 | |||
|  |             setBookBg(config.getBookBgType()); | |||
|  |         } | |||
|  |     } | |||
|  | 
 | |||
|  |     private void calculateLineCount(){ | |||
|  |         mLineCount = (int) (mVisibleHeight / (m_fontSize + lineSpace));// 可显示的行数 | |||
|  |     } | |||
|  |     private void calculateLineCount(float paragrapheight){ | |||
|  |         mLineCount = (int) ((mVisibleHeight - paragrapheight  ) / (m_fontSize + lineSpace));// 可显示的行数 | |||
|  |      //  Log.d(TAG,"line count is " + mLineCount +" paragrapheight is " +paragrapheight); | |||
|  |     } | |||
|  |     private void drawStatus(){ | |||
|  |         if(mBookPageWidget!=null) { | |||
|  |            // drawStatus(mBookPageWidget.getCurPage()); | |||
|  |            drawStatus(mBookPageWidget.getNextPage()); | |||
|  |         } | |||
|  |     } | |||
|  |     private String loadingTxt =""; | |||
|  |     private String statusChangeSource ="正在换源..."; | |||
|  |     private boolean showingStatusAd =false; | |||
|  |     private long showStatusAdTime =0; | |||
|  |     private void drawStatus(Bitmap bitmap){ | |||
|  |         hideSysUI(); | |||
|  |        mAd.showRefresh(View.VISIBLE); | |||
|  |         mAd.hideProgressbar(); | |||
|  |      //   mAd.showLoading(false); | |||
|  |         String status = ""; | |||
|  |         boolean showAd =true; | |||
|  |         switch (mStatus){ | |||
|  |             case OPENING: | |||
|  |                 status =  "正在拼命加载" + loadingTxt; | |||
|  |                mAd.showRefresh(View.GONE); | |||
|  |              //  mAd.showProgressbar(false,status); | |||
|  |                 mAd.showLoading(true); | |||
|  |                 Log.d(TAG, "showloading: case OPENING: true"  ); | |||
|  |               //handler.sendEmptyMessage(MSG_SHOW_LOADING); | |||
|  |                // showProgressDialog(); | |||
|  |                 break; | |||
|  |             case FAIL: | |||
|  |                 status = "读取错误,请稍后重试"; | |||
|  |                 mAd.showRefresh(View.VISIBLE); | |||
|  |                 mAd.showReadSetting(); | |||
|  |                 mAd.showLoading(false); | |||
|  |                 try { | |||
|  |                     throw new Exception("error on reading"); | |||
|  |                 } catch (Exception e) { | |||
|  |                     e.printStackTrace(); | |||
|  |                     Log.d(TAG, "prepare book: why fail ",e); | |||
|  |                 } | |||
|  |                 break; | |||
|  |             case NETWORKFAILE: | |||
|  |                 mAd.showLoading(false); | |||
|  |                 Log.d(TAG, "showloading: case NETWORKFAILE: false"  ); | |||
|  |                 showAd =false; | |||
|  |                 status = "请开启网络"; | |||
|  |                 break; | |||
|  |             case SERVERERROR: | |||
|  |                 mAd.showLoading(false); | |||
|  |                 Log.d(TAG, "showloading: case SERVERERROR: false"  ); | |||
|  |                 status =   "服务器故障"; | |||
|  |                 break; | |||
|  |             case FINISH: | |||
|  |                 mAd.showLoading(false); | |||
|  |                 Log.d(TAG, "showloading: case FINISH: false"  ); | |||
|  |                 status =   "加载成功"; | |||
|  |                 mAd.showRefresh(View.GONE); | |||
|  |                 mAd.hideProgressbar(); | |||
|  |                 showAd =false; | |||
|  |                 break; | |||
|  |             case CHANGESOURCE: | |||
|  |                 mAd.showLoading(true); | |||
|  |                 Log.d(TAG, "showloading: case CHANGESOURCE: true"  ); | |||
|  |                 status = statusChangeSource; | |||
|  |                 mAd.showRefresh(View.GONE); | |||
|  |                 break; | |||
|  | 
 | |||
|  |             case LOCALFAIL: | |||
|  |                 mAd.showLoading(false); | |||
|  |                 Log.d(TAG, "showloading: case LOCALFAIL: false"  ); | |||
|  |                 status = "本地缓存加载错误"; | |||
|  |                 mAd.showRefresh(View.GONE); | |||
|  |                 break; | |||
|  |             case LASTPAGE: | |||
|  |                 status = "看完了,没有了"; | |||
|  |                 mAd.showRefresh(View.GONE); | |||
|  |                 mAd.showLoading(false); | |||
|  |                 Log.d(TAG, "showloading: case LASTPAGE: false"  ); | |||
|  |                 break; | |||
|  |         } | |||
|  | 
 | |||
|  |         Canvas c = new Canvas(bitmap); | |||
|  |         c.drawBitmap(getBgBitmap(), 0, 0, null); | |||
|  |         waitPaint.setTextSize(mContext.getResources().getDimension(R.dimen.reading_max_text_size));// 字体大小 | |||
|  |         waitPaint.setColor(getTextColor()); | |||
|  |         waitPaint.setTextAlign(Paint.Align.CENTER); | |||
|  | 
 | |||
|  |         Rect targetRect = new Rect(0, 0, mWidth, mHeight); | |||
|  | //        c.drawRect(targetRect, waitPaint); | |||
|  |         Paint.FontMetricsInt fontMetrics = waitPaint.getFontMetricsInt(); | |||
|  |         // 转载请注明出处:http://blog.csdn.net/hursing | |||
|  |         int baseline = (targetRect.bottom + targetRect.top - fontMetrics.bottom - fontMetrics.top) *4/5; | |||
|  |         // 下面这行是实现水平居中,drawText对应改为传入targetRect.centerX() | |||
|  |         waitPaint.setTextAlign(Paint.Align.CENTER); | |||
|  |         c.drawText(status, targetRect.centerX(), baseline, waitPaint); | |||
|  | //        c.drawText("正在打开书本...", mHeight / 2, 0, waitPaint); | |||
|  |     /*    TextPaint tp = new TextPaint(); | |||
|  |         tp.setColor(getTextColor()); | |||
|  |         tp.setStyle(Paint.Style.FILL); | |||
|  |         tp.setTextSize(50); | |||
|  |         StaticLayout myStaticLayout = new StaticLayout(status, tp, c.getWidth(), Layout.Alignment.ALIGN_CENTER, 1.0f, 0.0f, false); | |||
|  |         myStaticLayout.draw(c);*/ | |||
|  | 
 | |||
|  | 
 | |||
|  |        // hideSysUI(); | |||
|  |        /* float adHeight = mHeight - baseline -marginHeight-statusMarginBottom-30; | |||
|  |         float adY =targetRect.top +10;*/ | |||
|  | 
 | |||
|  |         float adHeight = baseline -100; | |||
|  |         float adY =targetRect.top +250; | |||
|  | 
 | |||
|  |         if(showAd) | |||
|  |         while(!showingStatusAd /*|| new Date().getTime() - showStatusAdTime > 2000*/) { | |||
|  |             showingStatusAd =true; | |||
|  |             showStatusAdTime = new Date().getTime(); | |||
|  |          //   showStatusAd((int) adHeight, (int) adY); | |||
|  |         //    Log.d(TAG, "loadBannerAd: draw status, AD is requested, mStatus:" +mStatus); | |||
|  |         } | |||
|  | 
 | |||
|  |         if (mStatus==Status.OPENING ) { | |||
|  |             String url = mBookUtil.getChapter(getNovel().getLastReadChapt()).getChapterUrl(); | |||
|  |             if(!TextUtils.isEmpty(url)) { | |||
|  |                 if(url.length()>100) | |||
|  |                 url =url.substring(0,100); | |||
|  | 
 | |||
|  | 
 | |||
|  |                 waitPaint.setTextSize(mContext.getResources().getDimension(R.dimen.reading_medu_text_size));// 字体大小 | |||
|  |                 waitPaint.setColor(getTextColor()); | |||
|  |                 waitPaint.setTextAlign(Paint.Align.CENTER); | |||
|  | 
 | |||
|  |                 targetRect = new Rect(0, 0, mWidth, mHeight); | |||
|  | 
 | |||
|  |                 fontMetrics = waitPaint.getFontMetricsInt(); | |||
|  |                 baseline = baseline +150; | |||
|  |                 // 下面这行是实现水平居中,drawText对应改为传入targetRect.centerX() | |||
|  |                 String site = getSite().getName() ==null ? "":getSite().getName(); | |||
|  |                 waitPaint.setTextAlign(Paint.Align.CENTER); | |||
|  |                 c.drawText("正加载第三方网站 " +site, targetRect.centerX(), baseline, waitPaint); | |||
|  |                 baseline+=40; | |||
|  |                 if(Constants.SHOW_NOVEL_CHAPTER_URL) { | |||
|  |                     c.drawText(url, targetRect.centerX(), baseline, waitPaint); | |||
|  |                 } | |||
|  |                 String chaptName=  mBookUtil.getChapter(getNovel().getLastReadChapt()).getChapterName(); | |||
|  |                 if(!TextUtils.isEmpty(chaptName)) { | |||
|  |                     if(chaptName.length()>100) | |||
|  |                         chaptName =chaptName.substring(0,100); | |||
|  | 
 | |||
|  |                     chaptName ="正为您搜索加载 " +chaptName +" ..."; | |||
|  | 
 | |||
|  |                     baseline = 80; | |||
|  |                     // 下面这行是实现水平居中,drawText对应改为传入targetRect.centerX() | |||
|  |                     waitPaint.setTextAlign(Paint.Align.CENTER); | |||
|  |                     c.drawText(chaptName, targetRect.centerX(), baseline, waitPaint); | |||
|  |                 } | |||
|  | 
 | |||
|  |             } | |||
|  |         } | |||
|  |         mBookPageWidget.postInvalidate(); | |||
|  | 
 | |||
|  | 
 | |||
|  |     } | |||
|  | 
 | |||
|  | 
 | |||
|  | 
 | |||
|  | 
 | |||
|  |     //上次翻书时间 | |||
|  |     private long lastPageTime; | |||
|  | 
 | |||
|  |     public void onDraw(Bitmap bitmap,TRPage trPage,Boolean updateChapter,Boolean showAd) { | |||
|  |         hideSysUI(); | |||
|  |         List<String> m_lines = trPage.getLines(); | |||
|  |        // mAd.showRefresh(View.GONE); | |||
|  | 
 | |||
|  |         Log.d(TAG, String.format("onDraw: trPage pageno %s,showAd %s",trPage.getPageNo(),showAd)); | |||
|  | 
 | |||
|  | 
 | |||
|  |         if(m_lines.size()==0 ){ | |||
|  |             return; | |||
|  |         } | |||
|  |        /* try { | |||
|  |             throw new Exception("who's ad"); | |||
|  |         }catch (Exception e){ | |||
|  |             Log.e(TAG, "onDraw:showTopBanner ",e ); | |||
|  |         }*/ | |||
|  |        /* Log.d(TAG, "showloading: ondraw showAd:  " +showAd ); | |||
|  |         try{ | |||
|  |             throw  new Exception("showloading: ondraw mStatus:  " +mStatus ); | |||
|  |         }catch (Exception e){ | |||
|  |             Log.e(TAG, "showloading: ", e); | |||
|  |         }*/ | |||
|  | 
 | |||
|  | 
 | |||
|  |         if(showAd && mAd!=null){ | |||
|  |             handler.sendEmptyMessage(MSG_HID_AD); | |||
|  |             //handler.sendEmptyMessage(MSG_HID_AD); | |||
|  |             handler.sendEmptyMessage(MSG_HIDEPROGRESS); | |||
|  |             mAdHeight=0; | |||
|  |             mAdY=0; | |||
|  |         } | |||
|  |         mStatus =Status.FINISH; | |||
|  |         //    Log.d(TAG, String.format(" prepare book  onDraw chapter %s,  getChapters().size() %s ",currentChapter ,getChapters().size() ) ); | |||
|  |         if (getChapters().size() > 0 && updateChapter) { | |||
|  |        //     Log.d(TAG, String.format(" prepare book  onDraw chapter to getCurrentChapter(),currentChapter %s  ",currentChapter  ) ); | |||
|  |             currentChapter = getCurrentChapter(); | |||
|  |           //  Log.d(TAG, String.format(" prepare book  onDraw chapter after getCurrentChapter(),currentChapter %s  ",currentChapter  ) ); | |||
|  |         } | |||
|  |    //     Log.d(TAG, String.format(" prepare book  onDraw chapter _____________ %s  ",currentChapter  ) ); | |||
|  | 
 | |||
|  | 
 | |||
|  | 
 | |||
|  | 
 | |||
|  | 
 | |||
|  | 
 | |||
|  |         //更新数据库进度 | |||
|  |         if ( mStatus ==Status.FINISH && currentPage != null && getNovel() != null) { | |||
|  |             new Thread() { | |||
|  |                 @Override | |||
|  |                 public void run() { | |||
|  |                     super.run(); | |||
|  |                     if (getNovel().getLastReadChapt() != currentChapter || getNovel().getLastReadPos() != currentPage.getBegin()) { | |||
|  |                         if (currentChapter > 1) { | |||
|  | 
 | |||
|  |                             getNovel().setLastReadChapt(currentChapter); | |||
|  | 
 | |||
|  |                         } else { | |||
|  |                             getNovel().setToDefault("lastReadChapt"); | |||
|  |                         } | |||
|  |                         if(lastPageTime>0) { | |||
|  |                             long time = new Date().getTime() - lastPageTime; | |||
|  |                    //         Log.d(TAG, String.format("prepare book read time last %s,current %s,spent %s",lastPageTime,new Date().getTime(), time)); | |||
|  |                             if (time > 1000) { | |||
|  |                                 getNovel().setReadtime(getNovel().getReadtime() + time); | |||
|  |                             } | |||
|  |                         } | |||
|  |                         getNovel().setToDefault("isUpdated"); //去除更新标志 | |||
|  |                         getNovel().setLastReadPos(currentPage.getBegin()); | |||
|  | 
 | |||
|  |                         getNovel().update(getNovel().getId());  //If you set a default value to a field, the corresponding | |||
|  |                         //	 * column won't be updated. | |||
|  |                         //   getNovel().save(); | |||
|  | 
 | |||
|  |               /*       Novel nv = LitePal.find(Novel.class,getNovel().getId()); | |||
|  |                         Log.d(TAG,String.format("prepare book %s ,%s isUpdated %s,saved isUpdated %s, saved lastchapt %s,lastpos %s, db lastchapt %s last pos %s", | |||
|  |                                 getNovel().getId(), | |||
|  |                                 getNovel().getName(),getNovel().isUpdated(),nv.isUpdated(), | |||
|  |                                 currentChapter,currentPage.getBegin(),nv.getLastReadChapt(),nv.getLastReadPos()));*/ | |||
|  | 
 | |||
|  |                      lastPageTime = new Date().getTime(); | |||
|  | 
 | |||
|  |                     } | |||
|  |                     /* | |||
|  |                     values.put("lastReadPos",currentPage.getBegin()); | |||
|  |                     values.put("lastReadChapt",currentChapter); | |||
|  |                    Log.d(TAG,String.format("begin to update book %s chapter%s bigin %s ",getNovel().getName(),currentChapter, currentPage.getBegin() ) ); | |||
|  |                   int rows =  LitePal.update(Novel.class,values,getNovel().getId()); | |||
|  |                    Log.d(TAG,String.format("update book %s chapter%s bigin %s, result %s",getNovel().getName(),currentChapter, currentPage.getBegin(),rows) ); | |||
|  |                    */ | |||
|  |                 } | |||
|  |             }.start(); | |||
|  |         } | |||
|  | 
 | |||
|  |         Canvas c = new Canvas(bitmap); | |||
|  |         c.drawBitmap(getBgBitmap(), 0, 0, null); | |||
|  | //        word.setLength(0); | |||
|  |         mPaint.setTextSize(getFontSize()); | |||
|  |         mPaint.setColor(getTextColor()); | |||
|  |         mBatterryPaint.setColor(getTextColor()); | |||
|  |         if (m_lines.size() == 0) { | |||
|  |             return; | |||
|  |         } | |||
|  |         float space =m_fontSize + lineSpace; | |||
|  |         paragraphSpace = prate * lineSpace; | |||
|  | 
 | |||
|  |        // if(showAd && mAd!=null){ | |||
|  |             mAdHeight= Constants.AD_SETTING.getChapterBanner().getDisplayPosition() ==AD_BANNER_TOP ? trPage.getBannerHeight() :0; | |||
|  |             mAdY=(int)marginHeight; | |||
|  |             mAdType =AdTpye.BANNER; | |||
|  | 
 | |||
|  |            if(trPage.getBannerHeight()==0) { | |||
|  |                mAd.showTopBanner(0,0);//hide banner container | |||
|  |            } | |||
|  | 
 | |||
|  | 
 | |||
|  | 
 | |||
|  |      //   } | |||
|  | 
 | |||
|  |     /*    if(trPage.getPageNo()>1 && m_lines.size() <= mLineCount/2+1){ | |||
|  |             if(trPage.getTopBannerHeight() + trPage.getNativeBannerHeight() ==0){ | |||
|  |                 mAdHeight=(int)mBannerNaviHeight; | |||
|  |                 mAdY=(int)marginHeight; | |||
|  |                 mAdType =AdTpye.NATIVEINLINES; | |||
|  | 
 | |||
|  |             } | |||
|  |         }*/ | |||
|  | 
 | |||
|  | 
 | |||
|  |             float y = marginHeight +mAdHeight; | |||
|  |             String lastLine =""; | |||
|  |             int lineNo =0; | |||
|  |             for (String strLine : m_lines) { | |||
|  |                 lineNo++; | |||
|  |              //   if(strLine.endsWith("\n")) { | |||
|  |                // if(strLine.charAt(strLine.length()-1) == ('\n' )) { | |||
|  |               // Log.d(TAG, strLine); | |||
|  |               // Log.d(TAG,"最后字符 。。。" +strLine.charAt(strLine.length()-1) + ""); | |||
|  |                 lastLine =strLine; | |||
|  |                 strLine = strLine.replace("<22>",""); | |||
|  | 
 | |||
|  |                 if(lineNo==trPage.getNativeBannerStartLine()){ | |||
|  |                     if(showAd && mAd!=null){ | |||
|  |                         mAdHeight=trPage.getNativeBannerHeight(); | |||
|  |                         mAdY=(int)y  +(int)( +lineSpace*0.5); | |||
|  |                         mAdType =AdTpye.NATIVEINLINES; | |||
|  |                       //  mAd.showNativeBannerInLines(trPage.getNativeBannerHeight(),(int)y); | |||
|  |                     } | |||
|  |                     y+=trPage.getNativeBannerHeight() +m_fontSize +lineSpace ; | |||
|  |                     Log.d(TAG, String.format("onDraw showNativeBannerInLines : lineno %s,strline %s ",lineNo,strLine)); | |||
|  |                     space = m_fontSize + lineSpace; | |||
|  |                    // y-=lineSpace; | |||
|  |                     if (strLine.length() > 0 && (strLine.charAt(strLine.length() - 1) + "").equals("\n")) { | |||
|  |                         space = m_fontSize + paragraphSpace; | |||
|  |                     } | |||
|  |                 }else { | |||
|  | 
 | |||
|  |                     if (strLine.length() > 0 && (strLine.charAt(strLine.length() - 1) + "").equals("\n")) { | |||
|  |                         strLine = strLine.replace("\n", ""); | |||
|  | 
 | |||
|  |                         y += space; | |||
|  |                         space = m_fontSize + paragraphSpace; | |||
|  | 
 | |||
|  |                         //  Log.d( TAG ,String.format("prepare book 开始新段落 %s,  y plus is %s" ,strLine, m_fontSize + paragraphSpace)); | |||
|  |                     } else { | |||
|  |                         y += space; | |||
|  |                         space = m_fontSize + lineSpace; | |||
|  | 
 | |||
|  |                         //  Log.d(TAG,String.format("prepare book %s,y plus is %s" ,strLine, m_fontSize + lineSpace)); | |||
|  |                     } | |||
|  | 
 | |||
|  |                 } | |||
|  |                 c.drawText(strLine, measureMarginWidth, y, mPaint); | |||
|  | 
 | |||
|  | //                word.append(strLine); | |||
|  | 
 | |||
|  |             } | |||
|  | 
 | |||
|  | //            Log.d(TAG,String.format("getNavigationBarSize mHeight is %s ,last line height %s, power %s,  %s", // | |||
|  | //                  mHeight,y,mHeight - CommonUtil.convertDpToPixel(mContext,10) + mBorderWidth - statusMarginBottom, lastLine)); | |||
|  |            // lastLine =lastLine.trim().replace(Constants.BAD_CHAR,""); | |||
|  |             Log.d(TAG, String.format("onDraw: last line lenth %s,%s,   ",lastLine.length() ,lastLine)); | |||
|  |             float adHeight = mHeight -y - space -marginHeight-statusMarginBottom; | |||
|  |             float adY =y ;//+space; | |||
|  |             adY= lastLine.length()==0 ?adY-m_fontSize - lineSpace :adY; | |||
|  |             if(mAdHeight ==0 && showAd  ) { | |||
|  | 
 | |||
|  |                 if(trPage.getBannerHeight()>0){ | |||
|  |                     mAdY=(int) (mHeight - statusMarginBottom - trPage.getBannerHeight()); | |||
|  |                     mAdHeight =  trPage.getBannerHeight(); | |||
|  |                     mAdType =AdTpye.BANNER; | |||
|  |                 }else if(trPage.getPageNo()>1 && trPage.isLastPage() && Constants.AD_SETTING.getChapterEndBanner().isShow())  { | |||
|  |                     mAdY=(int)adY; | |||
|  |                     mAdHeight = (int) adHeight; | |||
|  |                     mAdType = AdTpye.CHAPTEREND; | |||
|  | 
 | |||
|  |                 }else{ | |||
|  |                     mAd.showNativeBannerInLines(0, 0);//清除内容广告 | |||
|  |                 } | |||
|  | 
 | |||
|  | 
 | |||
|  |               //  showAd((int) adHeight, (int) adY); | |||
|  |                 Log.d(TAG, String.format("loadBannerAd: AD is requested, adtype %s, adHeight %s, ady %s",mAdType,adHeight,adY)); | |||
|  |             } | |||
|  |          //   Log.d(TAG,String.format("ad + statusMarginBottom %s ",200+ statusMarginBottom)); | |||
|  |         //    Log.d(TAG,String.format("adHeight %s, adY %s",adHeight,adY)); | |||
|  | 
 | |||
|  |         if(trPage.getBannerHeight()==0 ){ | |||
|  |             mAd.showTopBanner(0, 0);//清除 banner广告 | |||
|  |         } | |||
|  |         if(trPage.getNativeBannerHeight()==0 && mAdType != AdTpye.CHAPTEREND){ | |||
|  |             mAd.showNativeBannerInLines(0,0);//hide content banner container | |||
|  |         } | |||
|  | 
 | |||
|  |         //画进度及时间 | |||
|  |         int dateWith = (int) (mBatterryPaint.measureText(date)+mBorderWidth);//时间宽度 | |||
|  |        // float fPercent = (float) (currentPage.getBegin() * 1.0 / mBookUtil.getChapterLen());//进度 | |||
|  |         float fPercent = (float) (currentPage.getPageNo() * 1.0 /currentChaptPages.size());//进度 | |||
|  |         currentProgress = fPercent; | |||
|  |         if (mPageEvent != null){ | |||
|  |             mPageEvent.changeProgress(fPercent); | |||
|  |         } | |||
|  |        // String strPercent = df.format(fPercent * 100) + "%";//进度文字 | |||
|  |         String strPercent = String.format("%s/%s",currentPage.getPageNo(),currentChaptPages.size()) + "页";//进度文字 | |||
|  |         int nPercentWidth = (int) mBatterryPaint.measureText("10/25页") + 50;  //Paint.measureText直接返回參數字串所佔用的寬度 | |||
|  |         float botoomY =mHeight - statusMarginBottom;// +screenHeihtDiff; | |||
|  |         c.drawText(strPercent, mWidth - nPercentWidth, botoomY, mBatterryPaint);//x y为坐标值 | |||
|  |         c.drawText(date, marginWidth ,botoomY, mBatterryPaint); | |||
|  |         // 画电池 | |||
|  |         Log.d(TAG, String.format("updateBattery to draw:   level1 %s ",level)); | |||
|  |       //  level = batteryInfoIntent.getIntExtra( "level" , 0 ); | |||
|  |         int scale = batteryInfoIntent.getIntExtra("scale", 100); | |||
|  |         mBatteryPercentage = (float) level / scale; | |||
|  |         Log.d(TAG, String.format("updateBattery to draw:   level2 %s ",level)); | |||
|  | 
 | |||
|  |         float rect1Left = marginWidth + dateWith + statusMarginBottom;//电池外框left位置 | |||
|  |         //画电池外框 | |||
|  |         float width = CommonUtil.convertDpToPixel(mContext,20) - mBorderWidth; | |||
|  |         float height = CommonUtil.convertDpToPixel(mContext,10); | |||
|  |         rect1.set(rect1Left, botoomY - height  ,rect1Left + width, botoomY); | |||
|  |         rect2.set(rect1Left + mBorderWidth, botoomY - height + mBorderWidth  , rect1Left + width - mBorderWidth, botoomY - mBorderWidth ); | |||
|  |        // c.save(Canvas.CLIP_SAVE_FLAG); | |||
|  |         c.save(); | |||
|  |         c.clipRect(rect2, Region.Op.DIFFERENCE); | |||
|  |         c.drawRect(rect1, mBatterryPaint); | |||
|  |         c.restore(); | |||
|  |         //画电量部分 | |||
|  |         rect2.left += mBorderWidth; | |||
|  |         rect2.right -= mBorderWidth; | |||
|  |         rect2.right = rect2.left + rect2.width() * mBatteryPercentage; | |||
|  |         rect2.top += mBorderWidth; | |||
|  |         rect2.bottom -= mBorderWidth; | |||
|  |         c.drawRect(rect2, mBatterryPaint); | |||
|  |         //画电池头 | |||
|  |         int poleHeight = (int) CommonUtil.convertDpToPixel(mContext,10) / 2; | |||
|  |         rect2.left = rect1.right; | |||
|  |         rect2.top = rect2.top + poleHeight / 4; | |||
|  |         rect2.right = rect1.right + mBorderWidth; | |||
|  |         rect2.bottom = rect2.bottom - poleHeight/4; | |||
|  |         c.drawRect(rect2, mBatterryPaint); | |||
|  |         //画书名 | |||
|  |         c.drawText(CommonUtil.subString(bookName,12), marginWidth ,statusMarginBottom + mBatterryFontSize, mBatterryPaint); | |||
|  |         //画章 | |||
|  |        /* String chapterName =""; | |||
|  |         if(mCurrentChapter!=null){ | |||
|  |             chapterName = mCurrentChapter.getChapterName(); | |||
|  |         }else*/ | |||
|  |      //  if (getChapters().size() > 0) | |||
|  |         { | |||
|  |             String  chapterName =CommonUtil.subString(mBookUtil.getChapter(mBookUtil.getChapterNo()).getChapterName(),16); // CommonUtil.subString(getChapterName(),16); | |||
|  |             int nChaterWidth = (int) mBatterryPaint.measureText(chapterName) + 1; | |||
|  |             c.drawText(chapterName, mWidth - marginWidth - nChaterWidth, statusMarginBottom  + mBatterryFontSize, mBatterryPaint); | |||
|  | 
 | |||
|  |         } | |||
|  |         if(mBookPageWidget!=null) | |||
|  |         mBookPageWidget.postInvalidate(); | |||
|  |         if(currentPage!=null && currentPage.getPageNo()==1){ | |||
|  | 
 | |||
|  |             String sn = getNovel().getDomainName(); | |||
|  |              if(TextUtils.isEmpty(sn)){ | |||
|  |                  if(getSite()!=null &&getSite().getName() !=null ){ | |||
|  |                      sn =getSite().getName(); | |||
|  |                  } | |||
|  |              } | |||
|  | 
 | |||
|  |             String source =String.format("本章节内容来自网络"); | |||
|  |             if(!TextUtils.isEmpty(sn)){ | |||
|  |                 source =String.format("本章节内容来自第三方网站:%s",sn); | |||
|  |             } | |||
|  |             int anny= (int) CommonUtil.convertDpToPixel(mContext,25); | |||
|  |             c.drawText(source,   marginWidth, statusMarginBottom  + mBatterryFontSize+anny, mBatterryPaint); | |||
|  |              anny= (int) CommonUtil.convertDpToPixel(mContext,45); | |||
|  |             c.drawText( Constants.announcement,   marginWidth, statusMarginBottom  + mBatterryFontSize+anny, mBatterryPaint); | |||
|  | 
 | |||
|  |         } | |||
|  |     } | |||
|  | 
 | |||
|  |     public void showAd(){ | |||
|  |         Log.d(TAG, String.format("loadBannerAd showAd: mAdType %s ",mAdType )); | |||
|  |         if(mStatus == Status.LASTPAGE || mAd==null ||currentPage==null){ | |||
|  |             return; | |||
|  |         } | |||
|  |        Log.d(TAG, String.format("loadBannerAd showAd: mAdType %s, pageNo %s",mAdType, currentPage.getPageNo())); | |||
|  |         if(mAdType ==AdTpye.BANNER){ | |||
|  |             mAd.showTopBanner(mAdHeight,mAdY); | |||
|  |         }else if(mAdType == AdTpye.NATIVEINLINES){ | |||
|  |            // mAd.showNativeBannerInLines(0,0); | |||
|  |             mAd.showNativeBannerInLines(mAdHeight,mAdY); | |||
|  |         }else if(mAdType == AdTpye.CHAPTEREND){ | |||
|  |          //   mAd.showNativeBannerInLines(0,0); | |||
|  |             mAd.showNativeBannerInLines(mAdHeight,mAdY); | |||
|  |         }else{ | |||
|  |             mAd.showNativeBannerInLines(0,0); | |||
|  |         } | |||
|  | 
 | |||
|  |     } | |||
|  |     private void showStatusAd(int adHeight,int adY) { | |||
|  | 
 | |||
|  |          boolean showAd = showingStatusAd /*|| getCurrentPage()==null || getCurrentPage().getPageNo() > 1*/; | |||
|  |         //Log.d(TAG, String.format("loadBannerAd showStatusAd: mAdType %s",mAdType)); | |||
|  |        // boolean showAd =true; | |||
|  |           if (showAd && mAd != null) { | |||
|  |              //   mAd.showStatusAd(adHeight, adY); | |||
|  | 
 | |||
|  |             } | |||
|  | 
 | |||
|  | 
 | |||
|  |     } | |||
|  | 
 | |||
|  |     //向前翻页 | |||
|  |     public void prePage(){ | |||
|  | 
 | |||
|  |         if(null == currentPage){ | |||
|  |             return; | |||
|  |         } | |||
|  |         if(mBookUtil.isBusy()){ | |||
|  |             return; | |||
|  |         } | |||
|  |         m_isfirstPage = false; | |||
|  |         if (currentPage.getBegin() <= 1) { | |||
|  |            Log.d(TAG,"当前是本章第一页"); | |||
|  |             m_isfirstPage =currentChapter ==1; | |||
|  |             if ( m_isfirstPage){ | |||
|  |                 Toast.makeText(mContext, "当前是第一页", Toast.LENGTH_SHORT).show(); | |||
|  |                 return; | |||
|  |             } | |||
|  |         } | |||
|  | 
 | |||
|  |         Log.d(TAG, "prepare book prePage: to  open prepage: "); | |||
|  |         cancelPage = currentPage; | |||
|  |         if(mBookPageWidget==null){ | |||
|  |             return; | |||
|  |         } | |||
|  |         if(mStatus ==Status.LASTPAGE) { | |||
|  |             onDraw(mBookPageWidget.getCurPage(),currentPage ,true,false); | |||
|  |             if(mBookPageWidget==null){ | |||
|  |                 return; | |||
|  |             } | |||
|  |             Log.d(TAG, " prePage() onDraw: mBookPageWidget.getNextPage() "); | |||
|  |             onDraw(mBookPageWidget.getNextPage(),currentPage ,true,true); | |||
|  |         }else{ | |||
|  |             if(mBookPageWidget==null){ | |||
|  |                 return; | |||
|  |             } | |||
|  |             Log.d(TAG, " prePage() onDraw: mBookPageWidget.getNextPage() "); | |||
|  |             currentPage = getPrePage(); | |||
|  |             onDraw(mBookPageWidget.getNextPage(),currentPage ,true,true); | |||
|  |         } | |||
|  | 
 | |||
|  |     } | |||
|  | 
 | |||
|  |     //向后翻页 | |||
|  |     public void nextPage(){ | |||
|  | 
 | |||
|  |         m_islastPage = false; | |||
|  | 
 | |||
|  |        if(null == currentPage){ | |||
|  |           changeChapter(mBookUtil.getChapterNo()); | |||
|  |            return; | |||
|  |        } | |||
|  |        if(mBookUtil.isBusy()){ | |||
|  |            return; | |||
|  |        } | |||
|  | 
 | |||
|  |         Log.d(TAG, "prepare book nextPage:chaptid " +mBookUtil.getChapterNo()); | |||
|  |         if (currentPage.getEnd() >= mBookUtil.getChapterLen()) { | |||
|  |            Log.d(TAG,"已经是本章最后一页了"); | |||
|  |             File file =new File( mBookUtil.fileChapterName(currentChapter+1)); | |||
|  |             if(!file.exists()) | |||
|  |             if(mBookUtil.getChapters().size()==0 &&NetUtil.isNetworkConnected()){ | |||
|  |                 mBookUtil.setChapterNo(currentChapter+1); | |||
|  |                 mStatus = Status.OPENING; | |||
|  |                 drawStatus(); | |||
|  |                 new Thread() { | |||
|  |                     @Override | |||
|  |                     public void run() { | |||
|  |                         int slepttime = 0; mBookUtil.muluRetryCount=0; | |||
|  |                         while (slepttime<200 && mBookUtil.getChapters().size()==0 && (mBookUtil.mMuluStatus == BookUtil.MuluStatus.isDownloading || mBookUtil.muluRetryCount < Constants.retryCnt)) { | |||
|  |                             try { | |||
|  |                                 sleep(50); | |||
|  |                                 slepttime++; | |||
|  | 
 | |||
|  |                             } catch (InterruptedException e) { | |||
|  |                                 e.printStackTrace(); | |||
|  |                             } | |||
|  |                         } | |||
|  | 
 | |||
|  |                         Log.d(TAG, String.format("prepare book waiting for chapters slept %s, chapt size %s,  MuluStatus %s, muluRetryCount %s ,mStatus %s" , | |||
|  |                                 slepttime *50,mBookUtil.getChapters().size(),mBookUtil.mMuluStatus,mBookUtil.muluRetryCount,mStatus)); | |||
|  | 
 | |||
|  |                          if(mBookUtil.getChapters().size()>0){ | |||
|  |                              if(  mBookUtil.getChapterNo() == mBookUtil.getChapters().size()+1){ | |||
|  |                                  mBookUtil.setChapterNo(mBookUtil.getChapterNo()-1); | |||
|  |                              } | |||
|  |                              currentChapter=mBookUtil.getChapterNo(); | |||
|  |                            handler.sendEmptyMessage(MSG_NEXTPAGE) ; | |||
|  |                          }else if(mStatus !=Status.OPENING){ | |||
|  |                              handler.sendEmptyMessage(MSG_NEXTPAGE_FAIL) ; | |||
|  |                          } | |||
|  | 
 | |||
|  |                     }}.start(); | |||
|  | 
 | |||
|  |                 return; | |||
|  |             } | |||
|  |             m_islastPage =currentChapter == mBookUtil.getChapters().size();// ||mBookUtil.getChapters().size()==0; | |||
|  |             if ( m_islastPage){ | |||
|  | 
 | |||
|  |                  Toast.makeText(mContext, "已经是最后一页了", Toast.LENGTH_SHORT).show(); | |||
|  |                  mStatus = Status.LASTPAGE; | |||
|  |                  drawStatus(); | |||
|  |              //   currentPage(false); | |||
|  |                 return; | |||
|  |             } else if(mBookUtil.getChapters().size()==0){ | |||
|  |                 return; | |||
|  |             } | |||
|  |         } | |||
|  |       //  Log.d(TAG, "prepare book nextPage: to  open next page: "); | |||
|  |         cancelPage = currentPage; | |||
|  |         if(mBookPageWidget==null){ | |||
|  |             return; | |||
|  |         } | |||
|  |         Log.d(TAG, "nextPage() onDraw: mBookPageWidget.getCurPage() "); | |||
|  |         onDraw(mBookPageWidget.getCurPage(),currentPage ,true,false); | |||
|  |         prePage = currentPage; | |||
|  |          currentPage = getNextPage(); | |||
|  |         // currentPage = currentChaptPages.get(currentPage.getPageNo()-1); | |||
|  |         if(mBookPageWidget==null){ | |||
|  |             return; | |||
|  |         } | |||
|  |         Log.d(TAG, "nextPage() onDraw: mBookPageWidget.getNextPage() "); | |||
|  |         onDraw(mBookPageWidget.getNextPage(),currentPage ,true,true); | |||
|  |        Log.d("nextPage","nextPagenext"); | |||
|  | 
 | |||
|  |         HashMap<String,String> map = new HashMap<String,String>(); | |||
|  |         map.put("novel",bookName); | |||
|  |         map.put("chapt",getChapter().getChapterName()); | |||
|  |         map.put("page",currentPage.getPageNo()+""); | |||
|  |         MobclickAgent.onEvent(MyApp.applicationContext, "page_reading", map); | |||
|  |     } | |||
|  | 
 | |||
|  |     //取消翻页 | |||
|  |     public void cancelPage(){ | |||
|  |         if(cancelPage !=null && (cancelPage.isLastPage() || cancelPage.isFirstPage())){ | |||
|  |             mBookUtil.setChapterNo(cancelPage.getChapterNo()); | |||
|  |             currentChaptPages = loadCurrentChapt(cancelPage.getChapterNo()); | |||
|  |             currentPage = getPageForBegin(cancelPage.getBegin()) ;// currentChaptPages.get(0); | |||
|  |             //  currentPage = getPageForBegin(begin); | |||
|  |           /*  if (mBookPageWidget != null) { | |||
|  |                 currentPage(true); | |||
|  |             }*/ | |||
|  |         } | |||
|  |         currentPage = cancelPage; | |||
|  |         if (mBookPageWidget != null) { | |||
|  |             currentPage(true); | |||
|  |         } | |||
|  |     } | |||
|  | 
 | |||
|  |     public void prepareBook(Novel book){ | |||
|  | 
 | |||
|  |         Log.d(TAG, "prepare book:  start prepare book " + book.getName()); | |||
|  | 
 | |||
|  |         if(getNovel()!=null) { | |||
|  |             if (getNovel().getNovelId() != book.getNovelId()) { //取消未上本书完成的web请求,待验证效果 | |||
|  |                 try { | |||
|  |                     NetUtil.cancelRequest(getNovel().getNovelId()); | |||
|  |                 } catch (Exception e) { | |||
|  |                     Log.e(TAG, "prepare book: error on canceling request " + e.getMessage()); | |||
|  |                     e.printStackTrace(); | |||
|  |                 } | |||
|  |             }else{ | |||
|  |                 Log.d(TAG, "prepare book: has been prepared, return.... " + book.getName()); | |||
|  |                if(mBookUtil!=null) { | |||
|  |                    return; | |||
|  |                } | |||
|  |             } | |||
|  | 
 | |||
|  |         } | |||
|  |         mBookUtil = new BookUtil(); | |||
|  |         mBookUtil.pagefactory=this; | |||
|  |         //this.mBookUtil.setContext(context); | |||
|  |         this.mBookUtil.setNovel(book); | |||
|  |         this.mBookUtil.getTargetSites(); | |||
|  |     } | |||
|  |     public void initBookUtil() { | |||
|  |         mBookUtil = new BookUtil(); | |||
|  |     } | |||
|  |     /** | |||
|  |      * 打开书本 | |||
|  |      * @throws IOException | |||
|  |      */ | |||
|  |     public void openBook(Novel book ,Context context) throws IOException { | |||
|  | 
 | |||
|  |         if(book==null){ | |||
|  |             return; | |||
|  |         } | |||
|  |           if(book.isLocalBook()){ //离线书籍重新初始化加载mBookUtil | |||
|  |               mBookUtil = new BookUtil(); | |||
|  |               mBookUtil.setNovel(book); | |||
|  |           }else if(mBookUtil ==null || getNovle()==null){ | |||
|  |               Log.d(TAG, "prepare book: preparing in openBook method" + book.getName()); | |||
|  |               prepareBook(book); | |||
|  |           } | |||
|  |         mBookUtil.setContext(context); | |||
|  |         mContext =context; | |||
|  |         mBookUtil.pagefactory=this; | |||
|  |         //清空数据 | |||
|  |         currentChapter = 0; | |||
|  | //        m_mbBufLen = 0; | |||
|  |         initBg(config.getDayOrNight()); | |||
|  | 
 | |||
|  |         if(getNovel()!=null &&getNovel().getNovelId() !=book.getNovelId()){ //取消未上本书完成的web请求 | |||
|  |            NetUtil.cancelRequest(getNovel().getNovelId() ); | |||
|  |         } | |||
|  | 
 | |||
|  |         bookPath = book.getNovelPath(); | |||
|  |         bookName =book.getName();// FileUtils.getFileName(bookPath); | |||
|  |       //  this.mCurrentChapter = chapter; | |||
|  |         mStatus = Status.OPENING; | |||
|  | 
 | |||
|  |          | |||
|  | 
 | |||
|  |         if (bookTask != null && bookTask.getStatus() != AsyncTask.Status.FINISHED){ | |||
|  |             bookTask.cancel(true); | |||
|  |         } | |||
|  | 
 | |||
|  |         bookTask = new BookTask(); | |||
|  |         Log.d(TAG, String.format("prepare book 1 to open chapter %s ,position %s,source %s",book.getLastReadChapt() ,book.getLastReadPos(),book.getDomain()+book.getDomainName() ) ); | |||
|  |         bookTask.execute((long)book.getLastReadChapt(),book .getLastReadPos()); | |||
|  | 
 | |||
|  |         drawStatus(); | |||
|  |     } | |||
|  | 
 | |||
|  |     private class BookTask extends AsyncTask<Long,Void,Boolean>{ | |||
|  |         private long chapter=0; | |||
|  |         private long begin = 0; | |||
|  |         @Override | |||
|  |         protected void onPostExecute(Boolean result) { | |||
|  |             super.onPostExecute(result); | |||
|  |            Log.d("onPostExecute",isCancelled() + ""); | |||
|  |             if (isCancelled()){ | |||
|  |                 return; | |||
|  |             } | |||
|  |             if (result) { | |||
|  |                 Log.d(TAG, String.format("prepare book  ready, to open chapter %s ",chapter  ) ); | |||
|  | //                m_mbBufLen = mBookUtil.getChapterLen(); | |||
|  |                 currentChapter =(int)chapter; | |||
|  |                 mBookUtil.setChapterNo((int)chapter); | |||
|  |                 Log.d(TAG, String.format("prepare book  ready, to open chapter, loadCurrentChapt %s ",chapter  ) ); | |||
|  |                 currentChaptPages = loadCurrentChapt((int)chapter); | |||
|  |                 currentPage = getPageForBegin(begin) ;// currentChaptPages.get(0); | |||
|  |               //  currentPage = getPageForBegin(begin); | |||
|  |                 if (mBookPageWidget != null) { | |||
|  |                     currentPage(true); | |||
|  |                     showAd(); | |||
|  |                 } | |||
|  |              //   Log.d(TAG, String.format("prepare book  set PageFactory.mStatus %s .",PageFactory.Status.FINISH ) ); | |||
|  |                // PageFactory.mStatus = PageFactory.Status.FINISH; | |||
|  |             }else{ | |||
|  |                 PageFactory.mStatus = PageFactory.Status.FAIL; | |||
|  |                 drawStatus(); | |||
|  |                  | |||
|  |                 Toast.makeText(mContext,"打开书本失败!",Toast.LENGTH_SHORT).show(); | |||
|  |             } | |||
|  |         } | |||
|  | 
 | |||
|  |         @Override | |||
|  |         protected void onPreExecute() { | |||
|  |             super.onPreExecute(); | |||
|  | 
 | |||
|  |         } | |||
|  | 
 | |||
|  |         @Override | |||
|  |         protected void onProgressUpdate(Void... values) { | |||
|  |             super.onProgressUpdate(values); | |||
|  |         } | |||
|  | 
 | |||
|  |         @Override | |||
|  |         protected Boolean doInBackground(Long... params) { | |||
|  |             chapter = params[0]; | |||
|  |             begin = params[1]; | |||
|  |             currentChapter = (int) chapter; | |||
|  | 
 | |||
|  |             try { | |||
|  |                 int slept=0; | |||
|  |                 while(getNovel() ==null){ | |||
|  |                   //  Log.d(TAG, "prepare book:waiting for bookutil book:" + getNovel()); | |||
|  |                     Thread.sleep(10); | |||
|  |                     slept++; | |||
|  |                    if(slept>500){ | |||
|  |                        return false; | |||
|  |                    } | |||
|  |                 } | |||
|  | 
 | |||
|  |                 Log.d(TAG, "prepare book:waiting for bookutil book slept "+slept*10); | |||
|  |                 mBookUtil.openBook(getNovel(),chapter); | |||
|  |             } catch (Exception e) { | |||
|  |                 Log.e(TAG, "prepare book: backgroud error", e); | |||
|  |                 e.printStackTrace(); | |||
|  |                 return false; | |||
|  |             } | |||
|  |             return true; | |||
|  |         } | |||
|  | 
 | |||
|  |     } | |||
|  | 
 | |||
|  |     public TRPage getNextPage(){ | |||
|  | 
 | |||
|  |        int nextPageNo =currentPage.getPageNo(); | |||
|  |        Log.e(TAG,String.format("prepare book getNextPage() currentChapter %s, chapters().size() %s,currentChaptPages .size() is %s,currentpage pageno is %s" | |||
|  |                ,currentChapter, getChapters().size(), currentChaptPages.size() ,   nextPageNo)); | |||
|  |        if(nextPageNo==0){ | |||
|  |            drawStatus(); | |||
|  |        } | |||
|  |        if(nextPageNo >= currentChaptPages.size() && (getChapters().size()==0 || getChapters().size()>currentChapter)){ | |||
|  |            preChaptPages =currentChaptPages; | |||
|  |            currentChapter++; | |||
|  |             mBookUtil.setChapterNo(currentChapter); | |||
|  |             currentChaptPages =   loadCurrentChapt(currentChapter )     ; | |||
|  |             nextPageNo =0; | |||
|  |        }else { | |||
|  |            if(getChapters().size()>currentChapter) { | |||
|  |                preReadChaptCache(currentChapter + 1); | |||
|  |            } | |||
|  |        } | |||
|  |        if(currentChaptPages.size()>nextPageNo) | |||
|  |             return currentChaptPages.get(nextPageNo); | |||
|  |        else{ | |||
|  |            return new TRPage(""); | |||
|  |        } | |||
|  |     } | |||
|  | 
 | |||
|  |     public TRPage getPrePage(){ | |||
|  | 
 | |||
|  | 
 | |||
|  |         int prePageNo =currentPage.getPageNo()-1; | |||
|  |         Log.d(TAG,String.format("currentPageno %s,total pagno %s",currentPage.getPageNo(),currentChaptPages.size())); | |||
|  | 
 | |||
|  | 
 | |||
|  |         if(prePageNo <=0){ | |||
|  |             nextChaptPages =currentChaptPages; | |||
|  |             currentChapter--; | |||
|  |             if(currentChapter ==0) { | |||
|  |                 return   new TRPage("没有内容了"); | |||
|  |             } | |||
|  |             mBookUtil.setChapterNo(currentChapter); | |||
|  |             currentChaptPages =   loadCurrentChapt(currentChapter )     ; | |||
|  |             prePageNo = currentChaptPages.size(); | |||
|  |         }else{ | |||
|  |             if(currentChapter-1>0) { | |||
|  |                  preReadChaptCache(currentChapter - 1); | |||
|  |             } | |||
|  |         } | |||
|  | 
 | |||
|  |         return currentChaptPages.get(prePageNo-1); | |||
|  | 
 | |||
|  |     } | |||
|  | 
 | |||
|  |     public TRPage getPageForBegin(long begin){ | |||
|  |      /* | |||
|  |         TRPage trPage = new TRPage(); | |||
|  |         trPage.setBegin(begin); | |||
|  | 
 | |||
|  |         mBookUtil.setPostition(begin - 1); | |||
|  |         trPage.setLines(getNextLines()); | |||
|  |         trPage.setEnd(mBookUtil.getPosition()); | |||
|  |         return trPage; | |||
|  |         */ | |||
|  |      if(currentChaptPages.size()==0){ | |||
|  |          return  new TRPage(); | |||
|  |      } | |||
|  |         Log.d(TAG, String.format("prepare book getPageForBegin: currentChaptPages count %s, chaptid %s, begin %s ",currentChaptPages.size(),currentChapter,begin)); | |||
|  |      for(TRPage page : currentChaptPages) | |||
|  |      { | |||
|  |          if(page.getEnd() >=begin){ | |||
|  |              return  page; | |||
|  |          } | |||
|  |      } | |||
|  | 
 | |||
|  |      //return new TRPage();// currentChaptPages.get(currentChaptPages.size()-1); | |||
|  |      return  currentChaptPages.get(currentChaptPages.size()-1); | |||
|  |     } | |||
|  | 
 | |||
|  |     boolean showChapTitleOnTopWhenNextPage =false; | |||
|  |     public List<String> getNextLines(int chaptId,TRPage trpage){ | |||
|  |         List<String> lines = new ArrayList<>(); | |||
|  |         float width = 0; | |||
|  |         float height = 0; | |||
|  |         String line = ""; | |||
|  |        // boolean isFirstPage =false; | |||
|  |         int firstPageLine =0; | |||
|  |         if(mBookUtil.getPosition(chaptId)==0) { | |||
|  |             lines.add("\n");//lines.add("\n"); | |||
|  |         } | |||
|  |         int adHeight = trpage.getNativeBannerHeight()+trpage.getBannerHeight(); | |||
|  |         calculateLineCount(adHeight ); | |||
|  |         Log.d(TAG, String.format("getNextChapterPage getNextLines: pageNo %s, adHeight %s, totalLines %s",trpage.getPageNo(),adHeight,mLineCount)); | |||
|  |         while (mBookUtil.next(true,chaptId) != -1){ | |||
|  |             char word = (char) mBookUtil.next(false,chaptId); | |||
|  |         //    Log.d(TAG, String.format(" loadchapt  getNextLines(), chaptId %s, word '%s'", chaptId,word  )); | |||
|  |             if((word+"").equals(Constants.BAD_CHAR)){ | |||
|  |               //  continue; | |||
|  |             } | |||
|  |             //判断是否换行 | |||
|  |             if ((word + "" ).equals("\n")  ){//   if ((word + "" ).equals("\r") && (((char) mBookUtil.next(true)) + "").equals("\n")){ | |||
|  |               //  mBookUtil.next(false); | |||
|  |                 if ( !line.isEmpty()){ | |||
|  |                     if (showChapTitleOnTopWhenNextPage && lines.size() >0 && mBookUtil.isChapterTitle(line)) { | |||
|  |                       Log.d(TAG,String.format("title is %s\n,size is %s ,position is %s" ,line,line.length(),mBookUtil.getPosition(chaptId)  )); | |||
|  |                         //isFirstPage =true; | |||
|  |                         firstPageLine=1; | |||
|  |                          break; | |||
|  |                     } | |||
|  |                 //    Log.d(TAG, String.format(" loadchapt  getNextLines(),chaptId %s, new line with enter '%s' ", chaptId, line+word  )); | |||
|  |                     lines.add(line+word); | |||
|  |                   //  lines.add("\n"); | |||
|  |                     line = ""; | |||
|  |                     width = 0; | |||
|  |                      height +=  paragraphSpace - lineSpace; | |||
|  |                     calculateLineCount(adHeight+height); | |||
|  |                     if (lines.size()>=   mLineCount +firstPageLine){ | |||
|  |                      //  Log.d(TAG,String.format("lines count limit a %s,lines size %s",mLineCount,lines.size())); | |||
|  |                         line =""; | |||
|  |                         break; | |||
|  |                     } | |||
|  |                 } | |||
|  |             }else { | |||
|  |                 float widthChar = mPaint.measureText(word + ""); | |||
|  | 
 | |||
|  |                 if(widthChar==0){ | |||
|  |                     continue; | |||
|  |                 } | |||
|  | 
 | |||
|  |                 width += widthChar; | |||
|  |            //     Log.d(TAG, String.format(" loadchapt  getNextLines(),widthChar %s ,width %s,mVisibleWidth %s",widthChar, width ,mVisibleWidth )); | |||
|  | 
 | |||
|  | 
 | |||
|  |                 if (width > mVisibleWidth) { | |||
|  |                     width = widthChar; | |||
|  |                     lines.add(line); | |||
|  |               //      Log.d(TAG, String.format(" loadchapt  getNextLines(),chaptId %s,new line '%s' ",chaptId , line   )); | |||
|  |                    /* if (lines.size() == mLineCount){ | |||
|  |                        Log.d(TAG,String.format("lines count limit b %s,lines size %s",mLineCount,lines.size())); | |||
|  |                         line =""; | |||
|  |                         break; | |||
|  |                     } | |||
|  |                     */ | |||
|  |                     line = word + ""; | |||
|  |                 } else { | |||
|  | 
 | |||
|  |                     line += word; | |||
|  |                 //    Log.d(TAG, String.format(" loadchapt  getNextLines(),chaptId %s,growing line '%s' ",chaptId , line   )); | |||
|  |                 } | |||
|  |             } | |||
|  | 
 | |||
|  |             if (lines.size() == mLineCount +firstPageLine){ | |||
|  |             // Log.d(TAG,String.format("loadchapt lines count ,chaptId %s limit c %s,lines size %s",chaptId ,mLineCount,lines.size())); | |||
|  |                 if (!line.isEmpty()){ | |||
|  |                   //  mBookUtil.setPostition(mBookUtil.getPosition() - line.length()-2);// mBookUtil.setPostition(mBookUtil.getPosition() - 1); | |||
|  |                     mBookUtil.setPostition(chaptId,mBookUtil.getPosition(chaptId) - 1); | |||
|  |                 } | |||
|  |                 break; | |||
|  |             } | |||
|  |         } | |||
|  |         /* | |||
|  |         if (lines.size() == mLineCount) { | |||
|  |            Log.d(TAG, String.format("lines count limit d %s,lines size %s", mLineCount, lines.size())); | |||
|  |            Log.d(TAG, String.format("lines count limit d %s,line is \n %s", mLineCount, line)); | |||
|  |             if (!line.isEmpty()) { | |||
|  |                 mBookUtil.setPostition(mBookUtil.getPosition() - line.length() - 2);// mBookUtil.setPostition(mBookUtil.getPosition() - 1); | |||
|  |             } | |||
|  |         }*/ | |||
|  | 
 | |||
|  |         if (!line.isEmpty() && lines.size() < mLineCount +firstPageLine){ | |||
|  | 
 | |||
|  |            if (!(showChapTitleOnTopWhenNextPage && mBookUtil.isChapterTitle(line)  ) ) { | |||
|  |                 lines.add(line); | |||
|  |             }else | |||
|  |             { | |||
|  |               //  mBookUtil.setPostition(mBookUtil.getPosition() - line.length()-2); | |||
|  |             } | |||
|  |          //   lines.add(line); | |||
|  |         } | |||
|  |         /*for (String str : lines){ | |||
|  |           Log.d(TAG,str + "   "); | |||
|  |           }*/ | |||
|  |         return lines; | |||
|  |     } | |||
|  | 
 | |||
|  |     /*public List<String> getPreLines(){ | |||
|  |         List<String> lines = new ArrayList<>(); | |||
|  |         float width = 0; | |||
|  |         String line = ""; | |||
|  | 
 | |||
|  |         char[] par = mBookUtil.preLine(); | |||
|  |         while (par != null){ | |||
|  |             List<String> preLines = new ArrayList<>(); | |||
|  |             for (int i = 0 ; i < par.length ; i++){ | |||
|  |                 char word = par[i]; | |||
|  |                 float widthChar = mPaint.measureText(word + ""); | |||
|  |                 width += widthChar; | |||
|  |                 if (width > mVisibleWidth) { | |||
|  |                     width = widthChar; | |||
|  |                     preLines.add(line); | |||
|  |                     line = word + ""; | |||
|  |                 } else { | |||
|  |                     line += word; | |||
|  |                 } | |||
|  | //               Log.d(TAG,"preLine is \n" + line); | |||
|  |             } | |||
|  | 
 | |||
|  |           *//*  if ( mBookUtil.isChapterTitle(line)) { | |||
|  | 
 | |||
|  |                 mBookUtil.setPostition(mBookUtil.getPosition() - line.length()-2); | |||
|  |                 break; | |||
|  |             }*//* | |||
|  |             //   lines.add(line); | |||
|  | 
 | |||
|  |             // Log.d(TAG,"preLine is \n" + line); | |||
|  |             if (!line.isEmpty()){ | |||
|  |                 preLines.add(line); | |||
|  |             } | |||
|  | 
 | |||
|  |             lines.addAll(0,preLines); | |||
|  | 
 | |||
|  |             if (lines.size() >= mLineCount){ | |||
|  |                 break; | |||
|  |             } | |||
|  |             width = 0; | |||
|  |             line = ""; | |||
|  |             par = mBookUtil.preLine(); | |||
|  |         } | |||
|  | 
 | |||
|  |         List<String> reLines = new ArrayList<>(); | |||
|  |         int num = 0; | |||
|  |         for (int i = lines.size() -1;i >= 0;i --){ | |||
|  |             if (reLines.size() < mLineCount) { | |||
|  |                 reLines.add(0,lines.get(i)); | |||
|  |             }else{ | |||
|  |                 num = num + lines.get(i).length(); | |||
|  |             } | |||
|  |            Log.d(TAG,lines.get(i) + "   "); | |||
|  |         } | |||
|  | 
 | |||
|  |         if (num > 0){ | |||
|  |             if ( mBookUtil.getPosition() > 0) { | |||
|  |                 mBookUtil.setPostition(mBookUtil.getPosition() + num + 1);//mBookUtil.setPostition(mBookUtil.getPosition() + num + 2); // /r/n -> /n,只需要回退1个字符 | |||
|  |             }else{ | |||
|  |                 mBookUtil.setPostition(mBookUtil.getPosition() + num ); | |||
|  |             } | |||
|  |         } | |||
|  | 
 | |||
|  |         return reLines; | |||
|  |     }*/ | |||
|  | 
 | |||
|  | 
 | |||
|  |     //上一章 | |||
|  |     public void preChapter(){ | |||
|  |         fileRetryCnt.clear(); | |||
|  |         mBookUtil.fileRetryCnt.clear(); | |||
|  |         if(currentChapter==1){ | |||
|  |             Toast.makeText(mContext,"到头了",Toast.LENGTH_SHORT).show(); | |||
|  |         } | |||
|  |        // if (mBookUtil.getChapters().size() > 0 ){ | |||
|  |             int num = currentChapter; | |||
|  |             if (num ==1){ | |||
|  |                 num = getCurrentChapter(); | |||
|  |             } | |||
|  |             num --; | |||
|  |             if (num >= 1){ | |||
|  | 
 | |||
|  |                 nextChaptPages =currentChaptPages; | |||
|  |                 currentChapter = num; | |||
|  |                 mBookUtil.setChapterNo(currentChapter); | |||
|  |                 currentChaptPages =   loadCurrentChapt(currentChapter )     ; | |||
|  |                 currentPage = getPageForBegin(0); | |||
|  |                 currentPage(true); | |||
|  | 
 | |||
|  |             } | |||
|  |         } | |||
|  |     //} | |||
|  | 
 | |||
|  |     //下一章 | |||
|  |     public void nextChapter(){ | |||
|  |         fileRetryCnt.clear(); | |||
|  |         mBookUtil.fileRetryCnt.clear(); | |||
|  |         int num = currentChapter; | |||
|  |         if (num == 0){ | |||
|  |             num = getCurrentChapter(); | |||
|  |         } | |||
|  | 
 | |||
|  |         if(num==getChapters().size()){ | |||
|  |             Toast.makeText(mContext,"没有了",Toast.LENGTH_SHORT).show(); | |||
|  |         } | |||
|  |         num ++; | |||
|  | 
 | |||
|  |         if (num <= getChapters().size() || mBookUtil.chaptCached(num)){ | |||
|  | 
 | |||
|  |             preChaptPages =currentChaptPages; | |||
|  |             currentChapter = num; | |||
|  |             mBookUtil.setChapterNo(currentChapter); | |||
|  |             currentChaptPages =   loadCurrentChapt(currentChapter )     ; | |||
|  |             currentPage = getPageForBegin(0); | |||
|  |             currentPage(true); | |||
|  | 
 | |||
|  |         } | |||
|  |     } | |||
|  | 
 | |||
|  |     //获取现在的章 | |||
|  |     public int getCurrentChapter(){ | |||
|  |         /*int num = 0; | |||
|  |         for (int i = 0;getDirectoryList().size() > i;i++){ | |||
|  |             Chapter bookCatalogue = getDirectoryList().get(i); | |||
|  |             if (currentPage.getEnd() >= bookCatalogue.getBookChapterStartPos()){ | |||
|  |                 num = i; | |||
|  |             }else{ | |||
|  |                 break; | |||
|  |             } | |||
|  |         } | |||
|  |         return num; | |||
|  |         */ | |||
|  | 
 | |||
|  |         currentChapter =  mBookUtil.getChapterNo(); | |||
|  |      Log.d(TAG, String.format(" prepare book  onDraw chapter  after mBookUtil.getChapterNo(),currentChapter %s  ",currentChapter  ) ); | |||
|  |         return  currentChapter ; | |||
|  |     } | |||
|  | 
 | |||
|  |     //绘制当前页面 | |||
|  |     public void currentPage(Boolean updateChapter){ | |||
|  |       //  Log.d(TAG, "prepare book currentPage: to  open current Page : "); | |||
|  |         if(mBookPageWidget==null){ | |||
|  |             return; | |||
|  |         } | |||
|  |         Log.d(TAG, "currentPage onDraw: mBookPageWidget.getCurPage() "); | |||
|  |         onDraw(mBookPageWidget.getCurPage(),currentPage ,updateChapter,false); | |||
|  |         Log.d(TAG, "currentPage onDraw: mBookPageWidget.getNextPage() "); | |||
|  |         onDraw(mBookPageWidget.getNextPage(),currentPage ,updateChapter,true); | |||
|  |     } | |||
|  | 
 | |||
|  |     //更新电量 | |||
|  |     public void updateBattery(int mLevel){ | |||
|  |        hideSysUI(); | |||
|  |         if (currentPage != null && mBookPageWidget != null && !mBookPageWidget.isRunning()) { | |||
|  | 
 | |||
|  |             Log.d(TAG, String.format("updateBattery: level old %s, new %s",level,mLevel)); | |||
|  |             if (level != mLevel) { | |||
|  |                 level = mLevel; | |||
|  |                 currentPage(false); | |||
|  |             } | |||
|  |         } | |||
|  |     } | |||
|  | 
 | |||
|  |     public void updateTime(){ | |||
|  |          hideSysUI(); | |||
|  |         if (currentPage != null && mBookPageWidget != null && !mBookPageWidget.isRunning()) { | |||
|  |             String mDate = sdf.format(new java.util.Date()); | |||
|  |             if (date != mDate) { | |||
|  |                 date = mDate; | |||
|  |                 currentPage(false); | |||
|  |             } | |||
|  |         } | |||
|  |     } | |||
|  | 
 | |||
|  |     //改变进度 | |||
|  |     public void changeProgress(float progress){ | |||
|  |         long begin = (long) (mBookUtil.getChapterLen() * progress); | |||
|  |         currentPage = getPageForBegin(begin); | |||
|  |         currentPage(true); | |||
|  |     } | |||
|  | 
 | |||
|  |     //改变章节 | |||
|  |     public void changeChapter(int chapNum){ | |||
|  |         if (getNovel() == null) { | |||
|  |            return; | |||
|  |         } | |||
|  |         long position =0; | |||
|  |         if(currentChapter == chapNum){ | |||
|  |           if( currentPage!=null){ | |||
|  |               position =currentPage.getBegin(); | |||
|  |               Log.d(TAG, "prepare book changeChapter: to position " + position); | |||
|  |           } | |||
|  | 
 | |||
|  |         } | |||
|  |         if(position==0){ | |||
|  |             if( !getNovle().isLocalBook() | |||
|  |                     && getNovle().getDomain()!=null && getSite().getDomain()!=null | |||
|  |                     && getNovle().getDomain().equals(getSite().getDomain()) | |||
|  |                     && getNovle().getLastReadChapt() == chapNum  ){ | |||
|  |                 position =getNovel().getLastReadPos(); | |||
|  |             } | |||
|  |         } | |||
|  |         preChaptPages =currentChaptPages; | |||
|  |         currentChapter = chapNum; | |||
|  |         mBookUtil.setChapterNo(currentChapter); | |||
|  |         currentChaptPages =   loadCurrentChapt(currentChapter )     ; | |||
|  |         currentPage = getPageForBegin(position); | |||
|  |         currentPage(true); | |||
|  |         hideSysUI(); | |||
|  |         if(position>0){ | |||
|  |             showAd(); | |||
|  |         } | |||
|  | 
 | |||
|  |     } | |||
|  |     public void retryChapt(int chapNum){ | |||
|  |             fileRetryCnt.clear(); | |||
|  |             mBookUtil.fileRetryCnt.clear(); | |||
|  |             changeChapter(chapNum); | |||
|  |     } | |||
|  |     public void openBookmark(int chapNum,long position){ | |||
|  | 
 | |||
|  |         //preChaptPages =currentChaptPages; | |||
|  |         currentChapter = chapNum; | |||
|  |         mBookUtil.setChapterNo(currentChapter); | |||
|  |         currentChaptPages =   loadCurrentChapt(currentChapter )     ; | |||
|  |         currentPage = getPageForBegin(position); | |||
|  |         currentPage(true); | |||
|  | 
 | |||
|  |     } | |||
|  | 
 | |||
|  |     //改变行间距 | |||
|  |     public void changeLineHight(int lineSpace) { | |||
|  | 
 | |||
|  |         this.lineSpace = lineSpace; | |||
|  |         mPaint.setTextSize(m_fontSize); | |||
|  |         calculateLineCount(); | |||
|  |         measureMarginWidth(); | |||
|  |         chaptMap.clear(); | |||
|  |         currentChaptPages =   loadCurrentChapt(currentChapter ); | |||
|  |         currentPage = getPageForBegin(currentPage.getBegin()); | |||
|  |         currentPage(true); | |||
|  |         showAd(); | |||
|  | 
 | |||
|  |     } | |||
|  |     //改变字体大小 | |||
|  |     public void changeFontSize(int fontSize){ | |||
|  |         this.m_fontSize = fontSize; | |||
|  |         mPaint.setTextSize(m_fontSize); | |||
|  |         calculateLineCount(); | |||
|  |         measureMarginWidth(); | |||
|  |         chaptMap.clear(); | |||
|  |         currentChaptPages =   loadCurrentChapt(currentChapter ); | |||
|  |         currentPage = getPageForBegin(currentPage.getBegin()); | |||
|  |         currentPage(true); | |||
|  |         showAd(); | |||
|  |     } | |||
|  | 
 | |||
|  |     //改变字体 | |||
|  |     public void changeTypeface(Typeface typeface){ | |||
|  |         this.typeface = typeface; | |||
|  |         mPaint.setTypeface(typeface); | |||
|  |         mBatterryPaint.setTypeface(typeface); | |||
|  |         calculateLineCount(); | |||
|  |         measureMarginWidth(); | |||
|  |         chaptMap.clear(); | |||
|  |         currentPage = getPageForBegin(currentPage.getBegin()); | |||
|  |         currentPage(true); | |||
|  |     } | |||
|  | 
 | |||
|  |     //改变背景 | |||
|  |     public void changeBookBg(int type){ | |||
|  |         setBookBg(type); | |||
|  |         currentPage(false); | |||
|  |     } | |||
|  | 
 | |||
|  |     //设置页面的背景 | |||
|  |     public void setBookBg(int type){ | |||
|  |         Bitmap bitmap = Bitmap.createBitmap(mWidth,mHeight, Bitmap.Config.RGB_565); | |||
|  |         Canvas canvas = new Canvas(bitmap); | |||
|  |         int color = 0; | |||
|  |         switch (type){ | |||
|  |             case Config.BOOK_BG_DEFAULT: | |||
|  |                 canvas = null; | |||
|  |                 bitmap.recycle(); | |||
|  |                 if (getBgBitmap() != null) { | |||
|  |                     getBgBitmap().recycle(); | |||
|  |                 } | |||
|  |                 bitmap = BitmapUtil.decodeSampledBitmapFromResource( | |||
|  |                         mContext.getResources(), R.drawable.paper, mWidth, mHeight); | |||
|  |                 color = mContext.getResources().getColor(R.color.read_font_default); | |||
|  |                 setBookPageBg(mContext.getResources().getColor(R.color.read_bg_default)); | |||
|  |                 break; | |||
|  |             case Config.BOOK_BG_1: | |||
|  |                 canvas.drawColor(mContext.getResources().getColor(R.color.read_bg_1)); | |||
|  |                 color = mContext.getResources().getColor(R.color.read_font_1); | |||
|  |                 setBookPageBg(mContext.getResources().getColor(R.color.read_bg_1)); | |||
|  |                 break; | |||
|  |             case Config.BOOK_BG_2: | |||
|  |                 canvas.drawColor(mContext.getResources().getColor(R.color.read_bg_2)); | |||
|  |                 color = mContext.getResources().getColor(R.color.read_font_2); | |||
|  |                 setBookPageBg(mContext.getResources().getColor(R.color.read_bg_2)); | |||
|  |                 break; | |||
|  |             case Config.BOOK_BG_3: | |||
|  |                 canvas.drawColor(mContext.getResources().getColor(R.color.read_bg_3)); | |||
|  |                 color = mContext.getResources().getColor(R.color.read_font_3); | |||
|  |                 if (mBookPageWidget != null) { | |||
|  |                     mBookPageWidget.setBgColor(mContext.getResources().getColor(R.color.read_bg_3)); | |||
|  |                 } | |||
|  |                 break; | |||
|  |             case Config.BOOK_BG_4: | |||
|  |                 canvas.drawColor(mContext.getResources().getColor(R.color.read_bg_4)); | |||
|  |                 color = mContext.getResources().getColor(R.color.read_font_4); | |||
|  |                 setBookPageBg(mContext.getResources().getColor(R.color.read_bg_4)); | |||
|  |                 break; | |||
|  |         } | |||
|  | 
 | |||
|  |         setBgBitmap(bitmap); | |||
|  |         //设置字体颜色 | |||
|  |         setM_textColor(color); | |||
|  |     } | |||
|  | 
 | |||
|  |     public void setBookPageBg(int color){ | |||
|  |         if (mBookPageWidget != null) { | |||
|  |             mBookPageWidget.setBgColor(color); | |||
|  |         } | |||
|  |     } | |||
|  |     //设置日间或者夜间模式 | |||
|  |     public void setDayOrNight(Boolean isNgiht){ | |||
|  |         initBg(isNgiht); | |||
|  |         currentPage(false); | |||
|  |     } | |||
|  | 
 | |||
|  |     public void clear(){ | |||
|  | //        Log.d(TAG, String .format("prepare Book: clearing book info %s" ,  getNovle().getName())); | |||
|  |         fileRetryCnt.clear(); | |||
|  |         lastPageTime=0; | |||
|  |        if(chaptMap!=null){ | |||
|  |            chaptMap.clear(); | |||
|  |        } | |||
|  |         currentChapter = 0; | |||
|  |         bookPath = ""; | |||
|  |         bookName = ""; | |||
|  |         //getNovel() = null; | |||
|  |       //  mBookPageWidget = null; | |||
|  |         mPageEvent = null; | |||
|  |         cancelPage = null; | |||
|  |         prePage = null; | |||
|  |         currentPage = null; | |||
|  |         mAd=null; | |||
|  |         currentChaptPages =null; | |||
|  |         preChaptPages=null; | |||
|  |         nextChaptPages=null; | |||
|  |         mNavtiveBannerPlusCnt=0; | |||
|  |         mSmallBannerMinusCnt  =0; | |||
|  |         mSmallBannerPlusCnt=0; | |||
|  |     } | |||
|  | 
 | |||
|  |     public static Status getStatus(){ | |||
|  |         return mStatus; | |||
|  |     } | |||
|  | 
 | |||
|  | 
 | |||
|  | 
 | |||
|  | 
 | |||
|  |     //是否是第一页 | |||
|  |     public boolean isfirstPage() { | |||
|  |         return m_isfirstPage; | |||
|  |     } | |||
|  |     //询问是否可以退出阅读 | |||
|  |     public boolean canExitSilent(){ | |||
|  |         return  m_islastPage | |||
|  |                 || mStatus==Status.FAIL | |||
|  |                 ||mStatus==Status.NETWORKFAILE | |||
|  |                 || mStatus==Status.SERVERERROR; | |||
|  |     } | |||
|  |     //是否是最后一页 | |||
|  |     public boolean islastPage() { | |||
|  |         return m_islastPage; | |||
|  |     } | |||
|  |     //是否可以翻页 | |||
|  |     public boolean isReady() { | |||
|  |         return mStatus==Status.FINISH; | |||
|  | 
 | |||
|  | 
 | |||
|  | 
 | |||
|  | 
 | |||
|  |     } | |||
|  |     //设置页面背景 | |||
|  |     public void setBgBitmap(Bitmap BG) { | |||
|  |         m_book_bg = BG; | |||
|  |     } | |||
|  |     //设置页面背景 | |||
|  |     public Bitmap getBgBitmap() { | |||
|  |         return m_book_bg; | |||
|  |     } | |||
|  |     //设置文字颜色 | |||
|  |     public void setM_textColor(int m_textColor) { | |||
|  |         this.m_textColor = m_textColor; | |||
|  |     } | |||
|  |     //获取文字颜色 | |||
|  |     public int getTextColor() { | |||
|  |         return this.m_textColor; | |||
|  |     } | |||
|  |     //获取文字大小 | |||
|  |     public float getFontSize() { | |||
|  |         return this.m_fontSize; | |||
|  |     } | |||
|  | 
 | |||
|  |     public void setPageWidget(PageWidget mBookPageWidget){ | |||
|  |         this.mBookPageWidget = mBookPageWidget; | |||
|  |     } | |||
|  |     public PageWidget getPageWidget( ){ | |||
|  |         return mBookPageWidget; | |||
|  |     } | |||
|  | 
 | |||
|  |     public void setPageEvent(PageEvent pageEvent){ | |||
|  |         this.mPageEvent = pageEvent; | |||
|  |     } | |||
|  | 
 | |||
|  |     public interface PageEvent{ | |||
|  |         void changeProgress(float progress); | |||
|  |     } | |||
|  | 
 | |||
|  |     public void refreshCate(){ | |||
|  |         mBookUtil.getChapters().clear(); | |||
|  |         mBookUtil.getSiteRule(); | |||
|  |     } | |||
|  |     public long getChapterLen(){ | |||
|  |         return mBookUtil.getChapterLen(); | |||
|  |     } | |||
|  | 
 | |||
|  |     public TRPage getCurrentPage(){ | |||
|  |         return currentPage; | |||
|  |     } | |||
|  | 
 | |||
|  |     //获取书本的章 | |||
|  |     public List<Chapter> getChapters(){ | |||
|  |         return mBookUtil.getChapters(); | |||
|  |     } | |||
|  |     public boolean isReadingCatalogs(){ | |||
|  |         return  mBookUtil.isReadingCatalogs(); | |||
|  |     } | |||
|  |     public String getBookPath(){ | |||
|  |         return bookPath; | |||
|  |     } | |||
|  |     public String getBookName(){ | |||
|  |         return  getNovel().getName(); | |||
|  |     } | |||
|  |     public Novel getNovle(){ | |||
|  |         return getNovel(); | |||
|  |     } | |||
|  |     private Novel getNovel(){ | |||
|  |         if(mBookUtil!=null){ | |||
|  |             return mBookUtil.getNovel(); | |||
|  |         } | |||
|  |         return new Novel(); | |||
|  |     } | |||
|  |     public Site getSite(){ | |||
|  |         if(mBookUtil!=null){ | |||
|  |             return mBookUtil.getSite(); | |||
|  |         } | |||
|  |       else{ | |||
|  |           return  new Site(); | |||
|  |         } | |||
|  |     } | |||
|  |     public boolean isWorking(){ | |||
|  |         return mBookUtil !=null; | |||
|  |     } | |||
|  |     public String getChapterFileName(int chapid) { | |||
|  |         return mBookUtil.fileChapterName(chapid); | |||
|  |     } | |||
|  | 
 | |||
|  | } |