在线下载章节内容
This commit is contained in:
parent
9ad85f7c2e
commit
355b7adf63
|
@ -11,11 +11,13 @@ import android.view.View;
|
|||
import android.widget.Toast;
|
||||
|
||||
import com.novelbook.android.adapter.BookListAdapter;
|
||||
import com.novelbook.android.db.Chapter;
|
||||
import com.novelbook.android.db.Novel;
|
||||
import com.novelbook.android.netsubscribe.MovieSubscribe;
|
||||
import com.novelbook.android.netutils.HttpMethods;
|
||||
import com.novelbook.android.netutils.OnSuccessAndFaultListener;
|
||||
import com.novelbook.android.netutils.OnSuccessAndFaultSub;
|
||||
import com.novelbook.android.utils.BookUtil;
|
||||
import com.novelbook.android.utils.NovelParseUtil;
|
||||
|
||||
import org.json.JSONException;
|
||||
|
@ -24,6 +26,7 @@ import org.litepal.LitePal;
|
|||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import butterknife.BindView;
|
||||
|
@ -41,6 +44,7 @@ public class BookActivity extends Activity_base {
|
|||
// private BookListAdapter mAdapter;
|
||||
private List<Novel> mData;;
|
||||
|
||||
private List<Chapter> chapters = new ArrayList<>();
|
||||
@BindView(R.id.toolbar)
|
||||
Toolbar toolbar;
|
||||
@BindView(R.id.rvBooklist)
|
||||
|
@ -143,7 +147,7 @@ public class BookActivity extends Activity_base {
|
|||
}).setCancelable(true).show();
|
||||
return;
|
||||
}
|
||||
ReadActivity.openBook(book ,this);
|
||||
ReadActivity.openBook(book ,chapters,this);
|
||||
|
||||
}
|
||||
|
||||
|
@ -201,12 +205,25 @@ void onResponseProcess( String content ,String url){
|
|||
}
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
|
||||
siteJson.put("chapterUrlRegexOnMulu", "<dd> <a[^>]*href=\"(/book/[\\d]+/[\\d]+\\.html)\">([^<]+)</a></dd>");
|
||||
String[] chapters2 = NovelParseUtil.getChapters(url, content, siteJson);
|
||||
if (chapters2 != null) {
|
||||
for (int i = 0; i < chapters2.length; i += 2) {
|
||||
Log.d(TAG, String.format("%s-->%s", chapters2[i], chapters2[i + 1]));
|
||||
Chapter chapter = new Chapter();
|
||||
chapter.setChapterName(chapters2[i + 1]);
|
||||
chapter.setChapterPath(chapters2[i ]);
|
||||
chapters.add(chapter);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
siteJson.put("chapterContentRegex", "<div id=\"content\">([\\s\\S]+?)</div>");
|
||||
siteJson.put("chapterContentDumpRegex", "<script>chaptererror();</script>");
|
||||
|
||||
|
@ -217,7 +234,7 @@ void onResponseProcess( String content ,String url){
|
|||
// .header("User-Agent", "OkHttp Example")
|
||||
.build();
|
||||
Response response = HttpMethods.getOkClient().newCall(request).execute();
|
||||
// Log.d(TAG,String.format("%s-->%s\n%s" , chapters2[i], chapters2[i+1] , NovelParseUtil.getChapterContent(response.body().string(), siteJson)));
|
||||
// Log.d(TAG,String.format("%s-->%s\n%s" , chapters2[i], chapters2[i+1] , NovelParseUtil.getChapterContent(response.body().string(), siteJson)));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -35,6 +35,7 @@ import com.baidu.tts.client.SpeechError;
|
|||
import com.baidu.tts.client.SpeechSynthesizer;
|
||||
import com.baidu.tts.client.SpeechSynthesizerListener;
|
||||
import com.baidu.tts.client.TtsMode;
|
||||
import com.novelbook.android.db.Chapter;
|
||||
import com.novelbook.android.db.Novel;
|
||||
import com.novelbook.android.db.BookMarks;
|
||||
import com.novelbook.android.dialog.PageModeDialog;
|
||||
|
@ -48,6 +49,7 @@ import org.litepal.LitePal;
|
|||
import java.io.IOException;
|
||||
import java.text.DecimalFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
|
@ -58,6 +60,7 @@ import butterknife.OnClick;
|
|||
public class ReadActivity extends Activity_base implements SpeechSynthesizerListener {
|
||||
private static final String TAG = "ReadActivity";
|
||||
private final static String EXTRA_BOOK = "book";
|
||||
private final static String EXTRA_CHAPTERS = "chapters";
|
||||
private final static int MESSAGE_CHANGEPROGRESS = 1;
|
||||
|
||||
@BindView(R.id.bookpage)
|
||||
|
@ -103,6 +106,7 @@ public class ReadActivity extends Activity_base implements SpeechSynthesizerLis
|
|||
private Config config;
|
||||
private WindowManager.LayoutParams lp;
|
||||
private Novel book;
|
||||
private List<Chapter> mChapters;
|
||||
private PageFactory pageFactory;
|
||||
private int screenWidth, screenHeight;
|
||||
// popwindow是否显示
|
||||
|
@ -194,12 +198,12 @@ public class ReadActivity extends Activity_base implements SpeechSynthesizerLis
|
|||
//获取intent中的携带的信息
|
||||
Intent intent = getIntent();
|
||||
book = (Novel) intent.getSerializableExtra(EXTRA_BOOK);
|
||||
|
||||
mChapters = (ArrayList<Chapter>) intent.getSerializableExtra(EXTRA_CHAPTERS);
|
||||
bookpage.setPageMode(config.getPageMode());
|
||||
pageFactory.setPageWidget(bookpage);
|
||||
|
||||
try {
|
||||
pageFactory.openBook(book);
|
||||
pageFactory.openBook(book,mChapters);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
Toast.makeText(this, "打开电子书失败", Toast.LENGTH_SHORT).show();
|
||||
|
@ -523,13 +527,15 @@ public class ReadActivity extends Activity_base implements SpeechSynthesizerLis
|
|||
}
|
||||
|
||||
|
||||
public static boolean openBook(final Novel book, Activity context) {
|
||||
public static boolean openBook(final Novel book,List<Chapter> chapters ,Activity context) {
|
||||
if (book == null){
|
||||
throw new NullPointerException("Novel can not be null");
|
||||
}
|
||||
|
||||
Intent intent = new Intent(context, ReadActivity.class);
|
||||
intent.putExtra(EXTRA_BOOK, book);
|
||||
// intent.putExtra(EXTRA_CHAPTERS, chapters);
|
||||
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
|
||||
context.overridePendingTransition(R.anim.in_from_right, R.anim.out_to_left);
|
||||
context.startActivity(intent);
|
||||
|
|
|
@ -14,6 +14,7 @@ public class Chapter extends LitePalSupport {
|
|||
private int length;
|
||||
private String chapterPath;
|
||||
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
@ -79,7 +80,5 @@ public class Chapter extends LitePalSupport {
|
|||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -23,6 +23,10 @@ public class Novel extends LitePalSupport implements Serializable{
|
|||
private String lastestChapterName;
|
||||
private String description;
|
||||
private long lastUpateTime;
|
||||
private boolean isOnShelf; //是否入书架
|
||||
private boolean isFinished; //是否完本
|
||||
|
||||
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
|
@ -152,8 +156,19 @@ public class Novel extends LitePalSupport implements Serializable{
|
|||
this.lastUpateTime = lastUpateTime;
|
||||
}
|
||||
|
||||
public boolean isOnShelf() {
|
||||
return isOnShelf;
|
||||
}
|
||||
|
||||
public void setOnShelf(boolean onShelf) {
|
||||
isOnShelf = onShelf;
|
||||
}
|
||||
|
||||
public boolean isFinished() {
|
||||
return isFinished;
|
||||
}
|
||||
|
||||
|
||||
public void setFinished(boolean finished) {
|
||||
isFinished = finished;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,8 +10,11 @@ import android.util.Log;
|
|||
import com.novelbook.android.bean.Cache;
|
||||
import com.novelbook.android.db.Chapter;
|
||||
import com.novelbook.android.db.Novel;
|
||||
import com.novelbook.android.netutils.HttpMethods;
|
||||
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
import org.litepal.LitePal;
|
||||
|
||||
import java.io.File;
|
||||
|
@ -26,6 +29,9 @@ import java.util.HashMap;
|
|||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import okhttp3.Request;
|
||||
import okhttp3.Response;
|
||||
|
||||
|
||||
public class BookUtil {
|
||||
public static final String TAG ="BookUtil";
|
||||
|
@ -40,7 +46,16 @@ public class BookUtil {
|
|||
public static final String lineBreakChar ="\n";
|
||||
protected final ArrayList<Cache> myArray = new ArrayList<>();
|
||||
//目录
|
||||
private List<Chapter> directoryList = new ArrayList<>();
|
||||
private List<Chapter> mChapters = new ArrayList<>();
|
||||
public List<Chapter> getChapters() {
|
||||
return mChapters;
|
||||
}
|
||||
|
||||
public void setChapters(List<Chapter> chapters) {
|
||||
this.mChapters = chapters;
|
||||
}
|
||||
|
||||
|
||||
|
||||
private String m_strCharsetName;
|
||||
private String bookName;
|
||||
|
@ -52,7 +67,17 @@ public class BookUtil {
|
|||
|
||||
private long bookLen;
|
||||
private long position;
|
||||
private Novel book;
|
||||
private Novel mNovel;
|
||||
|
||||
private Chapter mChapter;
|
||||
|
||||
public Chapter getChapter() {
|
||||
return mChapter;
|
||||
}
|
||||
|
||||
public void setChapter(Chapter chapter) {
|
||||
this.mChapter = chapter;
|
||||
}
|
||||
|
||||
public void setChapterNo(int chapterNo) {
|
||||
this.chapterNo = chapterNo;
|
||||
|
@ -83,28 +108,39 @@ public class BookUtil {
|
|||
}
|
||||
}
|
||||
|
||||
public synchronized void openBook(Novel book) throws IOException {
|
||||
this.book = book;
|
||||
public synchronized void openBook(Novel novel) throws IOException {
|
||||
this.mNovel = novel;
|
||||
//如果当前缓存不是要打开的书本就缓存书本同时删除缓存
|
||||
|
||||
//TODO 构建新的缓存策略,几个选项,1:每本书一个缓存 2:控制缓存总大小,超过限制删除旧缓存 3:网络小说的缓存
|
||||
|
||||
directoryList = LitePal.where("bookId=?",book.getId()+"").find(Chapter.class);
|
||||
boolean isLocalImport = TextUtils.isEmpty( novel.getNovelId());
|
||||
boolean isOnShelf = isLocalImport || novel.isOnShelf();
|
||||
boolean isLoadChaptsFromRemote = !isLocalImport ;// && !novel.isFinished() ; //是否从目标网站下载目录
|
||||
|
||||
|
||||
for(Chapter c :directoryList){
|
||||
Log.d(TAG, String.format("bookchapter :%s,fileName :%s, chapter Size %s",c.getChapterName(),c.getChapterPath(),c.getLength()));
|
||||
}
|
||||
|
||||
chaptCache = new HashMap<Integer,Cache>();
|
||||
if(directoryList.isEmpty()) { //1. 首次打开 本地导入的书 2. 首次打开 未缓存的在线小说
|
||||
if(isLocalImport) {
|
||||
|
||||
if (bookPath == null || !bookPath.equals(book.getNovelPath())) {
|
||||
cleanCacheFile();
|
||||
this.bookPath = book.getNovelPath();
|
||||
bookName = FileUtils.getFileName(bookPath);
|
||||
cacheBook();
|
||||
mChapters = LitePal.where("novelId=?", mNovel.getId() + "").find(Chapter.class);
|
||||
|
||||
for (Chapter c : mChapters) {
|
||||
Log.d(TAG, String.format("bookchapter :%s,fileName :%s, chapter Size %s", c.getChapterName(), c.getChapterPath(), c.getLength()));
|
||||
}
|
||||
|
||||
chaptCache = new HashMap<Integer, Cache>();
|
||||
if (mChapters.isEmpty()) { //1. 首次打开 本地导入的书 2. 首次打开 未缓存的在线小说
|
||||
|
||||
if (bookPath == null || !bookPath.equals(mNovel.getNovelPath())) {
|
||||
cleanCacheFile();
|
||||
this.bookPath = mNovel.getNovelPath();
|
||||
bookName = FileUtils.getFileName(bookPath);
|
||||
cacheBook();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
private void cleanCacheFile(){
|
||||
|
@ -236,23 +272,23 @@ public class BookUtil {
|
|||
|
||||
//缓存书本
|
||||
private void cacheBook() throws IOException {
|
||||
if (TextUtils.isEmpty(book.getCharset())) {
|
||||
if (TextUtils.isEmpty(mNovel.getCharset())) {
|
||||
m_strCharsetName = FileUtils.getCharset(bookPath);
|
||||
if (m_strCharsetName == null) {
|
||||
m_strCharsetName = "utf-8";
|
||||
}
|
||||
ContentValues values = new ContentValues();
|
||||
values.put("charset",m_strCharsetName);
|
||||
LitePal.update(Novel.class,values,book.getId());
|
||||
LitePal.update(Novel.class,values,mNovel.getId());
|
||||
}else{
|
||||
m_strCharsetName = book.getCharset();
|
||||
m_strCharsetName = mNovel.getCharset();
|
||||
}
|
||||
|
||||
File file = new File(bookPath);
|
||||
InputStreamReader reader = new InputStreamReader(new FileInputStream(file),m_strCharsetName);
|
||||
int index = 0;
|
||||
bookLen = 0;
|
||||
directoryList.clear();
|
||||
mChapters.clear();
|
||||
myArray.clear();
|
||||
while (true){
|
||||
char[] buf = new char[cachedSize];
|
||||
|
@ -348,11 +384,11 @@ public class BookUtil {
|
|||
bookChapter.setLength((int)(size - start));
|
||||
bookChapter.setChapterPath(fileChapterName(chaptId) );
|
||||
bookChapter.update(bookChapter.getId());
|
||||
directoryList.add(bookChapter);
|
||||
mChapters.add(bookChapter);
|
||||
}
|
||||
|
||||
bookChapter = new Chapter();
|
||||
bookChapter.setNovelId(book.getId());
|
||||
bookChapter.setNovelId(mNovel.getId());
|
||||
bookChapter.setNovelChapterStartPos(start);
|
||||
bookChapter.setChapterName(str.replaceAll("###",""));
|
||||
bookChapter.setNovelPath(bookPath);
|
||||
|
@ -376,7 +412,7 @@ public class BookUtil {
|
|||
|
||||
if(writer==null) {
|
||||
bookChapter = new Chapter();
|
||||
bookChapter.setNovelId(book.getId());
|
||||
bookChapter.setNovelId(mNovel.getId());
|
||||
bookChapter.setNovelChapterStartPos(start);
|
||||
bookChapter.setChapterName(str.replaceAll("###",""));
|
||||
bookChapter.setNovelPath(bookPath);
|
||||
|
@ -397,7 +433,7 @@ public class BookUtil {
|
|||
|
||||
/*
|
||||
Chapter bookChapter = new Chapter();
|
||||
bookChapter.setBookId(book.getId());
|
||||
bookChapter.setBookId(mNovel.getId());
|
||||
|
||||
bookChapter.setBookChapterStartPos(start);
|
||||
bookChapter.setChapterName(title.replaceAll("###",""));
|
||||
|
@ -406,7 +442,7 @@ public class BookUtil {
|
|||
bookChapter.save();
|
||||
int id= bookChapter.getId();
|
||||
Log.d(TAG,str + " chaptId is " + id);
|
||||
directoryList.add(bookChapter);
|
||||
mChapters.add(bookChapter);
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
@ -417,7 +453,7 @@ public class BookUtil {
|
|||
bookChapter.setLength((int)(size - start));
|
||||
bookChapter.setChapterPath(fileChapterName(chaptId) );
|
||||
bookChapter.update(bookChapter.getId());
|
||||
directoryList.add(bookChapter);
|
||||
mChapters.add(bookChapter);
|
||||
}
|
||||
}catch (Exception e){
|
||||
e.printStackTrace();
|
||||
|
@ -429,7 +465,7 @@ public class BookUtil {
|
|||
}
|
||||
|
||||
public List<Chapter> getDirectoryList(){
|
||||
return directoryList;
|
||||
return mChapters;
|
||||
}
|
||||
|
||||
public long getBookLen(){
|
||||
|
@ -445,7 +481,7 @@ public class BookUtil {
|
|||
}
|
||||
|
||||
String getChapterPath(){
|
||||
return chapterPath +book.getId()+"/";
|
||||
return chapterPath +mNovel.getId()+"/";
|
||||
}
|
||||
|
||||
//获取书本缓存
|
||||
|
@ -493,11 +529,37 @@ public class BookUtil {
|
|||
try {
|
||||
File file = new File(fileChapterName(index));
|
||||
|
||||
if(!file.exists()){
|
||||
if(!file.exists()) {
|
||||
/* 章节内容没有缓存在本地
|
||||
1. 根据本地的章节网络地址信息,读取章节内容到本地,若读取失败则
|
||||
2. 查询主服务器,若有地址更新则更新本地信息,并重复1,若没有更新地址,则地址无效,返回章节内容正待手打
|
||||
*/
|
||||
|
||||
Chapter chapter = mChapters.get(index);
|
||||
String url = chapter.getChapterUrl();
|
||||
|
||||
JSONObject siteJson = new JSONObject();
|
||||
siteJson.put("chapterContentRegex", "<div id=\"content\">([\\s\\S]+?)</div>");
|
||||
siteJson.put("chapterContentDumpRegex", "<script>chaptererror();</script>");
|
||||
Request request = new Request.Builder()
|
||||
.url(url)
|
||||
// .header("User-Agent", "OkHttp Example")
|
||||
.build();
|
||||
Response response = HttpMethods.getOkClient().newCall(request).execute();
|
||||
String content = NovelParseUtil.getChapterContent(response.body().string(), siteJson);
|
||||
|
||||
char[] buf = content.toCharArray();
|
||||
try {
|
||||
file.createNewFile();
|
||||
|
||||
final OutputStreamWriter writer = new OutputStreamWriter(new FileOutputStream(fileChapterName(index)), "UTF-16LE"); // UTF-16LE 比 utf-8 文件小
|
||||
writer.write(buf);
|
||||
writer.close();
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException("Error during writing " + fileName(index));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -519,6 +581,8 @@ public class BookUtil {
|
|||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
throw new RuntimeException("Error during reading " + fileChapterName(index));
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
Cache cache = new Cache();
|
||||
cache.setSize(block.length);
|
||||
|
|
|
@ -137,6 +137,8 @@ public class PageFactory {
|
|||
//书本名字
|
||||
private String bookName = "";
|
||||
private Novel mBook;
|
||||
//书的目录列表
|
||||
private List<Chapter> mChapters;
|
||||
//书本章节
|
||||
private int currentChapter = 0;
|
||||
//当前电量
|
||||
|
@ -498,7 +500,7 @@ public class PageFactory {
|
|||
* 打开书本
|
||||
* @throws IOException
|
||||
*/
|
||||
public void openBook(Novel book ) throws IOException {
|
||||
public void openBook(Novel book , List<Chapter> chapters ) throws IOException {
|
||||
//清空数据
|
||||
currentChapter = 0;
|
||||
// m_mbBufLen = 0;
|
||||
|
@ -506,8 +508,8 @@ public class PageFactory {
|
|||
|
||||
this.mBook = book ;
|
||||
bookPath = mBook.getNovelPath();
|
||||
bookName = FileUtils.getFileName(bookPath);
|
||||
|
||||
bookName =mBook.getNovelName();// FileUtils.getFileName(bookPath);
|
||||
this.mChapters = chapters;
|
||||
mStatus = Status.OPENING;
|
||||
drawStatus(mBookPageWidget.getCurPage());
|
||||
drawStatus(mBookPageWidget.getNextPage());
|
||||
|
@ -533,6 +535,7 @@ public class PageFactory {
|
|||
PageFactory.mStatus = PageFactory.Status.FINISH;
|
||||
// m_mbBufLen = mBookUtil.getBookLen();
|
||||
mBookUtil.setChapterNo((int)chapter);
|
||||
mBookUtil.setChapters(mChapters);
|
||||
currentChaptPages = loadCurrentChapt((int)chapter);
|
||||
currentPage = getPageForBegin(begin) ;// currentChaptPages.get(0);
|
||||
// currentPage = getPageForBegin(begin);
|
||||
|
|
Loading…
Reference in New Issue