2342 lines
		
	
	
		
			87 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
			
		
		
	
	
			2342 lines
		
	
	
		
			87 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.AdSetting;
 | ||
| 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;
 | ||
|     private int mLoadingChaptNo;
 | ||
| 
 | ||
|     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+1000;
 | ||
| 
 | ||
|           // 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( slepttime <maxSleep && getChapters().size()==0 &&  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 ,getChapters().size() %s," +
 | ||
|                                 "  mBookUtil.muluRetryCount %s,thread.name %s",chid,slepttime  , getChapters().size(),mBookUtil.muluRetryCount,Thread.currentThread().getName()  ) );
 | ||
|                         slepttime=0;
 | ||
|                         while( !file.exists() && slepttime <maxSleep &&  ( !mBookUtil.fileRetryCnt.containsKey(chid) || mBookUtil.fileRetryCnt.get(chid)< 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 , mBookUtil.fileRetryCnt.get(chid) %s,thread.name %s"
 | ||
|                               ,chid,slepttime,  mBookUtil.fileRetryCnt.get(chid),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()) + "...";
 | ||
|         }
 | ||
|       //  drawChangeSourceStatus();
 | ||
|         drawStatus();
 | ||
|         mBookUtil.pagefactory=this;
 | ||
|         mBookUtil.changeSource(domain,  chapId,  chapTitle);
 | ||
| 
 | ||
|     }
 | ||
| 
 | ||
|     @Override
 | ||
|     public void drawStatus(Status status) {
 | ||
|         mStatus =status;
 | ||
|         drawStatus();
 | ||
|     }
 | ||
| 
 | ||
|     /*   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());
 | ||
|         }
 | ||
|     }
 | ||
| 
 | ||
|     public boolean isChangingSource(){
 | ||
|         return mStatus == Status.CHANGESOURCE;
 | ||
|     }
 | ||
| 
 | ||
|     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 =false;
 | ||
|         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);
 | ||
|         Log.d(TAG, "changing Source showloading: drawing status :" +status  );
 | ||
| //        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);
 | ||
|         }
 | ||
|         Log.d(TAG, "drawStatus: mStatus is " +mStatus);
 | ||
|         if (mStatus==Status.OPENING ) {
 | ||
|             mLoadingChaptNo =mLoadingChaptNo >0?mLoadingChaptNo: getNovel().getLastReadChapt();
 | ||
|             String url = mBookUtil.getChapter(mLoadingChaptNo).getChapterUrl();
 | ||
|             Log.d(TAG, "drawStatus: url is " +url);
 | ||
|             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(mLoadingChaptNo).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));
 | ||
|        // Log.d(TAG, "changing Source onDraw showloading: drawing status :"  );
 | ||
| 
 | ||
|         if(m_lines.size()==0 ){
 | ||
|             return;
 | ||
|         }
 | ||
|         /* try {
 | ||
|             throw new Exception("who's ad");
 | ||
|         }catch (Exception e){
 | ||
|             Log.e(TAG, "onDraw:changing Source ",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  ) );
 | ||
| 
 | ||
|         String  chapterName =CommonUtil.subString(mBookUtil.getChapter(mBookUtil.getChapterNo()).getChapterName(),16); // CommonUtil.subString(getChapterName(),16);
 | ||
|         Log.d(TAG, String.format(" prepare book  reading chapter %s  ",chapterName  ) );
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
|         //更新数据库进度
 | ||
|         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(!TextUtils.isEmpty(chapterName)) {
 | ||
|                             getNovel().setLastReadChaptName(chapterName);
 | ||
|                         }
 | ||
| 
 | ||
|                         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)
 | ||
|         {
 | ||
| 
 | ||
|             int nChaterWidth = (int) mBatterryPaint.measureText(chapterName) + 1;
 | ||
|             c.drawText(chapterName, mWidth - marginWidth - nChaterWidth, statusMarginBottom  + mBatterryFontSize, mBatterryPaint);
 | ||
| 
 | ||
|         }
 | ||
| 
 | ||
|         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);
 | ||
| 
 | ||
|         }
 | ||
|         if(mBookPageWidget!=null) {
 | ||
|             mBookPageWidget.postInvalidate();
 | ||
|           /*  if(mAd!=null)
 | ||
|             new Handler().postDelayed(new Runnable() {
 | ||
|                 @Override
 | ||
|                 public void run() {
 | ||
|                     mBookPageWidget.setetCurPage(mAd.getBitmapWithAd());
 | ||
|                     mBookPageWidget.setPageMode(config.getPageMode());
 | ||
|                 }
 | ||
|             }, 1000);*/
 | ||
|         }
 | ||
|     }
 | ||
| 
 | ||
|     public void showAd(){
 | ||
|        // Log.d(TAG, String.format("loadBannerAd showAd: mAdType %s ",mAdType ));
 | ||
|         if(mStatus == Status.LASTPAGE || mAd==null ||currentPage==null || !Constants.AD_SETTING.isShowAdsense()){
 | ||
|             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(mBookUtil.mMuluStatus == BookUtil.MuluStatus.failed || mStatus !=Status.OPENING){
 | ||
|                              handler.sendEmptyMessage(MSG_NEXTPAGE_FAIL) ;
 | ||
|                          }
 | ||
| 
 | ||
|                     }}.start();
 | ||
| 
 | ||
|                 return;
 | ||
|             }
 | ||
|             mLoadingChaptNo =currentChapter+1;
 | ||
|             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);
 | ||
|    //     Log.d(TAG, "nextpage:set current bitmap ..ondraw");
 | ||
|         prePage = currentPage;
 | ||
|          currentPage = getNextPage();
 | ||
|         mLoadingChaptNo=0;
 | ||
|         // 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;
 | ||
|                }
 | ||
|             }
 | ||
| 
 | ||
|         }
 | ||
|         if(mBookUtil!=null){
 | ||
|            mBookUtil. clear();
 | ||
|            mBookUtil=null;
 | ||
|         }
 | ||
|         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--;
 | ||
|             mLoadingChaptNo =currentChapter;
 | ||
|             if(currentChapter ==0) {
 | ||
|                 return   new TRPage("没有内容了");
 | ||
|             }
 | ||
|             mBookUtil.setChapterNo(currentChapter);
 | ||
|             currentChaptPages =   loadCurrentChapt(currentChapter )     ;
 | ||
|             prePageNo = currentChaptPages.size();
 | ||
|         }else{
 | ||
|             if(currentChapter-1>0) {
 | ||
|                  preReadChaptCache(currentChapter - 1);
 | ||
|             }
 | ||
|         }
 | ||
|         mLoadingChaptNo =0;
 | ||
|         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));
 | ||
|         boolean newParagraph =false;
 | ||
|         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);
 | ||
|                 newParagraph =true;
 | ||
|                 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;
 | ||
|                 }
 | ||
| 
 | ||
|                 if(newParagraph && line.length()==0) {
 | ||
|                     newParagraph = false;
 | ||
|                     if(!(word+"").equals(Constants.BAD_CHAR)){
 | ||
|                         line += Constants.BAD_CHAR + Constants.BAD_CHAR;
 | ||
|                         widthChar += 2* mPaint.measureText( Constants.BAD_CHAR + "");
 | ||
|                     }
 | ||
| 
 | ||
|                 }
 | ||
|                 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();
 | ||
|             mBookUtil.chaptDownStatus.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()));
 | ||
|      //   if(mBookUtil!=null) {
 | ||
|           //  mBookUtil.clear();
 | ||
|           //  mBookUtil=null;
 | ||
|      //   }
 | ||
|       /*  try{
 | ||
|             throw new Exception("factory cleared");
 | ||
|         }catch (Exception e){
 | ||
|             Log.e(TAG, "prepare book: clear() called", e);
 | ||
|         }*/
 | ||
|         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(true);
 | ||
|     }
 | ||
|     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);
 | ||
|     }
 | ||
| 
 | ||
| }
 |