try read book online
This commit is contained in:
		
							parent
							
								
									9fb63f10aa
								
							
						
					
					
						commit
						90af9bbce2
					
				|  | @ -2,12 +2,12 @@ | ||||||
| <litepal> | <litepal> | ||||||
|     <dbname value="book" ></dbname> |     <dbname value="book" ></dbname> | ||||||
| 
 | 
 | ||||||
|     <version value="1" ></version> |     <version value="3" ></version> | ||||||
| 
 | 
 | ||||||
|     <list> |     <list> | ||||||
|         <mapping class="com.novelbook.android.db.BookChapter"></mapping> |         <mapping class="com.novelbook.android.db.Chapter"></mapping> | ||||||
|         <mapping class="com.novelbook.android.db.Book"></mapping> |         <mapping class="com.novelbook.android.db.Novel"></mapping> | ||||||
|         <mapping class="com.novelbook.android.db.BookMarks"></mapping> |         <mapping class="com.novelbook.android.db.BookMarks"></mapping> | ||||||
|         <mapping class="com.novelbook.android.db.BookDan"></mapping> |         <mapping class="com.novelbook.android.db.SiteRule"></mapping> | ||||||
|     </list> |     </list> | ||||||
| </litepal> | </litepal> | ||||||
|  | @ -119,7 +119,7 @@ public abstract  class Activity_base extends AppCompatActivity { | ||||||
|         { |         { | ||||||
|             Novel bk = new Novel(); |             Novel bk = new Novel(); | ||||||
|             bk.setAuthor("金庸"); |             bk.setAuthor("金庸"); | ||||||
|             bk.setNovelName("射雕英雄传" +(char)i); |             bk.setName("射雕英雄传" +(char)i); | ||||||
|             bk.setNovelType("武侠"); |             bk.setNovelType("武侠"); | ||||||
|             bk.setDescription("南宋时期的武林故事南宋时期的武林故事南宋时期的武林故事南宋时期的武林故事南宋时期的武林故事南宋时期的武林故事南宋时期的武林故事南宋时期的武林故事南宋时期的武林故事南宋时期的武林故事南宋时期的武林故事"); |             bk.setDescription("南宋时期的武林故事南宋时期的武林故事南宋时期的武林故事南宋时期的武林故事南宋时期的武林故事南宋时期的武林故事南宋时期的武林故事南宋时期的武林故事南宋时期的武林故事南宋时期的武林故事南宋时期的武林故事"); | ||||||
|             mDatas.add(bk); |             mDatas.add(bk); | ||||||
|  |  | ||||||
|  | @ -109,7 +109,7 @@ public class Activity_createShudan  extends Activity_base  { | ||||||
|         { |         { | ||||||
|             Novel  bk = new Novel (); |             Novel  bk = new Novel (); | ||||||
|             bk.setAuthor("金庸" +i); |             bk.setAuthor("金庸" +i); | ||||||
|             bk.setNovelName("射雕" +(char)i); |             bk.setName("射雕" +(char)i); | ||||||
|             bk.setNovelType("cate" +i); |             bk.setNovelType("cate" +i); | ||||||
|             bk.setDescription(" 南宋时期的武林故事南宋时期的武林故事南宋时期的武林故事南宋时期的武林故事南宋时期的武林故事南宋时期的武林故事南宋时期的武林故事"); |             bk.setDescription(" 南宋时期的武林故事南宋时期的武林故事南宋时期的武林故事南宋时期的武林故事南宋时期的武林故事南宋时期的武林故事南宋时期的武林故事"); | ||||||
|             mData .add(bk); |             mData .add(bk); | ||||||
|  | @ -185,7 +185,7 @@ public class Activity_createShudan  extends Activity_base  { | ||||||
|         @Override |         @Override | ||||||
|         public void onBindViewHolder(MyViewHolder holder, int position) { |         public void onBindViewHolder(MyViewHolder holder, int position) { | ||||||
| 
 | 
 | ||||||
|             holder.tvTitle.setText(mDatas.get(position).getNovelName()); |             holder.tvTitle.setText(mDatas.get(position).getName()); | ||||||
|             holder.tvAuthor.setText(mDatas.get(position).getAuthor()); |             holder.tvAuthor.setText(mDatas.get(position).getAuthor()); | ||||||
|             holder.tvCate.setText(mDatas.get(position).getNovelType()); |             holder.tvCate.setText(mDatas.get(position).getNovelType()); | ||||||
|             holder.tvDesc.setText(mDatas.get(position).getDescription()); |             holder.tvDesc.setText(mDatas.get(position).getDescription()); | ||||||
|  |  | ||||||
|  | @ -1,26 +1,41 @@ | ||||||
| package com.novelbook.android; | package com.novelbook.android; | ||||||
| 
 | 
 | ||||||
|  | import android.Manifest; | ||||||
| import android.app.AlertDialog; | import android.app.AlertDialog; | ||||||
|  | import android.content.Context; | ||||||
| import android.content.DialogInterface; | import android.content.DialogInterface; | ||||||
|  | import android.os.Build; | ||||||
|  | import android.os.Handler; | ||||||
|  | import android.os.Message; | ||||||
| import android.support.v7.widget.LinearLayoutManager; | import android.support.v7.widget.LinearLayoutManager; | ||||||
| import android.support.v7.widget.RecyclerView; | import android.support.v7.widget.RecyclerView; | ||||||
| import android.support.v7.widget.Toolbar; | import android.support.v7.widget.Toolbar; | ||||||
|  | import android.text.TextUtils; | ||||||
| import android.util.Log; | import android.util.Log; | ||||||
| import android.view.MenuItem; | import android.view.MenuItem; | ||||||
| import android.view.View; | import android.view.View; | ||||||
|  | import android.widget.Button; | ||||||
|  | import android.widget.ImageView; | ||||||
|  | import android.widget.TextView; | ||||||
| import android.widget.Toast; | import android.widget.Toast; | ||||||
| 
 | 
 | ||||||
|  | import com.bumptech.glide.Glide; | ||||||
| import com.google.gson.Gson; | import com.google.gson.Gson; | ||||||
| import com.novelbook.android.adapter.BookListAdapter; | import com.novelbook.android.adapter.BookListAdapter; | ||||||
|  | import com.novelbook.android.bean.NovelSites; | ||||||
| import com.novelbook.android.db.Chapter; | import com.novelbook.android.db.Chapter; | ||||||
| import com.novelbook.android.db.Novel; | import com.novelbook.android.db.Novel; | ||||||
|  | import com.novelbook.android.filechooser.FileChooserActivity; | ||||||
| import com.novelbook.android.netsubscribe.BookSubscribe; | import com.novelbook.android.netsubscribe.BookSubscribe; | ||||||
| import com.novelbook.android.netsubscribe.MovieSubscribe; | import com.novelbook.android.netsubscribe.MovieSubscribe; | ||||||
| import com.novelbook.android.netutils.HttpMethods; | import com.novelbook.android.netutils.HttpMethods; | ||||||
| import com.novelbook.android.netutils.OnSuccessAndFaultListener; | import com.novelbook.android.netutils.OnSuccessAndFaultListener; | ||||||
| import com.novelbook.android.netutils.OnSuccessAndFaultSub; | import com.novelbook.android.netutils.OnSuccessAndFaultSub; | ||||||
| import com.novelbook.android.utils.BookUtil; | import com.novelbook.android.utils.BookUtil; | ||||||
|  | import com.novelbook.android.utils.GsonUtil; | ||||||
| import com.novelbook.android.utils.NovelParseUtil; | import com.novelbook.android.utils.NovelParseUtil; | ||||||
|  | import com.novelbook.android.utils.PageFactory; | ||||||
|  | import com.youth.banner.loader.ImageLoader; | ||||||
| 
 | 
 | ||||||
| import org.json.JSONException; | import org.json.JSONException; | ||||||
| import org.json.JSONObject; | import org.json.JSONObject; | ||||||
|  | @ -41,21 +56,45 @@ import okhttp3.Request; | ||||||
| import okhttp3.Response; | import okhttp3.Response; | ||||||
| import okhttp3.ResponseBody; | import okhttp3.ResponseBody; | ||||||
| 
 | 
 | ||||||
|  | import static com.novelbook.android.FileActivity.EXTERNAL_STORAGE_REQ_CODE; | ||||||
|  | 
 | ||||||
| public class BookActivity extends   Activity_base { | public class BookActivity extends   Activity_base { | ||||||
| 
 | 
 | ||||||
|  |     private PageFactory pageFactory; | ||||||
|     String novelId="f2619820112625133c14dcb170f5e092"; |     String novelId="f2619820112625133c14dcb170f5e092"; | ||||||
|     String muluUrl="https://www.qu.la/book/390/"; |     String muluUrl="https://www.qu.la/book/390/"; | ||||||
|     private Novel mNovel; |     private Novel mNovel; | ||||||
|  |     private Chapter mChapter; | ||||||
|     static String TAG = BookActivity.class.getSimpleName(); |     static String TAG = BookActivity.class.getSimpleName(); | ||||||
|     BookListAdapter mAdapter; |     BookListAdapter mAdapter; | ||||||
|     // private BookListAdapter mAdapter; |     // private BookListAdapter mAdapter; | ||||||
|     private List<Novel> mData;; |     private List<Novel> mData;; | ||||||
| 
 |     private Gson gson = new Gson(); | ||||||
|     private ArrayList<Chapter> mChapters = new ArrayList<>(); |     private  List<Chapter> mChapters = new ArrayList<>(); | ||||||
|     @BindView(R.id.toolbar) |     @BindView(R.id.toolbar) | ||||||
|     Toolbar toolbar; |     Toolbar toolbar; | ||||||
|     @BindView(R.id.rvBooklist) |     @BindView(R.id.rvBooklist) | ||||||
|     RecyclerView rvBooklist; |     RecyclerView rvBooklist; | ||||||
|  |     @BindView(R.id.btnShelf) | ||||||
|  |     Button btnShelf; | ||||||
|  |     @BindView(R.id.imageView) | ||||||
|  |     ImageView imageView; | ||||||
|  |     @BindView(R.id.title) | ||||||
|  |     TextView txtTitle; | ||||||
|  |     @BindView(R.id.desc) | ||||||
|  |     TextView txtDesc; | ||||||
|  |     @BindView(R.id.author) | ||||||
|  |     TextView txtAuth; | ||||||
|  |     @BindView(R.id.category) | ||||||
|  |     TextView txtCategory; | ||||||
|  |     @BindView(R.id.txtDesc2) | ||||||
|  |     TextView txtDesc2; | ||||||
|  |     @BindView(R.id.txtLatestCate) | ||||||
|  |     TextView txtLatestCate; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
|     @Override |     @Override | ||||||
|     public int getLayoutRes() { |     public int getLayoutRes() { | ||||||
|  | @ -92,31 +131,111 @@ public class BookActivity extends   Activity_base { | ||||||
| 
 | 
 | ||||||
|     @Override |     @Override | ||||||
|     protected void initData() { |     protected void initData() { | ||||||
|  |         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { | ||||||
|  |             checkPermission(BookActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE, EXTERNAL_STORAGE_REQ_CODE,"添加图书需要此权限,请允许"); | ||||||
|  |         } | ||||||
|  |         pageFactory = PageFactory.getInstance(); | ||||||
|  |         setBookInfo();//set title ,data from novel list | ||||||
|  |         if(mNovel==null) { | ||||||
|             getBookInfo(); |             getBookInfo(); | ||||||
|       //  getMuluInfo(); |         } | ||||||
| 
 | 
 | ||||||
|         mData =getFakeData(5); |         mData =getFakeData(5); | ||||||
|         mAdapter = getBookListAdapter(mData); |         mAdapter = getBookListAdapter(mData); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| @OnClick({R.id.btnRead,R.id.btnCacheBook}) |     private void setBookInfo() { | ||||||
|  |     } | ||||||
|  |     private MyLoader loader = new MyLoader(); | ||||||
|  |     public void setBookDetailInfo(  ){ | ||||||
|  |         setShelfButtonText(); | ||||||
|  |         this.txtAuth.setText(mNovel.getAuthor()); | ||||||
|  |         this.txtCategory.setText(mNovel.getNovelType()); | ||||||
|  |         this.txtDesc.setText(mNovel.getDescription()); | ||||||
|  |         this.txtTitle.setText(mNovel.getName()); | ||||||
|  |         this.txtDesc2.setText(mNovel.getDescription()); | ||||||
|  |         this.txtLatestCate.setText(mNovel.getLastestChapterName()); | ||||||
|  |         if(mNovel.getLastUpateTime()>0){ | ||||||
|  |            ; | ||||||
|  |             this.txtLatestCate.setText(  new Date(mNovel.getLastUpateTime()).toString()  +"\n"+txtLatestCate.getText()); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |         if(!TextUtils.isEmpty(mNovel.getCover())) { | ||||||
|  |             loader.displayImage(BookActivity.this, mNovel.getCover(), imageView); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |     } | ||||||
|  |     private class MyLoader extends ImageLoader { | ||||||
|  |         @Override | ||||||
|  |         public void displayImage(Context context, Object path, ImageView imageView) { | ||||||
|  |             Glide.with(context).load((String) path).into(imageView); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |     void setShelfButtonText(){ | ||||||
|  |         String title = mNovel.isOnShelf()?"移除书架":"加入书架"; | ||||||
|  |         btnShelf.setText(title); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @OnClick({R.id.btnRead,R.id.btnCacheBook,R.id.btnShelf}) | ||||||
|         void submitButton(View view){ |         void submitButton(View view){ | ||||||
| 
 | 
 | ||||||
|         switch (view.getId()) { |         switch (view.getId()) { | ||||||
|             case R.id.btnRead: |             case R.id.btnRead: | ||||||
|                 testBook(); |                 readBook(); | ||||||
|  |                 //testBook(); | ||||||
| 
 | 
 | ||||||
|               //  openBook(new Novel() ); |               //  openBook(new Novel() ); | ||||||
|                 break; |                 break; | ||||||
|             case R.id.btnCacheBook: |             case R.id.btnCacheBook: | ||||||
|                 cachBook(); |                 cacheBook(); | ||||||
|  |                 break; | ||||||
|  | 
 | ||||||
|  |             case R.id.btnShelf: | ||||||
|  |                 shelfBook(); | ||||||
|                 break; |                 break; | ||||||
| 
 | 
 | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|     private void cachBook() { |     private void shelfBook() { | ||||||
|  |         mNovel.setOnShelf(!mNovel.isOnShelf()); | ||||||
|  |         mNovel.save(); | ||||||
|  |         setShelfButtonText(); | ||||||
|  | 
 | ||||||
|  |     } | ||||||
|  |     Handler handler = new Handler() { | ||||||
|  |         @Override | ||||||
|  |         public void handleMessage(Message msg) { | ||||||
|  | 
 | ||||||
|  |             int wt = msg.what; | ||||||
|  | 
 | ||||||
|  |             if (msg.what == 1 ) { | ||||||
|  |                 setBookDetailInfo(); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |         } | ||||||
|  |     }; | ||||||
|  |     private void readBook() { | ||||||
|  |         if(mNovel ==null){ | ||||||
|  |             Toast.makeText(this,"网络错误",Toast.LENGTH_LONG); | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|  |         ReadActivity.openBook(mNovel  , BookActivity.this); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     private void getChapters() { | ||||||
|  | 
 | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     private void cacheBook() { | ||||||
|         MovieSubscribe.getData(1,10,new OnSuccessAndFaultSub(new OnSuccessAndFaultListener() { |         MovieSubscribe.getData(1,10,new OnSuccessAndFaultSub(new OnSuccessAndFaultListener() { | ||||||
|             @Override |             @Override | ||||||
|             public void onSuccess(String result) { |             public void onSuccess(String result) { | ||||||
|  | @ -158,32 +277,33 @@ public class BookActivity extends   Activity_base { | ||||||
|                     }).setCancelable(true).show(); |                     }).setCancelable(true).show(); | ||||||
|             return; |             return; | ||||||
|         } |         } | ||||||
|         ReadActivity.openBook(book ,mChapters,this); |      //   ReadActivity.openBook(book  ,null,this); | ||||||
| 
 | 
 | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
|     void getMuluInfo(){ |     void getMuluInfo(){ | ||||||
|         BookSubscribe.getNovelMulu(novelId,new OnSuccessAndFaultSub(new OnSuccessAndFaultListener() { |         BookSubscribe.getNovelSites(novelId,new OnSuccessAndFaultSub(new OnSuccessAndFaultListener() { | ||||||
|             @Override |             @Override | ||||||
|             public void onSuccess(String result) { |             public void onSuccess(String result) { | ||||||
|                 //成功 |                 //成功 | ||||||
|                 try { |                 try { | ||||||
|                     JSONObject jsonObject = new JSONObject(result); |  | ||||||
| 
 | 
 | ||||||
|                   muluUrl=  jsonObject.getString("muluUrl"); |                     NovelSites nvs = (NovelSites) gson.fromJson(result,NovelSites.class); | ||||||
|  |                     pageFactory.prepareBook(mNovel,nvs,BookActivity.this); | ||||||
| 
 | 
 | ||||||
|                 } catch (JSONException e) { |                 } catch ( Exception e) { | ||||||
|                     e.printStackTrace(); |                     e.printStackTrace(); | ||||||
|                 } |                 } | ||||||
| 
 | 
 | ||||||
|                 Toast.makeText(BookActivity.this,"muluUrl 请求成功:" + muluUrl,Toast.LENGTH_SHORT).show(); |                 Toast.makeText(BookActivity.this,"getMuluInfo 请求成功 "  ,Toast.LENGTH_SHORT).show(); | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             @Override |             @Override | ||||||
|             public void onFault(String errorMsg) { |             public void onFault(String errorMsg) { | ||||||
|                 //失败 |                 //失败 | ||||||
|                 Toast.makeText(BookActivity.this,"Novel 请求失败:"+errorMsg,Toast.LENGTH_SHORT).show(); |                 Toast.makeText(BookActivity.this,"getMuluInfo 请求失败"+errorMsg,Toast.LENGTH_SHORT).show(); | ||||||
|             } |             } | ||||||
|         },BookActivity.this)); |         },BookActivity.this)); | ||||||
|     } |     } | ||||||
|  | @ -197,37 +317,10 @@ public class BookActivity extends   Activity_base { | ||||||
|             @Override |             @Override | ||||||
|             public void onSuccess(String result) { |             public void onSuccess(String result) { | ||||||
|                 //成功 |                 //成功 | ||||||
|                 Gson gson = new Gson(); |  | ||||||
| 
 |  | ||||||
|               //  result ={"id":"f2619820112625133c14dcb170f5e092","novelType":"<EFBFBD><EFBFBD><EFBFBD><EFBFBD>","novelType2":"<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>½","name":"<EFBFBD><EFBFBD><EFBFBD>Ʋ<EFBFBD><EFBFBD>","author":"<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>","cover":"http:\/\/qidian.qpic.cn\/qdbimg\/349573\/1209977\/180","description":"","lastestChapterName":"<EFBFBD>ڰ<EFBFBD><EFBFBD><EFBFBD> <20><>ʼ","lastUpateTime":""} |  | ||||||
|               //  Novel nv = gson.fromJson(result,Novel.class);  //to change id to noveId |  | ||||||
| 
 |  | ||||||
|                 Novel nv = new Novel(); |  | ||||||
|                 try { |  | ||||||
|                     JSONObject jsonObject = new JSONObject(result); |  | ||||||
|                    nv.setNovelId(jsonObject.getString("id")); |  | ||||||
|                //    nv.setLastUpateTime(jsonObject.getLong("lastUpateTime")); |  | ||||||
|                    nv.setAuthor(jsonObject.getString("author")); |  | ||||||
|                    nv.setNovelName(jsonObject.getString("name")); |  | ||||||
|                    nv.setCover(jsonObject.getString("cover")); |  | ||||||
|                     nv.setNovelType(jsonObject.getString("novelType")); |  | ||||||
|                     nv.setNovelType2(jsonObject.getString("novelType2")); |  | ||||||
|                     nv.setLastestChapterName(jsonObject.getString("lastestChapterName")); |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
|                 } catch (JSONException e) { |  | ||||||
|                     e.printStackTrace(); |  | ||||||
|                 } |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
|                 //to load image |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
|                 //to load desc |  | ||||||
| 
 |  | ||||||
|                 //... |  | ||||||
| 
 | 
 | ||||||
|  |                 Novel nv ; | ||||||
|  |                 nv = gson.fromJson(result,Novel.class); | ||||||
|  |               //   nv = GsonUtil.getNovel(result); | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | @ -235,6 +328,7 @@ public class BookActivity extends   Activity_base { | ||||||
|                 if(!isLocalDbExist){ |                 if(!isLocalDbExist){ | ||||||
|                  //  nv.saveAsync(); |                  //  nv.saveAsync(); | ||||||
|                     nv.save (); |                     nv.save (); | ||||||
|  | 
 | ||||||
|                 }else{ |                 }else{ | ||||||
| 
 | 
 | ||||||
|                     List<Novel> nvs = LitePal.where("novelId=?",novelId).find(Novel.class); |                     List<Novel> nvs = LitePal.where("novelId=?",novelId).find(Novel.class); | ||||||
|  | @ -243,7 +337,7 @@ public class BookActivity extends   Activity_base { | ||||||
|                         Log.d(TAG,String.format("novel id %s before update: lastUpdateTime: %s",novel.getId(),novel.getLastUpateTime())); |                         Log.d(TAG,String.format("novel id %s before update: lastUpdateTime: %s",novel.getId(),novel.getLastUpateTime())); | ||||||
|                     } |                     } | ||||||
| 
 | 
 | ||||||
|                     nv.setLastUpateTime(new Date().getTime()); |                   //  nv.setLastUpateTime(new Date().getTime()); | ||||||
|                     nv.updateAll("novelId=?",novelId); |                     nv.updateAll("novelId=?",novelId); | ||||||
| 
 | 
 | ||||||
|                     nvs = LitePal.where("novelId=?",novelId).find(Novel.class); |                     nvs = LitePal.where("novelId=?",novelId).find(Novel.class); | ||||||
|  | @ -258,9 +352,10 @@ public class BookActivity extends   Activity_base { | ||||||
| 
 | 
 | ||||||
|                 if(nvs.size()>0) { |                 if(nvs.size()>0) { | ||||||
|                     mNovel = nvs.get(0); |                     mNovel = nvs.get(0); | ||||||
|  |                     handler.sendEmptyMessage(1); | ||||||
|                 } |                 } | ||||||
| 
 | 
 | ||||||
|               //  getMuluInfo(); |                getMuluInfo(); | ||||||
|                 Toast.makeText(BookActivity.this,"Novel 请求成功:"+result,Toast.LENGTH_SHORT).show(); |                 Toast.makeText(BookActivity.this,"Novel 请求成功:"+result,Toast.LENGTH_SHORT).show(); | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|  | @ -272,13 +367,13 @@ public class BookActivity extends   Activity_base { | ||||||
|         },BookActivity.this)); |         },BookActivity.this)); | ||||||
| 
 | 
 | ||||||
|     } |     } | ||||||
| 
 | /* | ||||||
|     void testBook(){ |     void readChapters( String url){ | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|         //to get mulu list |         //to get mulu list | ||||||
| 
 | 
 | ||||||
|         String url = muluUrl;// "https://www.qu.la/book/161/";//"https://www.qu.la/book/746/"; |         url = muluUrl;// "https://www.qu.la/book/161/";//"https://www.qu.la/book/746/"; | ||||||
|         Request request = new Request.Builder() |         Request request = new Request.Builder() | ||||||
|                 .url(url) |                 .url(url) | ||||||
|                // .header("User-Agent", "OkHttp Example") |                // .header("User-Agent", "OkHttp Example") | ||||||
|  | @ -298,7 +393,7 @@ public class BookActivity extends   Activity_base { | ||||||
|                         String bodyStr = body.string(); |                         String bodyStr = body.string(); | ||||||
|                         Log.d(TAG, "onResponse: " +bodyStr); |                         Log.d(TAG, "onResponse: " +bodyStr); | ||||||
|                         onResponseProcess(bodyStr,url); |                         onResponseProcess(bodyStr,url); | ||||||
|                         ReadActivity.openBook(mNovel ,mChapters,BookActivity.this); |                         ReadActivity.openBook(mNovel  ,mChapter,BookActivity.this); | ||||||
|                     } catch (IOException e) { |                     } catch (IOException e) { | ||||||
|                         e.printStackTrace(); |                         e.printStackTrace(); | ||||||
|                     }finally { |                     }finally { | ||||||
|  | @ -315,51 +410,19 @@ void onResponseProcess( String content ,String url){ | ||||||
|    // HttpResult result  ; |    // HttpResult result  ; | ||||||
|    // HttpResult result2 = null; |    // HttpResult result2 = null; | ||||||
|     try { |     try { | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
|         JSONObject siteJson = new JSONObject(); |         JSONObject siteJson = new JSONObject(); | ||||||
|         siteJson.put("chapterUrlRegexOnMulu", ""); |         siteJson.put("chapterUrlRegexOnMulu", ""); | ||||||
|         siteJson.put("chapterUrlPattern", "/book/[\\d]+/[\\d]+\\.html$"); |         siteJson.put("chapterUrlPattern", "/book/[\\d]+/[\\d]+\\.html$"); | ||||||
| 
 |  | ||||||
|         /* |  | ||||||
|         String[] chapters = NovelParseUtil.getChapters(url, content, siteJson); |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
|         if (chapters != null) { |  | ||||||
|             for (int i = 0; i < chapters.length; i += 2) { |  | ||||||
|                Log.d(TAG,String.format("%s-->%s", chapters[i], chapters[i+1])); |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
| */ |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
|         siteJson.put("chapterUrlRegexOnMulu", "<dd> <a[^>]*href=\"(/book/[\\d]+/[\\d]+\\.html)\">([^<]+)</a></dd>"); |         siteJson.put("chapterUrlRegexOnMulu", "<dd> <a[^>]*href=\"(/book/[\\d]+/[\\d]+\\.html)\">([^<]+)</a></dd>"); | ||||||
|         String[] chapters2 = NovelParseUtil.getChapters(url, content, siteJson); |         mChapters = NovelParseUtil.getChapters(url, content, siteJson); | ||||||
|         if (chapters2 != null) { |         if (mChapters != null) { | ||||||
|             for (int i = 0; i < chapters2.length; i += 2) { |             int lastReadChapt = mNovel.getLastReadChapt(); | ||||||
|                 Log.d(TAG, String.format("%s-->%s", chapters2[i], chapters2[i + 1])); |          //   int index =lastReadChapt*2-2; | ||||||
|                 Chapter chapter = new Chapter(); |  | ||||||
|                 chapter.setChapterName(chapters2[i + 1]); |  | ||||||
|                 chapter.setChapterUrl(chapters2[i ]); |  | ||||||
|                 mChapters.add(chapter); |  | ||||||
| 
 | 
 | ||||||
|             } |             lastReadChapt = lastReadChapt >=mChapters.size() ? mChapters.size() -1:lastReadChapt; | ||||||
|  |             lastReadChapt = lastReadChapt <=0 ? 1:lastReadChapt; | ||||||
|  |             mChapter =mChapters.get(lastReadChapt-1); | ||||||
| 
 | 
 | ||||||
|            /* |  | ||||||
|             siteJson.put("chapterContentRegex", "<div id=\"content\">([\\s\\S]+?)</div>"); |  | ||||||
|             siteJson.put("chapterContentDumpRegex", "<script>chaptererror();</script>"); |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
|             for (int i = 0; i < chapters2.length; i += 2) { |  | ||||||
|                 Request request = new Request.Builder() |  | ||||||
|                         .url(chapters2[i]) |  | ||||||
|                         // .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))); |  | ||||||
|             } |  | ||||||
|             */ |  | ||||||
|         } |         } | ||||||
|     } catch (JSONException e) { |     } catch (JSONException e) { | ||||||
|    // } catch (JSONException | IOException e) { |    // } catch (JSONException | IOException e) { | ||||||
|  | @ -368,7 +431,7 @@ void onResponseProcess( String content ,String url){ | ||||||
|      //   result.close(); |      //   result.close(); | ||||||
|      //   if (result2 != null) result2.close(); |      //   if (result2 != null) result2.close(); | ||||||
|     } |     } | ||||||
| } | }*/ | ||||||
| 
 | 
 | ||||||
|     //----------------绑定列表 |     //----------------绑定列表 | ||||||
| 
 | 
 | ||||||
|  | @ -398,126 +461,5 @@ void onResponseProcess( String content ,String url){ | ||||||
|          super.onStop(); |          super.onStop(); | ||||||
|       //   blurLayout.pauseBlur(); |       //   blurLayout.pauseBlur(); | ||||||
|     } |     } | ||||||
| /* |  | ||||||
|     class BookListAdapter extends RecyclerView.Adapter< BookListAdapter.MyViewHolder> { |  | ||||||
|         private final int EMPTY_VIEW = 1; |  | ||||||
|         private final int PROGRESS_VIEW = 2; |  | ||||||
|         private final int IMAGE_VIEW = 3; |  | ||||||
| 
 |  | ||||||
|         private Context context; |  | ||||||
|         private List<String> mDatas = new ArrayList<String>(); |  | ||||||
|         private OnItemClickListener mOnItemClickListener; |  | ||||||
|         private int listItemID; |  | ||||||
|         public BookListAdapter(Context context,List<String> mDatas,int listItemID,OnItemClickListener clickLitener) { |  | ||||||
|             this.context = context; |  | ||||||
|             this.mDatas = mDatas; |  | ||||||
|             this.mOnItemClickListener = clickLitener; |  | ||||||
|             this.listItemID = listItemID; |  | ||||||
|         } |  | ||||||
|         public BookListAdapter(Context context, OnItemClickListener clickLitener) { |  | ||||||
|             this.context = context; |  | ||||||
|             this.mOnItemClickListener = clickLitener; |  | ||||||
| 
 | 
 | ||||||
| } | } | ||||||
| 
 |  | ||||||
|         @Override |  | ||||||
|         public int getItemViewType(int position) { |  | ||||||
|             if(mDatas.size() == 0){ |  | ||||||
|                 return EMPTY_VIEW; |  | ||||||
|             } else if(mDatas.get(position) == null){ |  | ||||||
|                 return PROGRESS_VIEW; |  | ||||||
|             } else { |  | ||||||
|                 return super.getItemViewType(position); |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         @Override |  | ||||||
|         public  MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) |  | ||||||
|         { |  | ||||||
|              BookListAdapter.MyViewHolder holder = new  BookListAdapter.MyViewHolder(LayoutInflater.from( |  | ||||||
|                     context).inflate(listItemID, parent, |  | ||||||
|                     false)); |  | ||||||
|             return holder; |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
|         public void setParameters(List<String> mDatas,int listItemID ) { |  | ||||||
|             this.mDatas = mDatas; |  | ||||||
|             this.listItemID = listItemID; |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         public void setOnItemClickLitener(OnItemClickListener mOnItemClickLitener) |  | ||||||
|         { |  | ||||||
|             this.mOnItemClickListener = mOnItemClickLitener; |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         @Override |  | ||||||
|         public void onBindViewHolder( BookListAdapter.MyViewHolder holder, int position) |  | ||||||
|         { |  | ||||||
|             holder.tvTitle.setText(mDatas.get(position)); |  | ||||||
|             holder.tvAuthor.setText("金庸" +position); |  | ||||||
|             holder.tvCate.setText("cate"+position); |  | ||||||
|             holder.tvDesc.setText("this is desc " +position); |  | ||||||
|             // 如果设置了回调,则设置点击事件 |  | ||||||
|             if (mOnItemClickListener != null) |  | ||||||
|             { |  | ||||||
|                 holder.itemView.setOnClickListener(new View.OnClickListener() |  | ||||||
|                 { |  | ||||||
|                     @Override |  | ||||||
|                     public void onClick(View v) |  | ||||||
|                     { |  | ||||||
|                         int pos = holder.getLayoutPosition(); |  | ||||||
|                         mOnItemClickListener.onItemClick(holder.itemView, pos); |  | ||||||
|                     } |  | ||||||
|                 }); |  | ||||||
| 
 |  | ||||||
|                 holder.itemView.setOnLongClickListener(new View.OnLongClickListener() |  | ||||||
|                 { |  | ||||||
|                     @Override |  | ||||||
|                     public boolean onLongClick(View v) |  | ||||||
|                     { |  | ||||||
|                         int pos = holder.getLayoutPosition(); |  | ||||||
|                         mOnItemClickListener.onItemLongClick(holder.itemView, pos); |  | ||||||
|                         return false; |  | ||||||
|                     } |  | ||||||
|                 }); |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         @Override |  | ||||||
|         public int getItemCount() |  | ||||||
|         { |  | ||||||
|             return mDatas.size(); |  | ||||||
|         } |  | ||||||
|         public void addData(int position) { |  | ||||||
|             mDatas.add(position, "Insert One"); |  | ||||||
|             notifyItemInserted(position); |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         public void removeData(int position) { |  | ||||||
|             mDatas.remove(position); |  | ||||||
|             notifyItemRemoved(position); |  | ||||||
|         } |  | ||||||
|         class MyViewHolder extends RecyclerView.ViewHolder |  | ||||||
|         { |  | ||||||
|             @BindView(R.id.title) |  | ||||||
|             TextView tvTitle; |  | ||||||
|             @BindView(R.id.author) |  | ||||||
|             TextView tvAuthor; |  | ||||||
|             @BindView(R.id.category) |  | ||||||
|             TextView tvCate; |  | ||||||
|             @BindView(R.id.desc) |  | ||||||
|             TextView tvDesc; |  | ||||||
|             public MyViewHolder(View view) |  | ||||||
|             { |  | ||||||
|                 super(view); |  | ||||||
|                 ButterKnife.bind(this, view); |  | ||||||
|                 //tvTitle = (TextView) view.findViewById(R.id.title); |  | ||||||
|                 // tvAuthor = (TextView) view.findViewById(R.id.author); |  | ||||||
| 
 |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|     */ |  | ||||||
| } |  | ||||||
|  |  | ||||||
|  | @ -157,7 +157,7 @@ public class FileActivity extends Activity_base { | ||||||
|             for (File file : files) { |             for (File file : files) { | ||||||
|                 Novel bookList = new Novel(); |                 Novel bookList = new Novel(); | ||||||
|                 String bookName = Fileutil.getFileNameNoEx(file.getName()); |                 String bookName = Fileutil.getFileNameNoEx(file.getName()); | ||||||
|                 bookList.setNovelName(bookName); |                 bookList.setName(bookName); | ||||||
|                 bookList.setNovelPath(file.getAbsolutePath()); |                 bookList.setNovelPath(file.getAbsolutePath()); | ||||||
|                 bookLists.add(bookList); |                 bookLists.add(bookList); | ||||||
|             } |             } | ||||||
|  | @ -206,7 +206,7 @@ public class FileActivity extends Activity_base { | ||||||
|                     adapter.cancel(); |                     adapter.cancel(); | ||||||
|                     break; |                     break; | ||||||
|                 case REPEAT: |                 case REPEAT: | ||||||
|                     msg = "书本" + repeatBookList.getNovelName() + "重复了"; |                     msg = "书本" + repeatBookList.getName() + "重复了"; | ||||||
|                     break; |                     break; | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -119,7 +119,7 @@ public abstract class BasicFragment extends Fragment { | ||||||
|         { |         { | ||||||
|             Novel bk = new Novel(); |             Novel bk = new Novel(); | ||||||
|             bk.setAuthor("金庸"); |             bk.setAuthor("金庸"); | ||||||
|             bk.setNovelName("射雕英雄传" +(char)i); |             bk.setName("射雕英雄传" +(char)i); | ||||||
|             bk.setNovelType("武侠"); |             bk.setNovelType("武侠"); | ||||||
|             bk.setDescription("南宋时期的武林故事南宋时期的武林故事南宋时期的武林故事南宋时期的武林故事南宋时期的武林故事南宋时期的武林故事南宋时期的武林故事南宋时期的武林故事南宋时期的武林故事南宋时期的武林故事南宋时期的武林故事"); |             bk.setDescription("南宋时期的武林故事南宋时期的武林故事南宋时期的武林故事南宋时期的武林故事南宋时期的武林故事南宋时期的武林故事南宋时期的武林故事南宋时期的武林故事南宋时期的武林故事南宋时期的武林故事南宋时期的武林故事"); | ||||||
|             mDatas.add(bk); |             mDatas.add(bk); | ||||||
|  | @ -143,7 +143,7 @@ public abstract class BasicFragment extends Fragment { | ||||||
|             book.setLastReadPos(book1.getLastReadPos()); |             book.setLastReadPos(book1.getLastReadPos()); | ||||||
|             book.setLastReadChapt(book1.getLastReadChapt()); |             book.setLastReadChapt(book1.getLastReadChapt()); | ||||||
|         } |         } | ||||||
|         Toast.makeText(activity, book.getNovelName() + "加载",  Toast.LENGTH_SHORT).show(); |         Toast.makeText(activity, book.getName() + "加载",  Toast.LENGTH_SHORT).show(); | ||||||
| 
 | 
 | ||||||
|         final String path = book.getNovelPath(); |         final String path = book.getNovelPath(); | ||||||
|         if(null ==path) { |         if(null ==path) { | ||||||
|  | @ -167,7 +167,7 @@ public abstract class BasicFragment extends Fragment { | ||||||
|                     }).setCancelable(true).show(); |                     }).setCancelable(true).show(); | ||||||
|             return; |             return; | ||||||
|         } |         } | ||||||
|        // ReadActivity.openBook(book ,activity); |         ReadActivity.openBook(book ,activity); | ||||||
| 
 | 
 | ||||||
|     } |     } | ||||||
|     void showShudanDetail(int shuandanId){ |     void showShudanDetail(int shuandanId){ | ||||||
|  |  | ||||||
|  | @ -28,7 +28,7 @@ public class BookMarkFragment extends BasicFragment { | ||||||
|     @BindView(R.id.lv_bookmark) |     @BindView(R.id.lv_bookmark) | ||||||
|     ListView lv_bookmark; |     ListView lv_bookmark; | ||||||
| 
 | 
 | ||||||
|     private String bookpath; |     private int novelId; | ||||||
|     private String mArgument; |     private String mArgument; | ||||||
|     private List<BookMarks> bookMarksList; |     private List<BookMarks> bookMarksList; | ||||||
|     private MarkAdapter markAdapter; |     private MarkAdapter markAdapter; | ||||||
|  | @ -44,10 +44,10 @@ public class BookMarkFragment extends BasicFragment { | ||||||
|         pageFactory = PageFactory.getInstance(); |         pageFactory = PageFactory.getInstance(); | ||||||
|         Bundle bundle = getArguments(); |         Bundle bundle = getArguments(); | ||||||
|         if (bundle != null) { |         if (bundle != null) { | ||||||
|             bookpath = bundle.getString(ARGUMENT); |             novelId = bundle.getInt(ARGUMENT); | ||||||
|         } |         } | ||||||
|         bookMarksList = new ArrayList<>(); |         bookMarksList = new ArrayList<>(); | ||||||
|         bookMarksList = LitePal.where("bookpath = ?", bookpath).find(BookMarks.class); |         bookMarksList = LitePal.where("novelId = ?", novelId+"").find(BookMarks.class); | ||||||
| 
 | 
 | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | @ -79,7 +79,7 @@ public class BookMarkFragment extends BasicFragment { | ||||||
|                             public void onClick(DialogInterface dialog, int which) { |                             public void onClick(DialogInterface dialog, int which) { | ||||||
|                                 LitePal.delete(BookMarks.class,bookMarksList.get(position).getId()); |                                 LitePal.delete(BookMarks.class,bookMarksList.get(position).getId()); | ||||||
|                                 bookMarksList.clear(); |                                 bookMarksList.clear(); | ||||||
|                                 bookMarksList.addAll(LitePal.where("bookpath = ?", bookpath).find(BookMarks.class)); |                                 bookMarksList.addAll(LitePal.where("novelId = ?", novelId+"").find(BookMarks.class)); | ||||||
|                                 markAdapter.notifyDataSetChanged(); |                                 markAdapter.notifyDataSetChanged(); | ||||||
|                             } |                             } | ||||||
|                         }).setCancelable(true).show(); |                         }).setCancelable(true).show(); | ||||||
|  | @ -101,13 +101,13 @@ public class BookMarkFragment extends BasicFragment { | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|      * 用于从Activity传递数据到Fragment |      * 用于从Activity传递数据到Fragment | ||||||
|      * @param bookpath |      * @param | ||||||
|      * @return |      * @return | ||||||
|      */ |      */ | ||||||
|     public static BookMarkFragment newInstance(String bookpath) |     public static BookMarkFragment newInstance(int novelId) | ||||||
|     { |     { | ||||||
|         Bundle bundle = new Bundle(); |         Bundle bundle = new Bundle(); | ||||||
|         bundle.putString(ARGUMENT, bookpath); |         bundle.putInt(ARGUMENT, novelId); | ||||||
|         BookMarkFragment bookMarkFragment = new BookMarkFragment(); |         BookMarkFragment bookMarkFragment = new BookMarkFragment(); | ||||||
|         bookMarkFragment.setArguments(bundle); |         bookMarkFragment.setArguments(bundle); | ||||||
|         return bookMarkFragment; |         return bookMarkFragment; | ||||||
|  |  | ||||||
|  | @ -39,7 +39,7 @@ public class CatalogFragment extends BasicFragment { | ||||||
|     @Override |     @Override | ||||||
|     protected void initData() { |     protected void initData() { | ||||||
|         pageFactory = PageFactory.getInstance(); |         pageFactory = PageFactory.getInstance(); | ||||||
|         catalogueList.addAll(pageFactory.getDirectoryList()); |         catalogueList.addAll(pageFactory.getChapters()); | ||||||
| 
 | 
 | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -85,7 +85,7 @@ public class Fragment_Shelf extends BasicFragment { | ||||||
|         flag = new boolean[100]; |         flag = new boolean[100]; | ||||||
|        // mDatas = initData(mDatas,'X'); |        // mDatas = initData(mDatas,'X'); | ||||||
| 
 | 
 | ||||||
|         bookLists = LitePal.findAll(Novel.class); |         bookLists = LitePal.where("isOnShelf=? or novelId=? ","1","").find(Novel.class); | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | @ -201,7 +201,7 @@ public class Fragment_Shelf extends BasicFragment { | ||||||
|                 .setBackgroundColor(getResources().getColor(android.R.color.transparent)); |                 .setBackgroundColor(getResources().getColor(android.R.color.transparent)); | ||||||
| 
 | 
 | ||||||
|         TextView tv =(TextView) bottomSheetDialog.findViewById(R.id.bdTitle); |         TextView tv =(TextView) bottomSheetDialog.findViewById(R.id.bdTitle); | ||||||
|         tv.setText(bookLists.get(position).getNovelName()); |         tv.setText(bookLists.get(position).getName()); | ||||||
| 
 | 
 | ||||||
|         bottomSheetDialog.show(); |         bottomSheetDialog.show(); | ||||||
|     } |     } | ||||||
|  | @ -399,7 +399,7 @@ public class Fragment_Shelf extends BasicFragment { | ||||||
|         public void onBindViewHolder(MyViewHolder holder, int position) |         public void onBindViewHolder(MyViewHolder holder, int position) | ||||||
|         { |         { | ||||||
| 
 | 
 | ||||||
|             holder.tvTitle.setText(mDatas.get(position).getNovelName()); |             holder.tvTitle.setText(mDatas.get(position).getName()); | ||||||
|             if(holder.tvAuthor!=null) holder.tvAuthor.setText(mDatas.get(position).getAuthor()); |             if(holder.tvAuthor!=null) holder.tvAuthor.setText(mDatas.get(position).getAuthor()); | ||||||
|             if(holder.tvCate!=null)   holder.tvCate.setText(mDatas.get(position).getNovelType()); |             if(holder.tvCate!=null)   holder.tvCate.setText(mDatas.get(position).getNovelType()); | ||||||
|             if(holder.tvDesc!=null)   holder.tvDesc.setText(mDatas.get(position).getDescription()); |             if(holder.tvDesc!=null)   holder.tvDesc.setText(mDatas.get(position).getDescription()); | ||||||
|  |  | ||||||
|  | @ -72,11 +72,11 @@ public class MarkActivity extends Activity_base { | ||||||
|             } |             } | ||||||
|         }); |         }); | ||||||
|         if (getSupportActionBar() != null) { |         if (getSupportActionBar() != null) { | ||||||
|             getSupportActionBar().setTitle(FileUtils.getFileName(pageFactory.getBookPath())); |             getSupportActionBar().setTitle(pageFactory.getBookName()); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         setTabsValue(); |         setTabsValue(); | ||||||
|         pager.setAdapter(new MyPagerAdapter(getSupportFragmentManager(),pageFactory.getBookPath())); |         pager.setAdapter(new MyPagerAdapter(getSupportFragmentManager(),pageFactory.getNovle().getId())); | ||||||
|         tabs.setViewPager(pager); |         tabs.setViewPager(pager); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -60,7 +60,7 @@ import butterknife.OnClick; | ||||||
| public class ReadActivity extends  Activity_base implements SpeechSynthesizerListener { | public class ReadActivity extends  Activity_base implements SpeechSynthesizerListener { | ||||||
|     private static final String TAG = "ReadActivity"; |     private static final String TAG = "ReadActivity"; | ||||||
|     private final static String EXTRA_BOOK = "book"; |     private final static String EXTRA_BOOK = "book"; | ||||||
|     private final static String EXTRA_CHAPTERS = "chapters"; |    // private final static String EXTRA_CHAPTER = "chapter"; | ||||||
|     private final static int MESSAGE_CHANGEPROGRESS = 1; |     private final static int MESSAGE_CHANGEPROGRESS = 1; | ||||||
| 
 | 
 | ||||||
|     @BindView(R.id.bookpage) |     @BindView(R.id.bookpage) | ||||||
|  | @ -106,7 +106,7 @@ public class ReadActivity extends  Activity_base implements SpeechSynthesizerLis | ||||||
|     private Config config; |     private Config config; | ||||||
|     private WindowManager.LayoutParams lp; |     private WindowManager.LayoutParams lp; | ||||||
|     private Novel book; |     private Novel book; | ||||||
|     private List<Chapter> mChapters; |    // private  Chapter  mChapter; | ||||||
|     private PageFactory pageFactory; |     private PageFactory pageFactory; | ||||||
|     private int screenWidth, screenHeight; |     private int screenWidth, screenHeight; | ||||||
|     // popwindow是否显示 |     // popwindow是否显示 | ||||||
|  | @ -198,12 +198,12 @@ public class ReadActivity extends  Activity_base implements SpeechSynthesizerLis | ||||||
|         //获取intent中的携带的信息 |         //获取intent中的携带的信息 | ||||||
|         Intent intent = getIntent(); |         Intent intent = getIntent(); | ||||||
|         book = (Novel) intent.getSerializableExtra(EXTRA_BOOK); |         book = (Novel) intent.getSerializableExtra(EXTRA_BOOK); | ||||||
|         mChapters = (ArrayList<Chapter>) intent.getSerializableExtra(EXTRA_CHAPTERS); |     //    mChapter = ( Chapter ) intent.getSerializableExtra(EXTRA_CHAPTER); | ||||||
|         bookpage.setPageMode(config.getPageMode()); |         bookpage.setPageMode(config.getPageMode()); | ||||||
|         pageFactory.setPageWidget(bookpage); |         pageFactory.setPageWidget(bookpage); | ||||||
| 
 | 
 | ||||||
|         try { |         try { | ||||||
|             pageFactory.openBook(book,mChapters); |             pageFactory.openBook(book,this); | ||||||
|         } catch (IOException e) { |         } catch (IOException e) { | ||||||
|             e.printStackTrace(); |             e.printStackTrace(); | ||||||
|             Toast.makeText(this, "打开电子书失败", Toast.LENGTH_SHORT).show(); |             Toast.makeText(this, "打开电子书失败", Toast.LENGTH_SHORT).show(); | ||||||
|  | @ -474,7 +474,7 @@ public class ReadActivity extends  Activity_base implements SpeechSynthesizerLis | ||||||
| 
 | 
 | ||||||
|         if (id == R.id.action_add_bookmark){ |         if (id == R.id.action_add_bookmark){ | ||||||
|             if (pageFactory.getCurrentPage() != null) { |             if (pageFactory.getCurrentPage() != null) { | ||||||
|                 List<BookMarks> bookMarksList = LitePal.where("bookpath = ? and begin = ?", pageFactory.getBookPath(),pageFactory.getCurrentPage().getBegin() + "").find(BookMarks.class); |                 List<BookMarks> bookMarksList = LitePal.where("novelId = ? and begin = ?", pageFactory.getNovle().getId()+"",pageFactory.getCurrentPage().getBegin() + "").find(BookMarks.class); | ||||||
| 
 | 
 | ||||||
|                 if (!bookMarksList.isEmpty()){ |                 if (!bookMarksList.isEmpty()){ | ||||||
|                     Toast.makeText(ReadActivity.this, "该书签已存在", Toast.LENGTH_SHORT).show(); |                     Toast.makeText(ReadActivity.this, "该书签已存在", Toast.LENGTH_SHORT).show(); | ||||||
|  | @ -491,7 +491,7 @@ public class ReadActivity extends  Activity_base implements SpeechSynthesizerLis | ||||||
|                         bookMarks.setTime(time); |                         bookMarks.setTime(time); | ||||||
|                         bookMarks.setBegin(pageFactory.getCurrentPage().getBegin()); |                         bookMarks.setBegin(pageFactory.getCurrentPage().getBegin()); | ||||||
|                         bookMarks.setText(word); |                         bookMarks.setText(word); | ||||||
|                         bookMarks.setBookpath(pageFactory.getBookPath()); |                         bookMarks.setNovelId(pageFactory.getNovle().getId()); | ||||||
|                         bookMarks.save(); |                         bookMarks.save(); | ||||||
| 
 | 
 | ||||||
|                         Toast.makeText(ReadActivity.this, "书签添加成功", Toast.LENGTH_SHORT).show(); |                         Toast.makeText(ReadActivity.this, "书签添加成功", Toast.LENGTH_SHORT).show(); | ||||||
|  | @ -527,14 +527,15 @@ public class ReadActivity extends  Activity_base implements SpeechSynthesizerLis | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|     public static boolean openBook(final Novel book,final ArrayList<Chapter> chapters ,Activity context) { |     public static boolean openBook(final Novel book, Activity context) { | ||||||
|         if (book == null){ |         if (book == null){ | ||||||
|             throw new NullPointerException("Novel can not be null"); |             throw new NullPointerException("Novel can not be null"); | ||||||
|  | 
 | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         Intent intent = new Intent(context, ReadActivity.class); |         Intent intent = new Intent(context, ReadActivity.class); | ||||||
|         intent.putExtra(EXTRA_BOOK, book); |         intent.putExtra(EXTRA_BOOK, book); | ||||||
|         intent.putExtra(EXTRA_CHAPTERS, chapters); |       //  intent.putExtra(EXTRA_CHAPTER, chapter); | ||||||
| 
 | 
 | ||||||
|         intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); |         intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); | ||||||
|         context.overridePendingTransition(R.anim.in_from_right, R.anim.out_to_left); |         context.overridePendingTransition(R.anim.in_from_right, R.anim.out_to_left); | ||||||
|  |  | ||||||
|  | @ -80,7 +80,7 @@ public  class BookListAdapter extends RecyclerView.Adapter< MyViewHolder> { | ||||||
| 
 | 
 | ||||||
|     @Override |     @Override | ||||||
|     public void onBindViewHolder(MyViewHolder holder, int position) { |     public void onBindViewHolder(MyViewHolder holder, int position) { | ||||||
|         holder.tvTitle.setText(mDatas.get(position).getNovelName()); |         holder.tvTitle.setText(mDatas.get(position).getName()); | ||||||
|         if (holder.tvAuthor != null) holder.tvAuthor.setText(mDatas.get(position).getAuthor()); |         if (holder.tvAuthor != null) holder.tvAuthor.setText(mDatas.get(position).getAuthor()); | ||||||
|         if (holder.tvCate != null) holder.tvCate.setText(mDatas.get(position).getNovelType()); |         if (holder.tvCate != null) holder.tvCate.setText(mDatas.get(position).getNovelType()); | ||||||
|         if (holder.tvDesc != null) holder.tvDesc.setText(mDatas.get(position).getDescription()); |         if (holder.tvDesc != null) holder.tvDesc.setText(mDatas.get(position).getDescription()); | ||||||
|  |  | ||||||
|  | @ -15,12 +15,12 @@ import com.novelbook.android.Fragments.CatalogFragment; | ||||||
| public class MyPagerAdapter extends FragmentPagerAdapter { | public class MyPagerAdapter extends FragmentPagerAdapter { | ||||||
|     private CatalogFragment catalogueFragment; |     private CatalogFragment catalogueFragment; | ||||||
|     private BookMarkFragment bookMarkFragment; |     private BookMarkFragment bookMarkFragment; | ||||||
|     private String bookPath; |     private int novelId; | ||||||
|     private final String[] titles = { "目录", "书签" }; |     private final String[] titles = { "目录", "书签" }; | ||||||
| 
 | 
 | ||||||
|     public MyPagerAdapter(FragmentManager fm,String bookPath) { |     public MyPagerAdapter(FragmentManager fm,int novelId) { | ||||||
|         super(fm); |         super(fm); | ||||||
|         this.bookPath = bookPath; |         this.novelId = novelId; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     @Override |     @Override | ||||||
|  | @ -42,7 +42,7 @@ public class MyPagerAdapter extends FragmentPagerAdapter { | ||||||
|                     //创建bookMarkFragment实例时同时把需要intent中的值传入 |                     //创建bookMarkFragment实例时同时把需要intent中的值传入 | ||||||
| //                    catalogueFragment = CatalogFragment | //                    catalogueFragment = CatalogFragment | ||||||
|                    // bookMarkFragment = BookMarkFragment.newInstance(MarkActivity.getBookpath_intent()); |                    // bookMarkFragment = BookMarkFragment.newInstance(MarkActivity.getBookpath_intent()); | ||||||
|                     catalogueFragment = CatalogFragment.newInstance(bookPath); |                     catalogueFragment = CatalogFragment.newInstance(""); | ||||||
|                 } |                 } | ||||||
|                 return catalogueFragment; |                 return catalogueFragment; | ||||||
| 
 | 
 | ||||||
|  | @ -51,7 +51,7 @@ public class MyPagerAdapter extends FragmentPagerAdapter { | ||||||
|                     //catalogueFragment = new CatalogueFragment(); |                     //catalogueFragment = new CatalogueFragment(); | ||||||
|                   //  catalogueFragment = CatalogueFragment.newInstance(MarkActivity.getBookpath_intent()); |                   //  catalogueFragment = CatalogueFragment.newInstance(MarkActivity.getBookpath_intent()); | ||||||
| //                    bookMarkFragment = BookMarkFragment.newInstance(MarkActivity.getBookpath_intent()); | //                    bookMarkFragment = BookMarkFragment.newInstance(MarkActivity.getBookpath_intent()); | ||||||
|                     bookMarkFragment = BookMarkFragment.newInstance(bookPath); |                     bookMarkFragment = BookMarkFragment.newInstance(novelId); | ||||||
|                 } |                 } | ||||||
|                 return bookMarkFragment; |                 return bookMarkFragment; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|  | @ -96,7 +96,7 @@ public class ShelfAdapter extends BaseAdapter implements DragGridListener { | ||||||
|                 viewHolder.deleteItem_IB.setVisibility(View.INVISIBLE); |                 viewHolder.deleteItem_IB.setVisibility(View.INVISIBLE); | ||||||
|             } |             } | ||||||
|             viewHolder.name.setVisibility(View.VISIBLE); |             viewHolder.name.setVisibility(View.VISIBLE); | ||||||
|             String fileName = bilist.get(position).getNovelName(); |             String fileName = bilist.get(position).getName(); | ||||||
|             viewHolder.name.setText(fileName); |             viewHolder.name.setText(fileName); | ||||||
|         }else { |         }else { | ||||||
|             contentView.setVisibility(View.INVISIBLE); |             contentView.setVisibility(View.INVISIBLE); | ||||||
|  | @ -167,9 +167,9 @@ public class ShelfAdapter extends BaseAdapter implements DragGridListener { | ||||||
|     public void updateBookPosition (int position,int databaseId,List<Novel> bookLists) { |     public void updateBookPosition (int position,int databaseId,List<Novel> bookLists) { | ||||||
|         Novel book = new Novel(); |         Novel book = new Novel(); | ||||||
|         String bookpath = bookLists.get(position).getNovelPath(); |         String bookpath = bookLists.get(position).getNovelPath(); | ||||||
|         String bookname = bookLists.get(position).getNovelName(); |         String bookname = bookLists.get(position).getName(); | ||||||
|         book.setNovelPath(bookpath); |         book.setNovelPath(bookpath); | ||||||
|         book.setNovelName(bookname); |         book.setName(bookname); | ||||||
|         book.setLastReadPos(bookLists.get(position).getLastReadPos()); |         book.setLastReadPos(bookLists.get(position).getLastReadPos()); | ||||||
|         book.setLastReadChapt(bookLists.get(position).getLastReadChapt()); |         book.setLastReadChapt(bookLists.get(position).getLastReadChapt()); | ||||||
|         book.setCharset(bookLists.get(position).getCharset()); |         book.setCharset(bookLists.get(position).getCharset()); | ||||||
|  |  | ||||||
|  | @ -0,0 +1,22 @@ | ||||||
|  | package com.novelbook.android.bean; | ||||||
|  | 
 | ||||||
|  | public class NovelSites { | ||||||
|  |  private  String novelId; | ||||||
|  |  private  Site[] sites; | ||||||
|  | 
 | ||||||
|  |     public String getNovelId() { | ||||||
|  |         return novelId; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public void setNovelId(String novelId) { | ||||||
|  |         this.novelId = novelId; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public Site[] getSites() { | ||||||
|  |         return sites; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public void setSites(Site[] sites) { | ||||||
|  |         this.sites = sites; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | @ -0,0 +1,31 @@ | ||||||
|  | package com.novelbook.android.bean; | ||||||
|  | 
 | ||||||
|  | public class Site { | ||||||
|  |     private String domain; | ||||||
|  |     private String muluUrl; | ||||||
|  |     private Boolean selectedByDefault; | ||||||
|  | 
 | ||||||
|  |     public String getDomain() { | ||||||
|  |         return domain; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public void setDomain(String domain) { | ||||||
|  |         this.domain = domain; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public String getMuluUrl() { | ||||||
|  |         return muluUrl; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public void setMuluUrl(String muluUrl) { | ||||||
|  |         this.muluUrl = muluUrl; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public Boolean getSelectedByDefault() { | ||||||
|  |         return selectedByDefault; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public void setSelectedByDefault(Boolean selectedByDefault) { | ||||||
|  |         this.selectedByDefault = selectedByDefault; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | @ -11,7 +11,7 @@ public class BookMarks extends LitePalSupport { | ||||||
|   //  private int count; |   //  private int count; | ||||||
|     private String text; |     private String text; | ||||||
|     private String time; |     private String time; | ||||||
|     private String bookpath; |     private int novelId; | ||||||
|     public int getId() { |     public int getId() { | ||||||
|         return this.id; |         return this.id; | ||||||
|     } |     } | ||||||
|  | @ -44,12 +44,12 @@ public class BookMarks extends LitePalSupport { | ||||||
|         this.begin = begin; |         this.begin = begin; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public String getBookpath() { |     public int getNovelId() { | ||||||
|         return this.bookpath; |         return this.novelId; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public void setBookpath(String bookpath) { |     public void setNovelId(int novelId  ) { | ||||||
|         this.bookpath = bookpath; |         this.novelId = novelId; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -8,14 +8,22 @@ import java.io.Serializable; | ||||||
| 
 | 
 | ||||||
| public class  Chapter extends LitePalSupport implements Serializable { | public class  Chapter extends LitePalSupport implements Serializable { | ||||||
|     private int id; |     private int id; | ||||||
|     private int novelId; |     private int novelId;//本地小说id | ||||||
|     private String  novelPath; |     private String  novelPath; //离线导入小说文件地址 | ||||||
|     private String chapterName; |     private String chapterName; | ||||||
|     private long novelChapterStartPos; |     private long novelChapterStartPos; | ||||||
|     private String chapterUrl; |     private String chapterUrl; | ||||||
|     private int length; |     private int length; | ||||||
|     private String chapterPath; |     private String chapterPath; //缓存地址 | ||||||
|  |     private String domain; //目标 site | ||||||
| 
 | 
 | ||||||
|  |     public String getDomain() { | ||||||
|  |         return domain; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public void setDomain(String domain) { | ||||||
|  |         this.domain = domain; | ||||||
|  |     } | ||||||
| 
 | 
 | ||||||
|     public int getId() { |     public int getId() { | ||||||
|         return id; |         return id; | ||||||
|  |  | ||||||
|  | @ -1,6 +1,7 @@ | ||||||
| package com.novelbook.android.db; | package com.novelbook.android.db; | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | import org.litepal.annotation.Column; | ||||||
| import org.litepal.crud.LitePalSupport; | import org.litepal.crud.LitePalSupport; | ||||||
| 
 | 
 | ||||||
| import java.io.Serializable; | import java.io.Serializable; | ||||||
|  | @ -8,13 +9,14 @@ import java.io.Serializable; | ||||||
| 
 | 
 | ||||||
| public class Novel extends LitePalSupport implements Serializable{ | public class Novel extends LitePalSupport implements Serializable{ | ||||||
|     private int id; |     private int id; | ||||||
|  |     @Column(unique = true, nullable = true) | ||||||
|     private String novelId; |     private String novelId; | ||||||
|     private String novelName; |     private String name; | ||||||
|     private String domain; |     private String domain; | ||||||
|     private String muluUrl; |     private String muluUrl; | ||||||
|     private String novelPath; |     private String novelPath; | ||||||
|     private long lastReadPos; |     private long lastReadPos; | ||||||
|     private long lastReadChapt=1; |     private int lastReadChapt=1; | ||||||
|     private String charset; |     private String charset; | ||||||
|     private String novelType; |     private String novelType; | ||||||
|     private String novelType2; |     private String novelType2; | ||||||
|  | @ -44,12 +46,12 @@ public class Novel extends LitePalSupport implements Serializable{ | ||||||
|         this.novelId = novelId; |         this.novelId = novelId; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public String getNovelName() { |     public String getName() { | ||||||
|         return novelName; |         return name; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public void setNovelName(String novelName) { |     public void setName(String novelName) { | ||||||
|         this.novelName = novelName; |         this.name = novelName; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public String getDomain() { |     public String getDomain() { | ||||||
|  | @ -84,11 +86,11 @@ public class Novel extends LitePalSupport implements Serializable{ | ||||||
|         this.lastReadPos = lastReadPos; |         this.lastReadPos = lastReadPos; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public long getLastReadChapt() { |     public int getLastReadChapt() { | ||||||
|         return lastReadChapt; |         return lastReadChapt; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public void setLastReadChapt(long lastReadChapt) { |     public void setLastReadChapt(int lastReadChapt) { | ||||||
|         this.lastReadChapt = lastReadChapt; |         this.lastReadChapt = lastReadChapt; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -0,0 +1,98 @@ | ||||||
|  | package com.novelbook.android.db; | ||||||
|  | 
 | ||||||
|  | import org.litepal.annotation.Column; | ||||||
|  | import org.litepal.crud.LitePalSupport; | ||||||
|  | 
 | ||||||
|  | public class SiteRule extends LitePalSupport { | ||||||
|  |     private int id; | ||||||
|  |     private String name; | ||||||
|  |     @Column(unique = true, nullable = false) | ||||||
|  |     private String domain; | ||||||
|  |     private String chapterUrlRegexOnMulu; | ||||||
|  |     private String chapterContentDumpRegex; | ||||||
|  |     private String chapterContentRegex; | ||||||
|  |     private String muluUrlPattern; | ||||||
|  |     private String chapterUrlPattern; | ||||||
|  |     private long miniInterval4AccessChapter; | ||||||
|  |     private String[] headers; | ||||||
|  | 
 | ||||||
|  |     public int getId() { | ||||||
|  |         return id; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public void setId(int id) { | ||||||
|  |         this.id = id; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public String getChapterContentRegex() { | ||||||
|  |         return chapterContentRegex; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public void setChapterContentRegex(String chapterContentRegex) { | ||||||
|  |         this.chapterContentRegex = chapterContentRegex; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public String getName() { | ||||||
|  |         return name; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public void setName(String name) { | ||||||
|  |         this.name = name; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public String getDomain() { | ||||||
|  |         return domain; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public void setDomain(String domain) { | ||||||
|  |         this.domain = domain; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public String getChapterUrlRegexOnMulu() { | ||||||
|  |         return chapterUrlRegexOnMulu; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public void setChapterUrlRegexOnMulu(String chapterUrlRegexOnMulu) { | ||||||
|  |         this.chapterUrlRegexOnMulu = chapterUrlRegexOnMulu; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public String getChapterContentDumpRegex() { | ||||||
|  |         return chapterContentDumpRegex; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public void setChapterContentDumpRegex(String chapterContentDumpRegex) { | ||||||
|  |         this.chapterContentDumpRegex = chapterContentDumpRegex; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public String getMuluUrlPattern() { | ||||||
|  |         return muluUrlPattern; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public void setMuluUrlPattern(String muluUrlPattern) { | ||||||
|  |         this.muluUrlPattern = muluUrlPattern; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public String getChapterUrlPattern() { | ||||||
|  |         return chapterUrlPattern; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public void setChapterUrlPattern(String chapterUrlPattern) { | ||||||
|  |         this.chapterUrlPattern = chapterUrlPattern; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public long getMiniInterval4AccessChapter() { | ||||||
|  |         return miniInterval4AccessChapter; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public void setMiniInterval4AccessChapter(long miniInterval4AccessChapter) { | ||||||
|  |         this.miniInterval4AccessChapter = miniInterval4AccessChapter; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public String[] getHeaders() { | ||||||
|  |         return headers; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public void setHeaders(String[] headers) { | ||||||
|  |         this.headers = headers; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | @ -289,7 +289,7 @@ public class DirectoryFragment extends Fragment implements View.OnClickListener | ||||||
|     @Override |     @Override | ||||||
|     public void onResume() { |     public void onResume() { | ||||||
|         super.onResume(); |         super.onResume(); | ||||||
|         bookLists = LitePal.findAll(Novel.class); |         bookLists = LitePal.where("isOnShelf=?","1").find(  Novel.class); | ||||||
|         listAdapter.notifyDataSetChanged(); |         listAdapter.notifyDataSetChanged(); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | @ -321,8 +321,9 @@ public class DirectoryFragment extends Fragment implements View.OnClickListener | ||||||
|             for (ListItem item : checkItems) { |             for (ListItem item : checkItems) { | ||||||
|                 Novel bookList = new Novel(); |                 Novel bookList = new Novel(); | ||||||
|                 String bookName = FileUtils.getFileName(item.thumb); |                 String bookName = FileUtils.getFileName(item.thumb); | ||||||
|                 bookList.setNovelName(bookName); |                 bookList.setName(bookName); | ||||||
|                 bookList.setNovelPath(item.thumb); |                 bookList.setNovelPath(item.thumb); | ||||||
|  |                 bookList.setOnShelf(true); | ||||||
|                 bookLists.add(bookList); |                 bookLists.add(bookList); | ||||||
|             } |             } | ||||||
|             SaveBookToSqlLiteTask mSaveBookToSqlLiteTask = new SaveBookToSqlLiteTask(); |             SaveBookToSqlLiteTask mSaveBookToSqlLiteTask = new SaveBookToSqlLiteTask(); | ||||||
|  | @ -363,7 +364,7 @@ public class DirectoryFragment extends Fragment implements View.OnClickListener | ||||||
|         protected Integer doInBackground(List<Novel>... params) { |         protected Integer doInBackground(List<Novel>... params) { | ||||||
|             List<Novel> bookLists = params[0]; |             List<Novel> bookLists = params[0]; | ||||||
|             for (Novel bookList : bookLists){ |             for (Novel bookList : bookLists){ | ||||||
|                 List<Novel> books = LitePal.where("bookpath = ?", bookList.getNovelPath()).find(Novel.class); |                 List<Novel> books = LitePal.where("novelPath = ?", bookList.getNovelPath()).find(Novel.class); | ||||||
|                 if (books.size() > 0){ |                 if (books.size() > 0){ | ||||||
|                     repeatBookList = bookList; |                     repeatBookList = bookList; | ||||||
|                     return REPEAT; |                     return REPEAT; | ||||||
|  | @ -390,12 +391,12 @@ public class DirectoryFragment extends Fragment implements View.OnClickListener | ||||||
|                 case SUCCESS: |                 case SUCCESS: | ||||||
|                     msg = "导入书本成功"; |                     msg = "导入书本成功"; | ||||||
|                     checkItems.clear(); |                     checkItems.clear(); | ||||||
|                     bookLists = LitePal.findAll(Novel.class); |                     bookLists = LitePal.where("isOnShelf=?","1").find(  Novel.class);//LitePal.findAll(Novel.class); | ||||||
|                     listAdapter.notifyDataSetChanged(); |                     listAdapter.notifyDataSetChanged(); | ||||||
|                     changgeCheckBookNum(); |                     changgeCheckBookNum(); | ||||||
|                     break; |                     break; | ||||||
|                 case REPEAT: |                 case REPEAT: | ||||||
|                     msg = "书本" + repeatBookList.getNovelName() + "重复了"; |                     msg = "书本" + repeatBookList.getName() + "重复了"; | ||||||
|                     break; |                     break; | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|  | @ -636,7 +637,7 @@ public class DirectoryFragment extends Fragment implements View.OnClickListener | ||||||
|             public void onClick(DialogInterface dialog, int which) { |             public void onClick(DialogInterface dialog, int which) { | ||||||
|                 Novel bookList = new Novel(); |                 Novel bookList = new Novel(); | ||||||
|                 String bookName = FileUtils.getFileName(path); |                 String bookName = FileUtils.getFileName(path); | ||||||
|                 bookList.setNovelName(bookName); |                 bookList.setName(bookName); | ||||||
|                 bookList.setNovelPath(path); |                 bookList.setNovelPath(path); | ||||||
| 
 | 
 | ||||||
|                 boolean isSave = false; |                 boolean isSave = false; | ||||||
|  | @ -649,7 +650,7 @@ public class DirectoryFragment extends Fragment implements View.OnClickListener | ||||||
|                 if (!isSave){ |                 if (!isSave){ | ||||||
|                     bookList.save(); |                     bookList.save(); | ||||||
|                 } |                 } | ||||||
|                 ReadActivity.openBook(bookList,null,getActivity()); |                 ReadActivity.openBook(bookList, getActivity()); | ||||||
|             } |             } | ||||||
|         }).show(); |         }).show(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  | @ -34,13 +34,18 @@ public interface HttpApi { | ||||||
|     @Streaming |     @Streaming | ||||||
|     Call<ResponseBody> downloadFile(@Url String fileUrl); |     Call<ResponseBody> downloadFile(@Url String fileUrl); | ||||||
| 
 | 
 | ||||||
| 
 | //http://xiaoshuofenxiang.com/api/g/ | ||||||
|  |     @GET("g") | ||||||
|  |     Observable<ResponseBody> getMasterDomain(); | ||||||
|  |     //http://xiaoshuofenxiang.com/api/n/f2619820112625133c14dcb170f5e092.json | ||||||
|     @GET("n/{id}.json") |     @GET("n/{id}.json") | ||||||
|     Observable<ResponseBody> getNovel(@Path("id") String novelId); |     Observable<ResponseBody> getNovel(@Path("id") String novelId); | ||||||
| 
 | 
 | ||||||
|  |     //http://xiaoshuofenxiang.com/api/n/f2619820112625133c14dcb170f5e092.mulu-urls.json | ||||||
|     @GET("n/{id}.mulu-urls.json") |     @GET("n/{id}.mulu-urls.json") | ||||||
|     Observable<ResponseBody> getNovelMulu(@Path("id") String novelId); |     Observable<ResponseBody> getNovelSites(@Path("id") String novelId); | ||||||
| 
 | 
 | ||||||
|     @GET("s/{siteName}.json") |     //http://xiaoshuofenxiang.com/api/s/www.qu.la.json | ||||||
|     Observable<ResponseBody> getNovelRegex(@Path("siteName") String siteName); |     @GET("s/{siteDomain}.json") | ||||||
|  |     Observable<ResponseBody> getNovelRule(@Path("siteDomain") String siteDomain); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -22,9 +22,12 @@ public class BookSubscribe { | ||||||
|         Observable<ResponseBody> observable =  HttpMethods.getInstance().getHttpApi().getNovel(novelId); |         Observable<ResponseBody> observable =  HttpMethods.getInstance().getHttpApi().getNovel(novelId); | ||||||
|         HttpMethods.getInstance().toSubscribe(observable, subscriber); |         HttpMethods.getInstance().toSubscribe(observable, subscriber); | ||||||
|     } |     } | ||||||
|     public static void getNovelMulu(String novelId,DisposableObserver<ResponseBody> subscriber){ |     public static void getNovelSites(String novelId,DisposableObserver<ResponseBody> subscriber){ | ||||||
|         Observable<ResponseBody> observable =  HttpMethods.getInstance().getHttpApi().getNovelMulu(novelId); |         Observable<ResponseBody> observable =  HttpMethods.getInstance().getHttpApi().getNovelSites(novelId); | ||||||
|  |         HttpMethods.getInstance().toSubscribe(observable, subscriber); | ||||||
|  |     } | ||||||
|  |     public static void getSiteRule(String domain,DisposableObserver<ResponseBody> subscriber){ | ||||||
|  |         Observable<ResponseBody> observable =  HttpMethods.getInstance().getHttpApi().getNovelRule(domain); | ||||||
|         HttpMethods.getInstance().toSubscribe(observable, subscriber); |         HttpMethods.getInstance().toSubscribe(observable, subscriber); | ||||||
|     } |     } | ||||||
| 
 |  | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -39,7 +39,7 @@ import retrofit2.converter.gson.GsonConverterFactory; | ||||||
| 
 | 
 | ||||||
| public class HttpMethods { | public class HttpMethods { | ||||||
|     public String TAG = "HttpMethods"; |     public String TAG = "HttpMethods"; | ||||||
|     public static final String CACHE_NAME = "yourApkName"; |     public static final String CACHE_NAME = "ZHUIKE"; | ||||||
|     public static String BASE_URL = URLConstant.BASE_URL; |     public static String BASE_URL = URLConstant.BASE_URL; | ||||||
|     private static final int DEFAULT_CONNECT_TIMEOUT = 30; |     private static final int DEFAULT_CONNECT_TIMEOUT = 30; | ||||||
|     private static final int DEFAULT_WRITE_TIMEOUT = 30; |     private static final int DEFAULT_WRITE_TIMEOUT = 30; | ||||||
|  |  | ||||||
|  | @ -8,6 +8,8 @@ import com.novelbook.android.MyApp; | ||||||
| 
 | 
 | ||||||
| import java.util.Random; | import java.util.Random; | ||||||
| 
 | 
 | ||||||
|  | import okhttp3.Call; | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
| /** | /** | ||||||
|  * Created by 眼神 on 2018/3/27. |  * Created by 眼神 on 2018/3/27. | ||||||
|  | @ -86,7 +88,19 @@ public class NetUtil { | ||||||
|         return -1; |         return -1; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     public static void cancelRequest(String tag) { | ||||||
|  |         for (Call call : HttpMethods.getOkClient().dispatcher().queuedCalls()) { | ||||||
|  |             if (call.request().tag().equals(tag)) | ||||||
|  |                 call.cancel(); | ||||||
|  |         } | ||||||
| 
 | 
 | ||||||
|  |         //B) go through the running calls and cancel if the tag matches: | ||||||
|  |         for (Call call : HttpMethods.getOkClient().dispatcher().runningCalls()) { | ||||||
|  |             if (call.request().tag().equals(tag)) | ||||||
|  |                 call.cancel(); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |     } | ||||||
| 
 | 
 | ||||||
|     public static String getUserAgent(){ |     public static String getUserAgent(){ | ||||||
|       String[] uas = { |       String[] uas = { | ||||||
|  |  | ||||||
|  | @ -75,17 +75,17 @@ import butterknife.ButterKnife; | ||||||
|     { |     { | ||||||
|         holder.tvCateName .setText(mDatas.get(0).getNovelType()); |         holder.tvCateName .setText(mDatas.get(0).getNovelType()); | ||||||
| 
 | 
 | ||||||
|         holder.tvTitle.setText(mDatas.get(0).getNovelName()); |         holder.tvTitle.setText(mDatas.get(0).getName()); | ||||||
|         holder.tvAuthor.setText(mDatas.get(0).getAuthor()); |         holder.tvAuthor.setText(mDatas.get(0).getAuthor()); | ||||||
|         holder.tvCate.setText(mDatas.get(0).getNovelType()); |         holder.tvCate.setText(mDatas.get(0).getNovelType()); | ||||||
|         holder.tvDesc.setText(mDatas.get(0).getDescription()); |         holder.tvDesc.setText(mDatas.get(0).getDescription()); | ||||||
| 
 | 
 | ||||||
|         holder.tvTitle2.setText(mDatas.get(1).getNovelName()); |         holder.tvTitle2.setText(mDatas.get(1).getName()); | ||||||
|         holder.tvAuthor2.setText(mDatas.get(1).getAuthor()); |         holder.tvAuthor2.setText(mDatas.get(1).getAuthor()); | ||||||
|         holder.tvCate2.setText(mDatas.get(1).getNovelType()); |         holder.tvCate2.setText(mDatas.get(1).getNovelType()); | ||||||
|         holder.tvDesc2.setText(mDatas.get(1).getDescription()); |         holder.tvDesc2.setText(mDatas.get(1).getDescription()); | ||||||
| 
 | 
 | ||||||
|         holder.tvTitle3.setText(mDatas.get(2).getNovelName()); |         holder.tvTitle3.setText(mDatas.get(2).getName()); | ||||||
|         holder.tvAuthor3.setText(mDatas.get(2).getAuthor()); |         holder.tvAuthor3.setText(mDatas.get(2).getAuthor()); | ||||||
|         holder.tvCate3.setText(mDatas.get(2).getNovelType()); |         holder.tvCate3.setText(mDatas.get(2).getNovelType()); | ||||||
|         holder.tvDesc3.setText(mDatas.get(2).getDescription()); |         holder.tvDesc3.setText(mDatas.get(2).getDescription()); | ||||||
|  |  | ||||||
|  | @ -1,22 +1,36 @@ | ||||||
| package com.novelbook.android.utils; | package com.novelbook.android.utils; | ||||||
| 
 | 
 | ||||||
|  | import android.app.ProgressDialog; | ||||||
| import android.content.ContentValues; | import android.content.ContentValues; | ||||||
| import android.os.Environment; | import android.content.Context; | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | import android.os.Handler; | ||||||
|  | import android.os.Looper; | ||||||
|  | import android.os.Message; | ||||||
| import android.text.TextUtils; | import android.text.TextUtils; | ||||||
| import android.util.Log; | import android.util.Log; | ||||||
|  | import android.widget.Toast; | ||||||
| 
 | 
 | ||||||
|  | import com.google.gson.Gson; | ||||||
|  | import com.novelbook.android.MyApp; | ||||||
| import com.novelbook.android.bean.Cache; | import com.novelbook.android.bean.Cache; | ||||||
|  | import com.novelbook.android.bean.NovelSites; | ||||||
|  | import com.novelbook.android.bean.Site; | ||||||
|  | import com.novelbook.android.db.SiteRule; | ||||||
| import com.novelbook.android.db.Chapter; | import com.novelbook.android.db.Chapter; | ||||||
| import com.novelbook.android.db.Novel; | import com.novelbook.android.db.Novel; | ||||||
|  | import com.novelbook.android.netsubscribe.BookSubscribe; | ||||||
| import com.novelbook.android.netutils.HttpMethods; | import com.novelbook.android.netutils.HttpMethods; | ||||||
|  | import com.novelbook.android.netutils.OnSuccessAndFaultListener; | ||||||
|  | import com.novelbook.android.netutils.OnSuccessAndFaultSub; | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| import org.json.JSONException; | import org.json.JSONException; | ||||||
| import org.json.JSONObject; | import org.json.JSONObject; | ||||||
| import org.litepal.LitePal; | import org.litepal.LitePal; | ||||||
| 
 | 
 | ||||||
|  | import java.io.Console; | ||||||
| import java.io.File; | import java.io.File; | ||||||
| import java.io.FileInputStream; | import java.io.FileInputStream; | ||||||
| import java.io.FileOutputStream; | import java.io.FileOutputStream; | ||||||
|  | @ -25,20 +39,32 @@ import java.io.InputStreamReader; | ||||||
| import java.io.OutputStreamWriter; | import java.io.OutputStreamWriter; | ||||||
| import java.lang.ref.WeakReference; | import java.lang.ref.WeakReference; | ||||||
| import java.util.ArrayList; | import java.util.ArrayList; | ||||||
|  | import java.util.Date; | ||||||
| import java.util.HashMap; | import java.util.HashMap; | ||||||
| import java.util.List; | import java.util.List; | ||||||
| import java.util.Map; | import java.util.Map; | ||||||
| 
 | 
 | ||||||
|  | import okhttp3.Call; | ||||||
|  | import okhttp3.Callback; | ||||||
| import okhttp3.Request; | import okhttp3.Request; | ||||||
| import okhttp3.Response; | import okhttp3.Response; | ||||||
|  | import okhttp3.ResponseBody; | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| public class BookUtil { | public class BookUtil { | ||||||
|     public static final  String TAG ="BookUtil"; |     public static final  String TAG ="BookUtil"; | ||||||
|     private static final String storagePath = Environment.getExternalStorageDirectory() + "/zhuike"; |     private static final String storagePath =  FileUtils.getDiskCacheDir(MyApp.applicationContext);//Environment.getExternalStorageDirectory() + "/zhuike"; | ||||||
|     private static final String cachedPath = storagePath + "/cache/"; |     private static final String cachedPath = storagePath + "/cache/"; | ||||||
|     private static final String chapterPath = storagePath + "/chapter/"; |     private static final String chapterPath = storagePath + "/chapter/"; | ||||||
|     private static final String charachterType = "utf-8";//"UTF-16LE"; |     private static final String charachterType = "utf-8";//"UTF-16LE"; | ||||||
|  |     private Context mContext; | ||||||
|  |     private ProgressDialog progressDialog; | ||||||
|  |     private MuluStatus mMuluStatus; //目录是否下载完成 | ||||||
|  |     private Gson gson = new Gson(); | ||||||
|  |     public void setContext(Context context) { | ||||||
|  |         this.mContext = context; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     //存储的字符数 |     //存储的字符数 | ||||||
|     public static final int cachedSize = 30000; |     public static final int cachedSize = 30000; | ||||||
| //    protected final ArrayList<WeakReference<char[]>> myArray = new ArrayList<>(); | //    protected final ArrayList<WeakReference<char[]>> myArray = new ArrayList<>(); | ||||||
|  | @ -47,6 +73,9 @@ public class BookUtil { | ||||||
|     protected final ArrayList<Cache> myArray = new ArrayList<>(); |     protected final ArrayList<Cache> myArray = new ArrayList<>(); | ||||||
|     //目录 |     //目录 | ||||||
|     private List<Chapter> mChapters = new ArrayList<>(); |     private List<Chapter> mChapters = new ArrayList<>(); | ||||||
|  |     //当前章节 | ||||||
|  |    // private Chapter  mCurrentChapter; | ||||||
|  | 
 | ||||||
|     public List<Chapter> getChapters() { |     public List<Chapter> getChapters() { | ||||||
|         return mChapters; |         return mChapters; | ||||||
|     } |     } | ||||||
|  | @ -69,14 +98,70 @@ public class BookUtil { | ||||||
|     private long position; |     private long position; | ||||||
|     private Novel mNovel; |     private Novel mNovel; | ||||||
| 
 | 
 | ||||||
|     private Chapter mChapter; |     public void setNovel(Novel novel) { | ||||||
| 
 |         this.mNovel = novel; | ||||||
|     public Chapter getChapter() { |  | ||||||
|         return mChapter; |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public void setChapter(Chapter chapter) { |     //当前目录网站列表 | ||||||
|         this.mChapter = chapter; |     private NovelSites mNovelSites; | ||||||
|  |     //当前目录网站 | ||||||
|  |     private Site mSite; | ||||||
|  |     private SiteRule mSiteRule; | ||||||
|  |     public void setNovelSites(NovelSites nvs) { | ||||||
|  | 
 | ||||||
|  |         this.mNovelSites = nvs; | ||||||
|  |         if(nvs.getSites().length ==0){ | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|  |         mSite =nvs.getSites()[0]; | ||||||
|  |         if(nvs.getSites().length > 0) | ||||||
|  |         for (Site site:nvs.getSites() ) { | ||||||
|  |             if(site.getSelectedByDefault()){ | ||||||
|  |                 mSite = site; | ||||||
|  |                 break; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         File file = new File(getChapterPath() +mSite.getDomain()); | ||||||
|  |         if(!file.exists()){ | ||||||
|  |             file.mkdir(); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         getSiteRule(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     private void getSiteRule() { | ||||||
|  |         mSiteRule = null; | ||||||
|  |         BookSubscribe.getSiteRule(mSite.getDomain(),new OnSuccessAndFaultSub(new OnSuccessAndFaultListener() { | ||||||
|  |             @Override | ||||||
|  |             public void onSuccess(String result) { | ||||||
|  |                 //成功 | ||||||
|  |                 SiteRule sr = (SiteRule)gson.fromJson(result,SiteRule.class); | ||||||
|  | 
 | ||||||
|  |                 List<SiteRule> srs = LitePal.where("domain=?",sr.getDomain()).limit(1).find(SiteRule.class); | ||||||
|  |                long id = srs.size()==1 ?srs.get(0).getId() :0; | ||||||
|  |                 if(id>0 ){ | ||||||
|  |                     sr.update(id); | ||||||
|  |                  //   mSiteRule =LitePal.find(SiteRule.class,id); | ||||||
|  |                 }else | ||||||
|  |                 { | ||||||
|  |                     sr.save(); | ||||||
|  |                 } | ||||||
|  |                 mSiteRule =sr; | ||||||
|  | 
 | ||||||
|  |                readChaptersAsync(); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             @Override | ||||||
|  |             public void onFault(String errorMsg) { | ||||||
|  |                 //失败 | ||||||
|  | 
 | ||||||
|  |             } | ||||||
|  |         },mContext)); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public void setChapterNo(int chapterNo) { |     public void setChapterNo(int chapterNo) { | ||||||
|  | @ -99,6 +184,26 @@ public class BookUtil { | ||||||
|         checkAndCreateDir(chapterPath); |         checkAndCreateDir(chapterPath); | ||||||
|         checkAndCreateDir(cachedPath); |         checkAndCreateDir(cachedPath); | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     enum MuluStatus{ | ||||||
|  |         isDownloading, | ||||||
|  |         isDone, | ||||||
|  |         failed | ||||||
|  |     } | ||||||
|  |     private void showProgressDialog() { | ||||||
|  |         if (  null == progressDialog) { | ||||||
|  |             progressDialog =new ProgressDialog(mContext); | ||||||
|  |         } | ||||||
|  |         progressDialog.show(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |     private void dismissProgressDialog() { | ||||||
|  |         if ( null != progressDialog) { | ||||||
|  |             progressDialog.dismiss(); | ||||||
|  |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     private void checkAndCreateDir(String path){ |     private void checkAndCreateDir(String path){ | ||||||
|  | @ -108,7 +213,7 @@ public class BookUtil { | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public synchronized void openBook(Novel novel) throws IOException { |     public synchronized void openBook(Novel novel) throws IOException, InterruptedException { | ||||||
|         this.mNovel = novel; |         this.mNovel = novel; | ||||||
|         //如果当前缓存不是要打开的书本就缓存书本同时删除缓存 |         //如果当前缓存不是要打开的书本就缓存书本同时删除缓存 | ||||||
| 
 | 
 | ||||||
|  | @ -118,8 +223,6 @@ public class BookUtil { | ||||||
|         boolean isOnShelf = isLocalImport || novel.isOnShelf(); |         boolean isOnShelf = isLocalImport || novel.isOnShelf(); | ||||||
|         boolean isLoadChaptsFromRemote = !isLocalImport ;// && !novel.isFinished() ; //是否从目标网站下载目录 |         boolean isLoadChaptsFromRemote = !isLocalImport ;// && !novel.isFinished() ; //是否从目标网站下载目录 | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
|         if(isLocalImport) { |         if(isLocalImport) { | ||||||
| 
 | 
 | ||||||
|             mChapters = LitePal.where("novelId=?", mNovel.getId() + "").find(Chapter.class); |             mChapters = LitePal.where("novelId=?", mNovel.getId() + "").find(Chapter.class); | ||||||
|  | @ -129,7 +232,7 @@ public class BookUtil { | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             chaptCache = new HashMap<Integer, Cache>(); |             chaptCache = new HashMap<Integer, Cache>(); | ||||||
|             if (mChapters.isEmpty()) {  //1. 首次打开 本地导入的书 2. 首次打开 未缓存的在线小说 |             if (mChapters.isEmpty()) {  //1. 首次打开 本地导入的书 | ||||||
| 
 | 
 | ||||||
|                 if (bookPath == null || !bookPath.equals(mNovel.getNovelPath())) { |                 if (bookPath == null || !bookPath.equals(mNovel.getNovelPath())) { | ||||||
|                     cleanCacheFile(); |                     cleanCacheFile(); | ||||||
|  | @ -138,11 +241,136 @@ public class BookUtil { | ||||||
|                     cacheBook(); |                     cacheBook(); | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|  |         }else{ //读取目录列表 | ||||||
|  |             MuluStatus m = mMuluStatus; | ||||||
|  |             Log.d(TAG,String.format("mulu on Site %s download status %s",mSite.getDomain(),mMuluStatus)); | ||||||
|  | 
 | ||||||
|  |             while(mMuluStatus == MuluStatus.isDownloading){ | ||||||
|  |                 Thread.sleep(50); | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|  |         } | ||||||
| 
 | 
 | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |    // String getMuluUrl() { | ||||||
|  |    //  return  "https://www.qu.la/book/390/"; | ||||||
|  |   //  } | ||||||
|  |    /* void readChapters(  String url){ | ||||||
|  |         Request request = getTagRequest(url); | ||||||
|  | 
 | ||||||
|  |         ResponseBody body =null; | ||||||
|  |         try { | ||||||
|  | 
 | ||||||
|  |             long startTime= new Date().getTime(); | ||||||
|  |             Log.d(TAG,String.format("loadChaptContent----start download %s  目录 from %s",  mNovel.getName()  ,url )); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |             Response response = HttpMethods.getOkClient().newCall(request).execute(); | ||||||
|  |             Log.d(TAG,String.format("loadChaptContent----end download %s  目录, 目录数量 %s, cost %s",  mNovel.getName()  , mChapters.size(),   new Date().getTime() -startTime )); | ||||||
|  |             startTime= new Date().getTime(); | ||||||
|  |             body = response.body(); | ||||||
|  |             String bodyStr = body.string(); | ||||||
|  |             Log.d(TAG, "onResponse: " +bodyStr); | ||||||
|  | 
 | ||||||
|  |             buildCharacters(bodyStr,url); | ||||||
|  |             Log.d(TAG,String.format("loadChaptContent----end build %s  目录, 目录数量 %s, cost %s",  mNovel.getName()  , mChapters.size(),   new Date().getTime() -startTime )); | ||||||
|  | 
 | ||||||
|  |         } catch (IOException e) { | ||||||
|  |             e.printStackTrace(); | ||||||
|  |         }finally { | ||||||
|  |             if(body!=null){ | ||||||
|  |                 body.close();; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |     }*/ | ||||||
|  | 
 | ||||||
|  |     void readChaptersAsync( ) { | ||||||
|  |         String url = mSite.getMuluUrl(); | ||||||
|  |         Request request = getTagRequest(url); | ||||||
|  |         mMuluStatus = MuluStatus.isDownloading; | ||||||
|  |         long startTime= new Date().getTime(); | ||||||
|  |         Log.d(TAG,String.format("loadChaptContent----start download %s  目录 from %s",  mNovel.getName()  ,url )); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |         HttpMethods.getOkClient().newCall(request).enqueue(new Callback() { | ||||||
|  |             @Override | ||||||
|  |             public void onFailure(Call call, IOException e) { | ||||||
|  |                 Log.d(TAG, "onFailure: " + e.getMessage()); | ||||||
|  |                 if( mNovelSites.getSites().length ==1){ | ||||||
|  |                     mMuluStatus = MuluStatus.failed; | ||||||
|  |                     return; | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 //try next site | ||||||
|  |                for(Site st :  mNovelSites.getSites() ){ | ||||||
|  |                    if(!st.getDomain().equals(mSite.getDomain())){ | ||||||
|  |                        mSite =st; | ||||||
|  |                        break; | ||||||
|  |                    } | ||||||
|  |                } | ||||||
|  |               //  readChaptersAsync(); | ||||||
|  |                 getSiteRule(); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             @Override | ||||||
|  |             public void onResponse(Call call, Response response){ | ||||||
|  |                 ResponseBody body = response.body(); | ||||||
|  |                 if (body != null) { | ||||||
|  | 
 | ||||||
|  |                     try { | ||||||
|  |                         String bodyStr = body.string(); | ||||||
|  |                         Log.d(TAG, "onResponse: " +bodyStr); | ||||||
|  |                         Log.d(TAG,String.format("loadChaptContent----end download %s  目录, 目录数量 %s, cost %s",  mNovel.getName()  , mChapters.size(),   new Date().getTime() -startTime )); | ||||||
|  |                         long startTime2= new Date().getTime(); | ||||||
|  |                         buildCharacters(bodyStr,url); | ||||||
|  |                         Log.d(TAG,String.format("loadChaptContent----end download %s  目录, 目录数量 %s, cost %s",  mNovel.getName()  , mChapters.size(),   new Date().getTime() -startTime2 )); | ||||||
|  |                         mMuluStatus = MuluStatus.isDone; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |                     } catch (IOException e) { | ||||||
|  |                         e.printStackTrace(); | ||||||
|  |                     }finally { | ||||||
|  |                         body.close(); | ||||||
|  |                     } | ||||||
|  | 
 | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |             } | ||||||
|  |         }); | ||||||
|  |     } | ||||||
|  |     void buildCharacters( String content ,String url){ | ||||||
|  | 
 | ||||||
|  |         try { | ||||||
|  |             JSONObject siteJson = new JSONObject(); | ||||||
|  | 
 | ||||||
|  |             siteJson.put("chapterUrlPattern", mSiteRule.getChapterUrlPattern()); | ||||||
|  |             siteJson.put("chapterUrlRegexOnMulu", mSiteRule.getChapterUrlRegexOnMulu());//示例接口表达式有问题 | ||||||
|  |             siteJson.put("chapterUrlRegexOnMulu", "<dd> <a[^>]*href=\"(/book/[\\d]+/[\\d]+\\.html)\">([^<]+)</a></dd>"); | ||||||
|  | 
 | ||||||
|  |             mChapters = NovelParseUtil.getChapters(mSite.getDomain(),url, content, siteJson); | ||||||
|  |             Log.d(TAG,String.format("mulu on Site %s download status %s",mSite.getDomain(),mMuluStatus)); | ||||||
|  |         /*    if (mChapters != null) { | ||||||
|  |                 int lastReadChapt = mNovel.getLastReadChapt(); | ||||||
|  |                 //   int index =lastReadChapt*2-2; | ||||||
|  | 
 | ||||||
|  |                 lastReadChapt = lastReadChapt >=mChapters.size() ? mChapters.size() -1:lastReadChapt; | ||||||
|  |                 lastReadChapt = lastReadChapt <=0 ? 1:lastReadChapt; | ||||||
|  |                 mCurrentChapter =mChapters.get(lastReadChapt-1); | ||||||
|  | 
 | ||||||
|  |             }*/ | ||||||
|  |         } catch (JSONException e) { | ||||||
|  |             // } catch (JSONException | IOException e) { | ||||||
|  |             Log.d(TAG,String.format("mulu on Site %s download status %s",mSite.getDomain(),mMuluStatus)); | ||||||
|  |             e.printStackTrace(); | ||||||
|  |         } finally { | ||||||
|  |             //   result.close(); | ||||||
|  |             //   if (result2 != null) result2.close(); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|     private void cleanCacheFile(){ |     private void cleanCacheFile(){ | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | @ -464,7 +692,7 @@ public class BookUtil { | ||||||
| 
 | 
 | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public List<Chapter> getDirectoryList(){ |     public List<Chapter> getmChapters(){ | ||||||
|         return mChapters; |         return mChapters; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | @ -473,14 +701,21 @@ public class BookUtil { | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     protected String fileName(int index) { |     protected String fileName(int index) { | ||||||
|         return cachedPath + bookName + index ; |         return cachedPath + mNovel.getName() + index ; | ||||||
|     } |     } | ||||||
|     protected String fileChapterName(int chaptId ) { |     protected String fileChapterName(int chaptId ) { | ||||||
|  |         if(mSite!=null){ | ||||||
| 
 | 
 | ||||||
|  |             return  getChapterPath() +mSite.getDomain()+"/"+ chaptId ; | ||||||
|  |         } | ||||||
|         return   getChapterPath() + chaptId ; |         return   getChapterPath() + chaptId ; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     String getChapterPath(){ |     String getChapterPath(){ | ||||||
|  |          File file = new File(chapterPath +mNovel.getId()); | ||||||
|  |          if(!file.exists()){ | ||||||
|  |              file.mkdir(); | ||||||
|  |          } | ||||||
|         return  chapterPath +mNovel.getId()+"/"; |         return  chapterPath +mNovel.getId()+"/"; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | @ -517,6 +752,28 @@ public class BookUtil { | ||||||
|         return block; |         return block; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     boolean isDownloadChapt =false; | ||||||
|  | 
 | ||||||
|  |     void setDownloadFlag(boolean flag){ | ||||||
|  |         isDownloadChapt = flag; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     Handler handler = new Handler() { | ||||||
|  |         @Override | ||||||
|  |         public void handleMessage(Message msg) { | ||||||
|  | 
 | ||||||
|  |             int wt = msg.what; | ||||||
|  | 
 | ||||||
|  |             if (msg.what == 123) { | ||||||
|  |                 isDownloadChapt =true; | ||||||
|  |             }else if(msg.what==1){ | ||||||
|  | 
 | ||||||
|  |                 Toast.makeText(mContext,"网络错误",Toast.LENGTH_LONG).show(); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |         } | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|     private Map<Integer,Cache> chaptCache = new HashMap<Integer,Cache>(); |     private Map<Integer,Cache> chaptCache = new HashMap<Integer,Cache>(); | ||||||
| 
 | 
 | ||||||
|     //获取chapter 缓存 |     //获取chapter 缓存 | ||||||
|  | @ -526,39 +783,37 @@ public class BookUtil { | ||||||
|             block = chaptCache .get(index).getData().get(); |             block = chaptCache .get(index).getData().get(); | ||||||
|         } |         } | ||||||
|         if (block == null) { |         if (block == null) { | ||||||
|  |      //       cleanCacheFile(); //to remove | ||||||
|             try { |             try { | ||||||
|                 File file = new File(fileChapterName(index)); |                 File file = new File(fileChapterName(index)); | ||||||
| 
 | 
 | ||||||
|                 if(!file.exists()) { |                 if(!file.exists()) { | ||||||
|                     /* 章节内容没有缓存在本地 |  | ||||||
|                         1. 根据本地的章节网络地址信息,读取章节内容到本地,若读取失败则 |  | ||||||
|                         2. 查询主服务器,若有地址更新则更新本地信息,并重复1,若没有更新地址,则地址无效,返回章节内容正待手打 |  | ||||||
|                     */ |  | ||||||
| 
 | 
 | ||||||
|                     Chapter chapter = mChapters.get(index); |                     Log.d(TAG,String.format("loadChaptContent----start %s"  ,new Date().toString() )); | ||||||
|                     String url = chapter.getChapterUrl(); |  | ||||||
| 
 | 
 | ||||||
|                     JSONObject siteJson = new JSONObject(); |                     loadChaptContent(index); | ||||||
|                     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(); |                      showProgressDialog();//why not show | ||||||
|                     try { |                     int slepttime =0; | ||||||
|                         file.createNewFile(); |                     while(!isDownloadChapt){ | ||||||
| 
 |                         Thread.sleep(50); | ||||||
|                         final OutputStreamWriter writer = new OutputStreamWriter(new FileOutputStream(fileChapterName(index)), "UTF-16LE"); // UTF-16LE 比 utf-8 文件小 |                         slepttime+=50; | ||||||
|                         writer.write(buf); |                     } | ||||||
|                         writer.close(); |                     dismissProgressDialog(); | ||||||
|                     } catch (IOException e) { |                     Log.d(TAG,String.format("loadChaptContent slept %s for downloading %s ",slepttime,  mChapters.get(index -1).getChapterName()   )); | ||||||
|                         throw new RuntimeException("Error during writing " + fileName(index)); |  | ||||||
|                 } |                 } | ||||||
| 
 | 
 | ||||||
|  |                 if(!file.exists()) { | ||||||
|  |                      String error = "网络错误"; | ||||||
|  |                      return  error.toCharArray(); | ||||||
|  |                 } | ||||||
|  |                 if(mChapters.size() > index ) { | ||||||
|  | 
 | ||||||
|  |                     File file2 = new File(fileChapterName(index+1)); | ||||||
|  | 
 | ||||||
|  |                     if(!file2.exists()) { | ||||||
|  |                         loadChaptContent(index + 1); | ||||||
|  |                     } | ||||||
| 
 | 
 | ||||||
|                 } |                 } | ||||||
| 
 | 
 | ||||||
|  | @ -583,6 +838,8 @@ public class BookUtil { | ||||||
|                 throw new RuntimeException("Error during reading " + fileChapterName(index)); |                 throw new RuntimeException("Error during reading " + fileChapterName(index)); | ||||||
|             } catch (JSONException e) { |             } catch (JSONException e) { | ||||||
|                 e.printStackTrace(); |                 e.printStackTrace(); | ||||||
|  |             } catch (InterruptedException e) { | ||||||
|  |                 e.printStackTrace(); | ||||||
|             } |             } | ||||||
|             Cache cache = new Cache(); |             Cache cache = new Cache(); | ||||||
|             cache.setSize(block.length); |             cache.setSize(block.length); | ||||||
|  | @ -592,7 +849,96 @@ public class BookUtil { | ||||||
|         } |         } | ||||||
|         return block; |         return block; | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|  | private void loadChaptContent(int index) throws JSONException, InterruptedException { | ||||||
|  |          /* 章节内容没有缓存在本地 | ||||||
|  |                         1. 根据本地的章节网络地址信息,读取章节内容到本地,若读取失败则 | ||||||
|  |                         2. 查询主服务器,若有地址更新则更新本地信息,并重复1,若没有更新地址,则地址无效,返回章节内容正待手打 | ||||||
|  |                     */ | ||||||
|  |     // | ||||||
|  |     if(mChapters ==null || mChapters.size() ==0){ | ||||||
|  |         return; | ||||||
|  |     } | ||||||
|  |     Chapter chapter = mChapters.get(index -1); | ||||||
|  |     String url = chapter.getChapterUrl(); | ||||||
|  |     if( TextUtils.isEmpty( url)){ | ||||||
|  |         return ; | ||||||
|  |     } | ||||||
|  |     long startTime= new Date().getTime(); | ||||||
|  |     Log.d(TAG,String.format("loadChaptContent----start download %s from %s",   chapter.getChapterName()  ,url )); | ||||||
|  | 
 | ||||||
|  |     setDownloadFlag(false); | ||||||
|  | 
 | ||||||
|  |     JSONObject siteJson = new JSONObject(); | ||||||
|  |     siteJson.put("chapterContentRegex", mSiteRule.getChapterContentRegex()); | ||||||
|  |     siteJson.put("chapterContentDumpRegex", mSiteRule.getChapterContentDumpRegex()); | ||||||
|  |     Request request = getTagRequest(url); | ||||||
|  |     HttpMethods.getOkClient().newCall(request).enqueue(new Callback() { | ||||||
|  |         @Override | ||||||
|  |         public void onFailure(Call call, IOException e) { | ||||||
|  |             handler.sendEmptyMessage(123); | ||||||
|  |             setDownloadFlag(true); | ||||||
|  |             Log.d(TAG, "loadChaptContent---- onFailure: " + e.getMessage()); | ||||||
|  |             throw new RuntimeException("Error during writing " + fileChapterName( index)); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         @Override | ||||||
|  |         public void onResponse(Call call, Response response){ | ||||||
|  |             ResponseBody body = response.body(); | ||||||
|  |             if (body != null ) { | ||||||
|  |                 if(response.code()!=200){ | ||||||
|  | 
 | ||||||
|  |                     setDownloadFlag(true); | ||||||
|  |                    handler.sendEmptyMessage(1); | ||||||
|  |                     return; | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 try { | ||||||
|  |                     String bodyStr = body.string(); | ||||||
|  |                     String title = chapter.getChapterName(); | ||||||
|  |                     String chapterContent = title+ "\n" + NovelParseUtil.getChapterContent(bodyStr, siteJson); | ||||||
|  |                     char[] buf = chapterContent.toCharArray(); | ||||||
|  |                     File file = new File(fileChapterName(index)); | ||||||
|  |                     file.createNewFile(); | ||||||
|  | 
 | ||||||
|  |                     final OutputStreamWriter writer = new OutputStreamWriter(new FileOutputStream(fileChapterName(index)), charachterType);//"UTF-16LE"); // UTF-16LE 比 utf-8 文件小 | ||||||
|  |                     writer.write(buf); | ||||||
|  |                     writer.close(); | ||||||
|  |                 } catch (IOException | JSONException e) { | ||||||
|  |                     e.printStackTrace(); | ||||||
|  |                     throw new RuntimeException("Error during writing " + fileChapterName( index)); | ||||||
|  |                 } | ||||||
|  |                 finally { | ||||||
|  |                     body.close(); | ||||||
|  | 
 | ||||||
|  |                     handler.sendEmptyMessage(123); | ||||||
|  |                     setDownloadFlag(true); | ||||||
|  |                 } | ||||||
|  |                 chapter.setNovelId(mNovel.getId()); | ||||||
|  |                 chapter.setChapterPath(fileChapterName(index)); | ||||||
|  |                 chapter.save(); | ||||||
|  | 
 | ||||||
|  |                Log.d(TAG,String.format("loadChaptContent---- finished download %s, cost time %s ,content path %s ",  chapter.getChapterName(),  new Date().getTime() -startTime ,chapter.getChapterPath()   )); | ||||||
|  | 
 | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     }); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  |     private Request getTagRequest(String url) { | ||||||
|  |         return new  Request.Builder() | ||||||
|  |                 .tag(mNovel.getNovelId()) //标记 请求的tag,切换小说或离开小说界面(BookActivity) 时 取消未执行完毕的 此tag的所有请求 | ||||||
|  |                 .url(url) | ||||||
|  |                 // .header("User-Agent", "OkHttp Example") | ||||||
|  |                 .build(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|     public boolean isChapterTitle(String line){ |     public boolean isChapterTitle(String line){ | ||||||
|         return (line.length() <= 30 && (line.matches(".*第.{1,8}章.*") || line.matches(".*第.{1,8}节.*")))  ; |         return (line.length() <= 30 && (line.matches(".*第.{1,8}章.*") || line.matches(".*第.{1,8}节.*")))  ; | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -0,0 +1,30 @@ | ||||||
|  | package com.novelbook.android.utils; | ||||||
|  | 
 | ||||||
|  | import com.novelbook.android.db.Novel; | ||||||
|  | 
 | ||||||
|  | import org.json.JSONException; | ||||||
|  | import org.json.JSONObject; | ||||||
|  | 
 | ||||||
|  | public class GsonUtil { | ||||||
|  | 
 | ||||||
|  |     public static Novel getNovel(String json){ | ||||||
|  |         Novel nv = new Novel(); | ||||||
|  |         try { | ||||||
|  |             JSONObject jsonObject = new JSONObject(json); | ||||||
|  |             nv.setNovelId(jsonObject.getString("novelId")); | ||||||
|  |             nv.setLastUpateTime(jsonObject.getLong("lastUpateTime")); | ||||||
|  |             nv.setAuthor(jsonObject.getString("author")); | ||||||
|  |             nv.setName(jsonObject.getString("name")); | ||||||
|  |             nv.setCover(jsonObject.getString("cover")); | ||||||
|  |             nv.setNovelType(jsonObject.getString("novelType")); | ||||||
|  |             nv.setNovelType2(jsonObject.getString("novelType2")); | ||||||
|  |             nv.setLastestChapterName(jsonObject.getString("lastestChapterName")); | ||||||
|  | 
 | ||||||
|  |             return  nv; | ||||||
|  | 
 | ||||||
|  |         } catch (JSONException e) { | ||||||
|  |             e.printStackTrace(); | ||||||
|  |         } | ||||||
|  |         return  nv; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | @ -0,0 +1,22 @@ | ||||||
|  | package com.novelbook.android.utils; | ||||||
|  | 
 | ||||||
|  | import com.novelbook.android.bean.NovelSites; | ||||||
|  | import com.novelbook.android.db.SiteRule; | ||||||
|  | import com.novelbook.android.db.Chapter; | ||||||
|  | import com.novelbook.android.db.Novel; | ||||||
|  | 
 | ||||||
|  | import java.util.List; | ||||||
|  | import java.util.Map; | ||||||
|  | 
 | ||||||
|  | public class NovelConstants { | ||||||
|  |     public static Novel CURRENT_NOVEL; | ||||||
|  |     public static NovelSites CURRENT_NOVEL_SITES; | ||||||
|  |     public static List<Chapter> CURRENT_CHPATERS; | ||||||
|  |     public static Map<String, SiteRule> SiteRules= new FIFOMap<String, SiteRule>(100);; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  | @ -1,16 +1,55 @@ | ||||||
| package com.novelbook.android.utils; | package com.novelbook.android.utils; | ||||||
| 
 | 
 | ||||||
|  | import com.novelbook.android.db.Chapter; | ||||||
|  | 
 | ||||||
| import org.json.JSONException; | import org.json.JSONException; | ||||||
| import org.json.JSONObject; | import org.json.JSONObject; | ||||||
| 
 | 
 | ||||||
|  | import java.util.ArrayList; | ||||||
|  | import java.util.Arrays; | ||||||
| import java.util.LinkedHashMap; | import java.util.LinkedHashMap; | ||||||
|  | import java.util.List; | ||||||
| import java.util.Map; | import java.util.Map; | ||||||
| import java.util.Set; | import java.util.Set; | ||||||
| 
 | 
 | ||||||
| public class NovelParseUtil { | public class NovelParseUtil { | ||||||
| 
 | 
 | ||||||
|     private static final String A_Regex = "<a[^>]+href[\\s]*=[\\s]*['\"]?([^'\"]+)['\"\\s]?[^>]*>([^<]+)<"; |     private static final String A_Regex = "<a[^>]+href[\\s]*=[\\s]*['\"]?([^'\"]+)['\"\\s]?[^>]*>([^<]+)<"; | ||||||
|     public static String[] getChapters(String muluUrl, String html, JSONObject siteJson) throws JSONException { |     public static String[] getChaptersArray(String muluUrl, String html, JSONObject siteJson) throws JSONException { | ||||||
|  | 
 | ||||||
|  |         Map<String, String> muluMap = getChaptersMap(muluUrl,   html,   siteJson); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |         String[] values = new String[muluMap.size() * 2]; | ||||||
|  | 
 | ||||||
|  |         Set<Map.Entry<String, String>> es = muluMap.entrySet(); | ||||||
|  |         int pos = values.length - 2; | ||||||
|  |         for (Map.Entry<String, String> e : es) { | ||||||
|  |             values[pos] = e.getKey(); | ||||||
|  |             values[pos + 1] = e.getValue(); | ||||||
|  |             pos -= 2; | ||||||
|  |         } | ||||||
|  |         return values; | ||||||
|  |     } | ||||||
|  |     public static List<Chapter>  getChapters(String domain,String muluUrl, String html, JSONObject siteJson) throws JSONException { | ||||||
|  | 
 | ||||||
|  |         Map<String, String> muluMap = getChaptersMap(muluUrl,   html,   siteJson); | ||||||
|  |         Chapter[] tmp = new Chapter[muluMap.size()]; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |         Set<Map.Entry<String, String>> es = muluMap.entrySet(); | ||||||
|  |         int pos = tmp.length - 1; | ||||||
|  |         for (Map.Entry<String, String> e : es) { | ||||||
|  |             Chapter chapter = new Chapter(); | ||||||
|  |             chapter.setChapterUrl( e.getKey()); | ||||||
|  |             chapter.setChapterName( e.getValue()); | ||||||
|  |             chapter.setDomain(domain); | ||||||
|  |            tmp[pos--] =chapter; | ||||||
|  |         } | ||||||
|  |         List<Chapter> values = new ArrayList<Chapter>(Arrays.asList(tmp)); | ||||||
|  |         return values; | ||||||
|  |     } | ||||||
|  |     public static Map<String, String> getChaptersMap(String muluUrl, String html, JSONObject siteJson) throws JSONException { | ||||||
|         String chapterUrlRegexOnMulu = siteJson.getString("chapterUrlRegexOnMulu"); |         String chapterUrlRegexOnMulu = siteJson.getString("chapterUrlRegexOnMulu"); | ||||||
|         String chapterUrlPattern = siteJson.getString("chapterUrlPattern"); |         String chapterUrlPattern = siteJson.getString("chapterUrlPattern"); | ||||||
| 
 | 
 | ||||||
|  | @ -34,16 +73,8 @@ public class NovelParseUtil { | ||||||
|             muluMap.put(href, name); |             muluMap.put(href, name); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         String[] values = new String[muluMap.size() * 2]; |         return  muluMap; | ||||||
| 
 | 
 | ||||||
|         Set<Map.Entry<String, String>> es = muluMap.entrySet(); |  | ||||||
|         int pos = values.length - 2; |  | ||||||
|         for (Map.Entry<String, String> e : es) { |  | ||||||
|             values[pos] = e.getKey(); |  | ||||||
|             values[pos + 1] = e.getValue(); |  | ||||||
|             pos -= 2; |  | ||||||
|         } |  | ||||||
|         return values; |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public static String getChapterContent(String html, JSONObject siteJson) throws JSONException  { |     public static String getChapterContent(String html, JSONObject siteJson) throws JSONException  { | ||||||
|  |  | ||||||
|  | @ -13,6 +13,7 @@ import android.graphics.RectF; | ||||||
| import android.graphics.Region; | import android.graphics.Region; | ||||||
| import android.graphics.Typeface; | import android.graphics.Typeface; | ||||||
| import android.os.AsyncTask; | import android.os.AsyncTask; | ||||||
|  | import android.text.TextUtils; | ||||||
| import android.util.DisplayMetrics; | import android.util.DisplayMetrics; | ||||||
| import android.util.Log; | import android.util.Log; | ||||||
| import android.view.WindowManager; | import android.view.WindowManager; | ||||||
|  | @ -20,8 +21,10 @@ import android.widget.Toast; | ||||||
| 
 | 
 | ||||||
| import com.novelbook.android.Config; | import com.novelbook.android.Config; | ||||||
| import com.novelbook.android.R; | import com.novelbook.android.R; | ||||||
|  | import com.novelbook.android.bean.NovelSites; | ||||||
| import com.novelbook.android.db.Chapter; | import com.novelbook.android.db.Chapter; | ||||||
| import com.novelbook.android.db.Novel; | import com.novelbook.android.db.Novel; | ||||||
|  | import com.novelbook.android.netutils.NetUtil; | ||||||
| import com.novelbook.android.view.PageWidget; | import com.novelbook.android.view.PageWidget; | ||||||
| 
 | 
 | ||||||
| import org.litepal.LitePal; | import org.litepal.LitePal; | ||||||
|  | @ -139,8 +142,12 @@ public class PageFactory { | ||||||
|     private Novel mBook; |     private Novel mBook; | ||||||
|     //书的目录列表 |     //书的目录列表 | ||||||
|     private List<Chapter> mChapters; |     private List<Chapter> mChapters; | ||||||
|  |     //当前章节 | ||||||
|  |    // private Chapter  mCurrentChapter; | ||||||
|     //书本章节 |     //书本章节 | ||||||
|     private int currentChapter = 0; |     private int currentChapter = 0; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|     //当前电量 |     //当前电量 | ||||||
|     private int level = 0; |     private int level = 0; | ||||||
|     private BookUtil mBookUtil; |     private BookUtil mBookUtil; | ||||||
|  | @ -218,7 +225,7 @@ public class PageFactory { | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     private PageFactory(Context context) { |     private PageFactory(Context context) { | ||||||
|         mBookUtil = new BookUtil(); |        // mBookUtil = new BookUtil(); | ||||||
|         mContext = context.getApplicationContext(); |         mContext = context.getApplicationContext(); | ||||||
|         config = Config.getInstance(); |         config = Config.getInstance(); | ||||||
|         //获取屏幕宽高 |         //获取屏幕宽高 | ||||||
|  | @ -343,7 +350,7 @@ public class PageFactory { | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public void onDraw(Bitmap bitmap,List<String> m_lines,Boolean updateChapter) { |     public void onDraw(Bitmap bitmap,List<String> m_lines,Boolean updateChapter) { | ||||||
|         if (getDirectoryList().size() > 0 && updateChapter) { |         if (getChapters().size() > 0 && updateChapter) { | ||||||
|             currentChapter = getCurrentCharter(); |             currentChapter = getCurrentCharter(); | ||||||
|         } |         } | ||||||
|         //更新数据库进度 |         //更新数据库进度 | ||||||
|  | @ -352,11 +359,11 @@ public class PageFactory { | ||||||
|                 @Override |                 @Override | ||||||
|                 public void run() { |                 public void run() { | ||||||
|                     super.run(); |                     super.run(); | ||||||
|                     values.put("begin",currentPage.getBegin()); |                     values.put("lastReadPos",currentPage.getBegin()); | ||||||
|                     values.put("biginChapt",currentChapter); |                     values.put("lastReadChapt",currentChapter); | ||||||
|                    Log.d(TAG,String.format("begin to update book %s chapter%s bigin %s ",mBook.getNovelName(),currentChapter, currentPage.getBegin() ) ); |                    Log.d(TAG,String.format("begin to update book %s chapter%s bigin %s ",mBook.getName(),currentChapter, currentPage.getBegin() ) ); | ||||||
|                   int rows =  LitePal.update(Novel.class,values,mBook.getId()); |                   int rows =  LitePal.update(Novel.class,values,mBook.getId()); | ||||||
|                    Log.d(TAG,String.format("update book %s chapter%s bigin %s, result %s",mBook.getNovelName(),currentChapter, currentPage.getBegin(),rows) ); |                    Log.d(TAG,String.format("update book %s chapter%s bigin %s, result %s",mBook.getName(),currentChapter, currentPage.getBegin(),rows) ); | ||||||
|         } |         } | ||||||
|     }.start(); |     }.start(); | ||||||
|         } |         } | ||||||
|  | @ -439,12 +446,17 @@ public class PageFactory { | ||||||
|         //画书名 |         //画书名 | ||||||
|         c.drawText(CommonUtil.subString(bookName,12), marginWidth ,statusMarginBottom + mBatterryFontSize, mBatterryPaint); |         c.drawText(CommonUtil.subString(bookName,12), marginWidth ,statusMarginBottom + mBatterryFontSize, mBatterryPaint); | ||||||
|         //画章 |         //画章 | ||||||
|         if (getDirectoryList().size() > 0) { |        /* String chapterName =""; | ||||||
|             String charterName = CommonUtil.subString(getDirectoryList().get(currentChapter-1).getChapterName(),16); |         if(mCurrentChapter!=null){ | ||||||
|             int nChaterWidth = (int) mBatterryPaint.measureText(charterName) + 1; |             chapterName = mCurrentChapter.getChapterName(); | ||||||
|             c.drawText(charterName, mWidth - marginWidth - nChaterWidth, statusMarginBottom  + mBatterryFontSize, mBatterryPaint); |         }else*/ | ||||||
|         } |        if (getChapters().size() > 0) | ||||||
|  |         { | ||||||
|  |             String  chapterName = CommonUtil.subString(getChapters().get(currentChapter-1).getChapterName(),16); | ||||||
|  |             int nChaterWidth = (int) mBatterryPaint.measureText(chapterName) + 1; | ||||||
|  |             c.drawText(chapterName, mWidth - marginWidth - nChaterWidth, statusMarginBottom  + mBatterryFontSize, mBatterryPaint); | ||||||
| 
 | 
 | ||||||
|  |         } | ||||||
|                mBookPageWidget.postInvalidate(); |                mBookPageWidget.postInvalidate(); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | @ -473,7 +485,7 @@ public class PageFactory { | ||||||
|         if (currentPage.getEnd() >= mBookUtil.getBookLen()) { |         if (currentPage.getEnd() >= mBookUtil.getBookLen()) { | ||||||
|            Log.d(TAG,"已经是本章最后一页了"); |            Log.d(TAG,"已经是本章最后一页了"); | ||||||
| 
 | 
 | ||||||
|             m_islastPage =currentChapter == mBookUtil.getDirectoryList().size(); |             m_islastPage =currentChapter == mBookUtil.getChapters().size(); | ||||||
|             if ( m_islastPage){ |             if ( m_islastPage){ | ||||||
|                 Toast.makeText(mContext, "已经是最后一页了", Toast.LENGTH_SHORT).show(); |                 Toast.makeText(mContext, "已经是最后一页了", Toast.LENGTH_SHORT).show(); | ||||||
|                 return; |                 return; | ||||||
|  | @ -496,29 +508,51 @@ public class PageFactory { | ||||||
|         currentPage = cancelPage; |         currentPage = cancelPage; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     public void prepareBook(Novel book,NovelSites nvs,Context context){ | ||||||
|  |         if(mBook!=null &&mBook.getNovelId() !=book.getNovelId()){ //取消未上本书完成的web请求,待验证效果 | ||||||
|  |             NetUtil.cancelRequest(mBook.getNovelId()); | ||||||
|  |         } | ||||||
|  |         mBookUtil = new BookUtil(); | ||||||
|  |         this.mBookUtil.setContext(context); | ||||||
|  |         this.mBookUtil.setNovel(book); | ||||||
|  |         this.mBookUtil.setNovelSites(nvs); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     /** |     /** | ||||||
|      * 打开书本 |      * 打开书本 | ||||||
|      * @throws IOException |      * @throws IOException | ||||||
|      */ |      */ | ||||||
|     public void openBook(Novel book , List<Chapter> chapters ) throws IOException { |     public void openBook(Novel book ,Context context) throws IOException { | ||||||
|  |         if(null ==mBookUtil || !TextUtils.isEmpty(book.getNovelPath())  ){ //离线书籍重新初始化加载mBookUtil | ||||||
|  |             mBookUtil = new BookUtil(); | ||||||
|  |             mBookUtil.setContext(context); | ||||||
|  |         } | ||||||
|         //清空数据 |         //清空数据 | ||||||
|         currentChapter = 0; |         currentChapter = 0; | ||||||
| //        m_mbBufLen = 0; | //        m_mbBufLen = 0; | ||||||
|         initBg(config.getDayOrNight()); |         initBg(config.getDayOrNight()); | ||||||
| 
 | 
 | ||||||
|  |         if(mBook!=null &&mBook.getNovelId() !=book.getNovelId()){ //取消未上本书完成的web请求 | ||||||
|  |            NetUtil.cancelRequest(mBook.getNovelId()); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|         this.mBook = book ; |         this.mBook = book ; | ||||||
|         bookPath = mBook.getNovelPath(); |         bookPath = mBook.getNovelPath(); | ||||||
|         bookName =mBook.getNovelName();// FileUtils.getFileName(bookPath); |         bookName =mBook.getName();// FileUtils.getFileName(bookPath); | ||||||
|         this.mChapters = chapters; |       //  this.mCurrentChapter = chapter; | ||||||
|         mStatus = Status.OPENING; |         mStatus = Status.OPENING; | ||||||
|         drawStatus(mBookPageWidget.getCurPage()); |         drawStatus(mBookPageWidget.getCurPage()); | ||||||
|         drawStatus(mBookPageWidget.getNextPage()); |         drawStatus(mBookPageWidget.getNextPage()); | ||||||
|         if (bookTask != null && bookTask.getStatus() != AsyncTask.Status.FINISHED){ |         if (bookTask != null && bookTask.getStatus() != AsyncTask.Status.FINISHED){ | ||||||
|             bookTask.cancel(true); |             bookTask.cancel(true); | ||||||
|         } |         } | ||||||
|  | 
 | ||||||
|         bookTask = new BookTask(); |         bookTask = new BookTask(); | ||||||
| 
 | 
 | ||||||
|         bookTask.execute(book.getLastReadChapt(),book .getLastReadPos()); |         bookTask.execute((long)book.getLastReadChapt(),book .getLastReadPos()); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     private class BookTask extends AsyncTask<Long,Void,Boolean>{ |     private class BookTask extends AsyncTask<Long,Void,Boolean>{ | ||||||
|  | @ -535,9 +569,6 @@ public class PageFactory { | ||||||
|                 PageFactory.mStatus = PageFactory.Status.FINISH; |                 PageFactory.mStatus = PageFactory.Status.FINISH; | ||||||
| //                m_mbBufLen = mBookUtil.getBookLen(); | //                m_mbBufLen = mBookUtil.getBookLen(); | ||||||
|                 mBookUtil.setChapterNo((int)chapter); |                 mBookUtil.setChapterNo((int)chapter); | ||||||
|                 if(mChapters!=null) { |  | ||||||
|                     mBookUtil.setChapters(mChapters); |  | ||||||
|                 } |  | ||||||
|                 currentChaptPages = loadCurrentChapt((int)chapter); |                 currentChaptPages = loadCurrentChapt((int)chapter); | ||||||
|                 currentPage = getPageForBegin(begin) ;// currentChaptPages.get(0); |                 currentPage = getPageForBegin(begin) ;// currentChaptPages.get(0); | ||||||
|               //  currentPage = getPageForBegin(begin); |               //  currentPage = getPageForBegin(begin); | ||||||
|  | @ -805,7 +836,7 @@ public class PageFactory { | ||||||
| 
 | 
 | ||||||
|     //上一章 |     //上一章 | ||||||
|     public void preChapter(){ |     public void preChapter(){ | ||||||
|         if (mBookUtil.getDirectoryList().size() > 0){ |         if (mBookUtil.getChapters().size() > 0){ | ||||||
|             int num = currentChapter; |             int num = currentChapter; | ||||||
|             if (num ==1){ |             if (num ==1){ | ||||||
|                 num =getCurrentCharter(); |                 num =getCurrentCharter(); | ||||||
|  | @ -831,7 +862,7 @@ public class PageFactory { | ||||||
|             num =getCurrentCharter(); |             num =getCurrentCharter(); | ||||||
|         } |         } | ||||||
|         num ++; |         num ++; | ||||||
|         if (num <= getDirectoryList().size()){ |         if (num <= getChapters().size()){ | ||||||
| 
 | 
 | ||||||
|             preChaptPages =currentChaptPages; |             preChaptPages =currentChaptPages; | ||||||
|             currentChapter = num; |             currentChapter = num; | ||||||
|  | @ -1032,13 +1063,19 @@ public class PageFactory { | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     //获取书本的章 |     //获取书本的章 | ||||||
|     public List<Chapter> getDirectoryList(){ |     public List<Chapter> getChapters(){ | ||||||
|         return mBookUtil.getDirectoryList(); |         return mBookUtil.getChapters(); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public String getBookPath(){ |     public String getBookPath(){ | ||||||
|         return bookPath; |         return bookPath; | ||||||
|     } |     } | ||||||
|  |     public String getBookName(){ | ||||||
|  |         return mBook.getName(); | ||||||
|  |     } | ||||||
|  |     public Novel getNovle(){ | ||||||
|  |         return mBook; | ||||||
|  |     } | ||||||
|     //是否是第一页 |     //是否是第一页 | ||||||
|     public boolean isfirstPage() { |     public boolean isfirstPage() { | ||||||
|         return m_isfirstPage; |         return m_isfirstPage; | ||||||
|  |  | ||||||
|  | @ -152,6 +152,7 @@ | ||||||
|         > |         > | ||||||
| 
 | 
 | ||||||
|         <Button |         <Button | ||||||
|  |             android:id="@+id/btnShelf" | ||||||
|             android:text="加入书架" |             android:text="加入书架" | ||||||
|             android:layout_width="match_parent" |             android:layout_width="match_parent" | ||||||
|             android:layout_height="match_parent" |             android:layout_height="match_parent" | ||||||
|  |  | ||||||
|  | @ -87,6 +87,7 @@ | ||||||
|                     /> |                     /> | ||||||
| 
 | 
 | ||||||
|                 <TextView |                 <TextView | ||||||
|  | 
 | ||||||
|                     style="@style/TextViewTitle" |                     style="@style/TextViewTitle" | ||||||
|                     android:layout_width="wrap_content" |                     android:layout_width="wrap_content" | ||||||
|                     android:layout_height="wrap_content" |                     android:layout_height="wrap_content" | ||||||
|  | @ -95,6 +96,7 @@ | ||||||
|             </LinearLayout> |             </LinearLayout> | ||||||
| 
 | 
 | ||||||
|             <TextView |             <TextView | ||||||
|  |                 android:id="@+id/txtDesc2" | ||||||
|                 style="@style/TextViewDesc" |                 style="@style/TextViewDesc" | ||||||
|                 android:layout_width="wrap_content" |                 android:layout_width="wrap_content" | ||||||
|                 android:layout_height="wrap_content" |                 android:layout_height="wrap_content" | ||||||
|  | @ -164,6 +166,7 @@ | ||||||
|                     android:orientation="vertical"> |                     android:orientation="vertical"> | ||||||
| 
 | 
 | ||||||
|                     <TextView |                     <TextView | ||||||
|  |                         android:id="@+id/txtLatestCate" | ||||||
|                         style="@style/TextViewDesc" |                         style="@style/TextViewDesc" | ||||||
|                         android:layout_width="wrap_content" |                         android:layout_width="wrap_content" | ||||||
|                         android:layout_height="wrap_content" |                         android:layout_height="wrap_content" | ||||||
|  | @ -171,16 +174,8 @@ | ||||||
| 
 | 
 | ||||||
|                         /> |                         /> | ||||||
| 
 | 
 | ||||||
|                     <TextView | 
 | ||||||
|                         style="@style/TextViewDesc" | 
 | ||||||
|                         android:layout_width="wrap_content" |  | ||||||
|                         android:layout_height="wrap_content" |  | ||||||
|                         android:text="第一万两千八百章 天冷好个秋" /> |  | ||||||
|                     <TextView |  | ||||||
|                         style="@style/TextViewDesc" |  | ||||||
|                         android:layout_width="wrap_content" |  | ||||||
|                         android:layout_height="wrap_content" |  | ||||||
|                         android:text="第一万两千八百零一章 天冷好个秋2" /> |  | ||||||
|                 </LinearLayout> |                 </LinearLayout> | ||||||
| 
 | 
 | ||||||
|                 <TextView |                 <TextView | ||||||
|  |  | ||||||
|  | @ -200,7 +200,7 @@ | ||||||
| 
 | 
 | ||||||
|     <style name="TextViewHead.bold"> |     <style name="TextViewHead.bold"> | ||||||
|         <item name="android:textStyle">bold</item> |         <item name="android:textStyle">bold</item> | ||||||
| 
 |         <item name="android:textSize">18sp</item> | ||||||
|     </style> |     </style> | ||||||
| 
 | 
 | ||||||
|     <style name="AppTheme.AppBarOverlay" parent="ThemeOverlay.AppCompat.Dark.ActionBar" /> |     <style name="AppTheme.AppBarOverlay" parent="ThemeOverlay.AppCompat.Dark.ActionBar" /> | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue