├── .gitignore
├── .idea
├── gradle.xml
├── kotlinc.xml
├── misc.xml
├── modules.xml
├── runConfigurations.xml
└── vcs.xml
├── README.md
├── app
├── .gitignore
├── build.gradle
├── proguard-rules.pro
├── release
│ └── output.json
└── src
│ ├── androidTest
│ └── java
│ │ └── cc
│ │ └── zsakvo
│ │ └── a99demo
│ │ └── ExampleInstrumentedTest.java
│ ├── main
│ ├── AndroidManifest.xml
│ ├── java
│ │ └── cc
│ │ │ └── zsakvo
│ │ │ └── ninecswd
│ │ │ ├── ArticleActivity.java
│ │ │ ├── BookDetailActivity.java
│ │ │ ├── CategoryActivity.java
│ │ │ ├── ChangeCoverActivity.java
│ │ │ ├── MainActivity.java
│ │ │ ├── SearchActivity.java
│ │ │ ├── adapter
│ │ │ ├── ArticleAdapter.java
│ │ │ ├── CategoryAdapter.java
│ │ │ ├── CoverListAdapter.java
│ │ │ ├── ListAdapter.java
│ │ │ └── MyViewpagerAdapter.java
│ │ │ ├── application
│ │ │ └── MyApplication.java
│ │ │ ├── classes
│ │ │ ├── ArticleList.java
│ │ │ ├── BookDetails.java
│ │ │ ├── BookList.java
│ │ │ └── DownloadDetails.java
│ │ │ ├── fragment
│ │ │ ├── ArticleFragment.java
│ │ │ ├── BaseFragment.java
│ │ │ ├── BookStoreFragment.java
│ │ │ └── CategoryFragment.java
│ │ │ ├── listener
│ │ │ ├── Interface.java
│ │ │ ├── ItemClickListener.java
│ │ │ └── OnDataFinishedListener.java
│ │ │ ├── phrase
│ │ │ ├── Book.java
│ │ │ └── PhraseBookDetail.java
│ │ │ ├── task
│ │ │ ├── DownloadTask.java
│ │ │ ├── GetArticleContentTask.java
│ │ │ ├── GetArticleListTask.java
│ │ │ ├── GetBookDetailTask.java
│ │ │ ├── GetBookListTask.java
│ │ │ ├── GetCategoryListTask.java
│ │ │ ├── GetCoversTask.java
│ │ │ ├── GetDownloadInfoTask.java
│ │ │ ├── GetSearchListTask.java
│ │ │ ├── OutPutTxtTask.java
│ │ │ └── SetCoverTask.java
│ │ │ └── utils
│ │ │ ├── DecodeUtils.java
│ │ │ ├── DialogUtils.java
│ │ │ ├── EpubUtils.java
│ │ │ ├── ReplaceUtils.java
│ │ │ ├── SplitUtil.java
│ │ │ └── TxtUtils.java
│ └── res
│ │ ├── drawable-v24
│ │ └── ic_launcher_foreground.xml
│ │ ├── drawable
│ │ ├── ic_baidu.xml
│ │ ├── ic_bing.xml
│ │ ├── ic_launcher_background.xml
│ │ └── ic_search.xml
│ │ ├── layout
│ │ ├── activity_article.xml
│ │ ├── activity_category.xml
│ │ ├── activity_change_cover.xml
│ │ ├── activity_main.xml
│ │ ├── activity_search.xml
│ │ ├── articlelist.xml
│ │ ├── booklist.xml
│ │ ├── categorylist.xml
│ │ ├── coverlist.xml
│ │ ├── dialog.xml
│ │ ├── fragment_99lib.xml
│ │ ├── fragment_article.xml
│ │ ├── fragment_category.xml
│ │ └── n_activity_book_detail.xml
│ │ ├── menu
│ │ ├── main_menu.xml
│ │ ├── search_menu.xml
│ │ └── select_engine_menu.xml
│ │ ├── mipmap-anydpi-v26
│ │ ├── ic_launcher.xml
│ │ └── ic_launcher_round.xml
│ │ ├── mipmap-hdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ ├── mipmap-mdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ ├── mipmap-xhdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ ├── mipmap-xxhdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ ├── mipmap-xxxhdpi
│ │ └── ic_launcher_round.png
│ │ └── values
│ │ ├── colors.xml
│ │ ├── strings.xml
│ │ └── styles.xml
│ └── test
│ └── java
│ └── cc
│ └── zsakvo
│ └── a99demo
│ └── ExampleUnitTest.java
├── build.gradle
├── gradle.properties
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
└── settings.gradle
/.gitignore:
--------------------------------------------------------------------------------
1 | *.iml
2 | .gradle
3 | /local.properties
4 | /.idea/workspace.xml
5 | /.idea/libraries
6 | .DS_Store
7 | /build
8 | /captures
9 | .externalNativeBuild
10 |
--------------------------------------------------------------------------------
/.idea/gradle.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
17 |
18 |
--------------------------------------------------------------------------------
/.idea/kotlinc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/.idea/runConfigurations.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | 2018.9.7 网站升级,目前已失效,研究更新
2 |
3 | # 99LibraryDownloader
4 | 从99lib抓取书籍并生成epub
5 |
6 |
7 |
--------------------------------------------------------------------------------
/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/app/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 |
3 | android {
4 | compileSdkVersion 27
5 | defaultConfig {
6 | applicationId "cc.zsakvo.ninecswd"
7 | minSdkVersion 21
8 | targetSdkVersion 27
9 | versionCode 3
10 | versionName "1.1-beta"
11 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
12 | }
13 | buildTypes {
14 | release {
15 | minifyEnabled false
16 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
17 | }
18 | }
19 | }
20 |
21 | dependencies {
22 | implementation fileTree(dir: 'libs', include: ['*.jar'])
23 | implementation 'com.android.support:appcompat-v7:27.0.2'
24 | implementation 'com.android.support:cardview-v7:27.0.2'
25 | implementation 'com.zzhoujay.richtext:richtext:3.0.5'
26 | implementation 'com.android.support:design:27.0.2'
27 | implementation 'com.scwang.smartrefresh:SmartRefreshLayout:1.0.4-7'
28 | implementation 'com.scwang.smartrefresh:SmartRefreshHeader:1.0.4-7'
29 | implementation 'org.zeroturnaround:zt-zip:1.12'
30 | // implementation 'org.jsoup:jsoup:1.11.2'
31 | implementation 'com.github.limuyang2:CardSearchView:1.0.6.9'
32 | implementation 'com.github.nukc.stateview:library:1.3.4'
33 | implementation 'io.simi:nob:0.0.8'
34 | // implementation 'com.mapzen:on-the-road:0.8.1'
35 | implementation 'com.github.bumptech.glide:glide:4.4.0'
36 | // implementation 'com.alibaba:fastjson:1.1.68.android'
37 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jre7:1.2.31"
38 | implementation 'com.android.support.constraint:constraint-layout:1.0.2'
39 | testImplementation 'junit:junit:4.12'
40 | androidTestImplementation 'com.android.support.test:runner:1.0.1'
41 | androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1'
42 | }
43 |
--------------------------------------------------------------------------------
/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
22 |
--------------------------------------------------------------------------------
/app/release/output.json:
--------------------------------------------------------------------------------
1 | [{"outputType":{"type":"APK"},"apkInfo":{"type":"MAIN","splits":[],"versionCode":3},"path":"app-release.apk","properties":{"packageId":"cc.zsakvo.ninecswd","split":"","minSdkVersion":"21"}}]
--------------------------------------------------------------------------------
/app/src/androidTest/java/cc/zsakvo/a99demo/ExampleInstrumentedTest.java:
--------------------------------------------------------------------------------
1 | package cc.zsakvo.a99demo;
2 |
3 | import android.content.Context;
4 | import android.support.test.InstrumentationRegistry;
5 | import android.support.test.runner.AndroidJUnit4;
6 |
7 | import org.junit.Test;
8 | import org.junit.runner.RunWith;
9 |
10 | import static org.junit.Assert.*;
11 |
12 | /**
13 | * Instrumented test, which will execute on an Android device.
14 | *
15 | * @see Testing documentation
16 | */
17 | @RunWith(AndroidJUnit4.class)
18 | public class ExampleInstrumentedTest {
19 | @Test
20 | public void useAppContext() throws Exception {
21 | // Context of the app under test.
22 | Context appContext = InstrumentationRegistry.getTargetContext();
23 |
24 | assertEquals("cc.zsakvo.a99demo", appContext.getPackageName());
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
8 |
9 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/app/src/main/java/cc/zsakvo/ninecswd/ArticleActivity.java:
--------------------------------------------------------------------------------
1 | package cc.zsakvo.ninecswd;
2 |
3 | import android.support.design.widget.Snackbar;
4 | import android.support.v7.app.AppCompatActivity;
5 | import android.os.Bundle;
6 | import android.support.v7.widget.Toolbar;
7 | import android.view.MenuItem;
8 | import android.view.View;
9 | import android.widget.ScrollView;
10 | import android.widget.TextView;
11 |
12 | import com.github.nukc.stateview.StateView;
13 | import com.scwang.smartrefresh.header.MaterialHeader;
14 | import com.scwang.smartrefresh.layout.api.RefreshLayout;
15 | import com.scwang.smartrefresh.layout.listener.OnRefreshListener;
16 |
17 | import cc.zsakvo.ninecswd.listener.Interface;
18 | import cc.zsakvo.ninecswd.task.GetArticleContentTask;
19 |
20 | public class ArticleActivity extends AppCompatActivity implements Interface.GetArticle,OnRefreshListener{
21 |
22 | Toolbar toolbar;
23 | private StateView mStateView;
24 | RefreshLayout refreshLayout;
25 | TextView tv_article;
26 | String url;
27 | ScrollView sv;
28 |
29 | @Override
30 | protected void onCreate(Bundle savedInstanceState) {
31 | super.onCreate (savedInstanceState);
32 | setContentView (R.layout.activity_article);
33 | toolbar = (Toolbar)findViewById (R.id.atToolBar);
34 | toolbar.setTitle ("文库");
35 | setSupportActionBar(toolbar);
36 | if (getSupportActionBar() != null) {
37 | getSupportActionBar ().setDisplayHomeAsUpEnabled (true);
38 | }
39 | url = getIntent ().getStringExtra ("url");
40 | String title = getIntent ().getStringExtra ("title");
41 | tv_article = (TextView)findViewById (R.id.article);
42 | sv = (ScrollView)findViewById (R.id.at_scroll);
43 | refreshLayout = (RefreshLayout)findViewById (R.id.atRefreshLayout);
44 | refreshLayout.setOnRefreshListener (this);
45 | refreshLayout.setEnableAutoLoadmore (true);
46 | MaterialHeader mMaterialHeader = (MaterialHeader) refreshLayout.getRefreshHeader ();
47 | refreshLayout.autoRefresh ();
48 | // GetArticleContentTask gct = new GetArticleContentTask (tv_article,toolbar,mStateView,this);
49 | // gct.execute (url);
50 | }
51 |
52 | @Override
53 | public boolean onOptionsItemSelected(MenuItem item) {
54 | if(item.getItemId()==android.R.id.home){
55 | finish ();
56 | return true;
57 | }
58 | return super.onOptionsItemSelected(item);
59 | }
60 |
61 | @Override
62 | public void GetResult(Boolean result) {
63 | if (result){
64 | sv.setVisibility (View.VISIBLE);
65 | refreshLayout.finishRefresh (300);
66 | }else {
67 | refreshLayout.finishRefresh (false);
68 | Snackbar.make (toolbar,"数据获取失败,请检查网络连接后重试!",Snackbar.LENGTH_LONG).show ();
69 | }
70 | }
71 |
72 | @Override
73 | public void onRefresh(RefreshLayout refreshlayout) {
74 | GetArticleContentTask gct = new GetArticleContentTask (tv_article,toolbar,mStateView,ArticleActivity.this);
75 | gct.execute (url);
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/app/src/main/java/cc/zsakvo/ninecswd/BookDetailActivity.java:
--------------------------------------------------------------------------------
1 | package cc.zsakvo.ninecswd;
2 |
3 | import android.app.Activity;
4 | import android.app.Dialog;
5 | import android.content.Intent;
6 | import android.content.pm.PackageManager;
7 | import android.graphics.Bitmap;
8 | import android.graphics.drawable.BitmapDrawable;
9 | import android.net.Uri;
10 | import android.os.AsyncTask;
11 | import android.os.Build;
12 | import android.os.Environment;
13 | import android.support.design.widget.FloatingActionButton;
14 | import android.support.design.widget.Snackbar;
15 | import android.support.v4.app.ActivityCompat;
16 | import android.support.v7.app.AppCompatActivity;
17 | import android.os.Bundle;
18 | import android.support.v7.widget.CardView;
19 | import android.support.v7.widget.Toolbar;
20 | import android.util.Log;
21 | import android.view.MenuItem;
22 | import android.view.View;
23 | import android.widget.ImageView;
24 | import android.widget.TextView;
25 |
26 | import com.bumptech.glide.Glide;
27 | import com.scwang.smartrefresh.header.MaterialHeader;
28 | import com.scwang.smartrefresh.layout.api.RefreshLayout;
29 | import com.scwang.smartrefresh.layout.listener.OnRefreshListener;
30 |
31 | import org.w3c.dom.Text;
32 |
33 | import java.io.File;
34 | import java.util.ArrayList;
35 | import java.util.List;
36 | import java.util.concurrent.ConcurrentHashMap;
37 |
38 | import cc.zsakvo.ninecswd.classes.DownloadDetails;
39 | import cc.zsakvo.ninecswd.listener.Interface;
40 | import cc.zsakvo.ninecswd.listener.OnDataFinishedListener;
41 | import cc.zsakvo.ninecswd.task.DownloadTask;
42 | import cc.zsakvo.ninecswd.task.GetDownloadInfoTask;
43 | import cc.zsakvo.ninecswd.task.GetBookDetailTask;
44 | import cc.zsakvo.ninecswd.task.OutPutTxtTask;
45 | import cc.zsakvo.ninecswd.task.SetCoverTask;
46 | import cc.zsakvo.ninecswd.utils.DialogUtils;
47 | import cc.zsakvo.ninecswd.utils.EpubUtils;
48 | import cc.zsakvo.ninecswd.utils.SplitUtil;
49 | import io.simi.nob.NOBKit;
50 |
51 | import static android.os.AsyncTask.THREAD_POOL_EXECUTOR;
52 |
53 | public class BookDetailActivity extends AppCompatActivity implements View.OnClickListener,OnDataFinishedListener,EpubUtils.getResult,Interface.GetBookDetailFinish,OnRefreshListener,Interface.OutPutTxtFinish{
54 |
55 | Toolbar toolbar;
56 | TextView tv_title,tv_intro,tv_detail,tv_dlTXT,tv_dlEpub,tv_dlNob;
57 | ImageView iv_cover;
58 | RefreshLayout refreshLayout;
59 | String url;
60 | CardView cv;
61 | FloatingActionButton fab;
62 | Dialog loadingDialog;
63 | ConcurrentHashMap ch = new ConcurrentHashMap<> ();
64 | private int nowNum;
65 | private int allNum;
66 | private List chapterIDs;
67 | private int whatGenerate = 0;
68 | private Boolean loadOK = false;
69 | DialogUtils du;
70 | Boolean hasPermissions = false;
71 | DownloadDetails downloadDetails = null;
72 | private static final int REQUEST_EXTERNAL_STORAGE = 1;
73 | private static String[] PERMISSIONS_STORAGE = {
74 | "android.permission.READ_EXTERNAL_STORAGE",
75 | "android.permission.WRITE_EXTERNAL_STORAGE" };
76 | private Bitmap cover_bit;
77 | private String searchStr;
78 |
79 | @Override
80 | protected void onCreate(Bundle savedInstanceState) {
81 | super.onCreate(savedInstanceState);
82 | setContentView(R.layout.n_activity_book_detail);
83 | toolbar = (Toolbar)findViewById(R.id.bdToolBar);
84 | toolbar.setTitle("书籍详情");
85 | setSupportActionBar(toolbar);
86 | if (getSupportActionBar() != null) {
87 | getSupportActionBar ().setDisplayHomeAsUpEnabled (true);
88 | }
89 | url = getIntent().getStringExtra("url");
90 | tv_title = (TextView)findViewById(R.id.bdTitle);
91 | tv_intro = (TextView)findViewById(R.id.bdIntro);
92 | tv_detail = (TextView)findViewById(R.id.bdDetail);
93 | iv_cover = (ImageView)findViewById(R.id.bdCover);
94 | iv_cover.setOnClickListener (this);
95 | du = new DialogUtils (this,loadingDialog);
96 |
97 | cv = (CardView)findViewById (R.id.dl_card);
98 | tv_dlTXT = (TextView)findViewById (R.id.dl_txt);
99 | tv_dlTXT.setOnClickListener (this);
100 | tv_dlEpub = (TextView)findViewById (R.id.dl_epub);
101 | tv_dlEpub.setOnClickListener (this);
102 | tv_dlNob = (TextView) findViewById (R.id.dl_nob);
103 | tv_dlNob.setOnClickListener (this);
104 |
105 | refreshLayout = (RefreshLayout) findViewById (R.id.bdRefreshLayout);
106 | refreshLayout.setOnRefreshListener(this);
107 | refreshLayout.setEnableAutoLoadmore (true);
108 | MaterialHeader mMaterialHeader = (MaterialHeader) refreshLayout.getRefreshHeader ();
109 | refreshLayout.autoRefresh ();
110 | verifyStoragePermissions(BookDetailActivity.this);
111 | }
112 |
113 | private void beginDownload(){
114 | remindStoragePermissions(BookDetailActivity.this);
115 | if (hasPermissions) {
116 | nowNum = 0;
117 | GetDownloadInfoTask gdi = new GetDownloadInfoTask (du);
118 | gdi.setOnDataFinishedListener (this);
119 | gdi.execute (url);
120 | }else {
121 | Snackbar.make (toolbar,"未授予存储权限,无法下载书籍!",Snackbar.LENGTH_LONG).show ();
122 | verifyStoragePermissions (BookDetailActivity.this);
123 | }
124 | }
125 |
126 | @Override
127 | public void onClick(View view) {
128 | switch (view.getId()){
129 | case R.id.dl_txt:
130 | whatGenerate = 0;
131 | beginDownload();
132 | break;
133 | case R.id.dl_epub:
134 | whatGenerate = 1;
135 | beginDownload();
136 | break;
137 | case R.id.dl_nob:
138 | whatGenerate = 2;
139 | beginDownload();
140 | break;
141 | case R.id.bdCover:
142 | Intent intent = new Intent (BookDetailActivity.this,ChangeCoverActivity.class);
143 | intent.putExtra ("str",searchStr);
144 | startActivityForResult(intent, 0);
145 | }
146 | }
147 |
148 | public void verifyStoragePermissions(Activity activity) {
149 |
150 | try {
151 | //检测是否有写的权限
152 | int permission = ActivityCompat.checkSelfPermission(activity,
153 | "android.permission.WRITE_EXTERNAL_STORAGE");
154 | if (permission != PackageManager.PERMISSION_GRANTED) {
155 | // 没有写的权限,去申请写的权限,会弹出对话框
156 | ActivityCompat.requestPermissions(activity, PERMISSIONS_STORAGE,REQUEST_EXTERNAL_STORAGE);
157 | }
158 |
159 | } catch (Exception e) {
160 | e.printStackTrace();
161 | }
162 | }
163 |
164 | public void remindStoragePermissions(Activity activity) {
165 |
166 | try {
167 | //检测是否有写的权限
168 | int permission = ActivityCompat.checkSelfPermission(activity,
169 | "android.permission.WRITE_EXTERNAL_STORAGE");
170 | if (permission != PackageManager.PERMISSION_GRANTED) {
171 | // 没有写的权限,去申请写的权限,会弹出对话框
172 | Snackbar.make (toolbar,"未授予存储权限,将无法下载书籍!",Snackbar.LENGTH_LONG).show ();
173 | }else {
174 | hasPermissions = true;
175 | }
176 | } catch (Exception e) {
177 | e.printStackTrace();
178 | }
179 | }
180 |
181 | @Override
182 | public void onDataSuccessfully(Object data) {
183 |
184 | }
185 |
186 | @Override
187 | public void onDataSuccessfully(DownloadDetails downloadDetails) {
188 | this.downloadDetails = downloadDetails;
189 | chapterIDs = downloadDetails.getChapterIDs ();
190 | allNum = chapterIDs.size ();
191 | du.setAllNum (allNum);
192 | for (int[] integers: SplitUtil.splitChaIDsByNum (downloadDetails.getChapterIDs (),3)){
193 | new DownloadTask (downloadDetails.getBookID (),
194 | ch,
195 | du,
196 | allNum,
197 | nowNum,
198 | whatGenerate,
199 | this)
200 | .executeOnExecutor (THREAD_POOL_EXECUTOR,integers);
201 | }
202 | }
203 |
204 | @Override
205 | public void onDataFailed() {
206 |
207 | }
208 |
209 | @Override
210 | public void onDownloadFinishedNum(int num){
211 | nowNum+=num;
212 | List chapters = new ArrayList<> ();
213 | if (nowNum>=allNum){
214 | du.setDialogTitle ("正在写出数据……");
215 | for (int id:chapterIDs){
216 | chapters.add (ch.get (id));
217 | }
218 | switch (whatGenerate){
219 | case 0:
220 | StringBuilder sb = new StringBuilder ();
221 | for (String s:chapters){
222 | sb.append (s);
223 | }
224 | new OutPutTxtTask (downloadDetails.getBookName (),this).execute (sb.toString ());
225 | break;
226 | case 1:
227 | new EpubUtils (downloadDetails.getBookID (),
228 | downloadDetails.getBookName (),
229 | downloadDetails.getBookAuthor (),
230 | downloadDetails.getBookCoverURL (),
231 | chapters,
232 | downloadDetails.getTitles (),
233 | this).generateEpub ();
234 | break;
235 | case 2:
236 | NOBKit.Builder builder = new NOBKit
237 | .Builder (Environment.getExternalStorageDirectory().getPath()+"/99lib/Nob")
238 | .cover (cover_bit)
239 | .metadata (downloadDetails.getBookName (), downloadDetails.getBookAuthor ().replace ("作者: ",""))
240 | .putChapters (downloadDetails.getTitles (),chapters);
241 | isGenerOk (1);
242 | builder.build (downloadDetails.getBookName ());
243 | break;
244 | }
245 | }
246 | }
247 |
248 | @Override
249 | public boolean onOptionsItemSelected(MenuItem item) {
250 | if(item.getItemId()==android.R.id.home){
251 | finish ();
252 | return true;
253 | }
254 | return super.onOptionsItemSelected(item);
255 | }
256 |
257 | public void scanFile() {
258 | final Intent scanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
259 | final Uri contentUri = Uri.fromFile(new File (Environment.getExternalStorageDirectory().getPath()+"/99lib/Nob/"+downloadDetails.getBookName ()+".nob"));
260 | scanIntent.setData(contentUri);
261 | sendBroadcast(scanIntent);
262 | }
263 |
264 | @Override
265 | public void isGenerOk(int i) {
266 | if (i==1){
267 | du.concelDialog ();
268 | scanFile ();
269 | Snackbar.make (toolbar,"书籍下载完毕!",Snackbar.LENGTH_LONG).show ();
270 | }
271 | }
272 |
273 | @Override
274 | public void GetFailed() {
275 | refreshLayout.finishRefresh (false);
276 | Snackbar.make (toolbar,"数据获取失败,请检查网络连接或重试",Snackbar.LENGTH_LONG).show ();
277 | }
278 |
279 | @Override
280 | public void GetSuccessful(String...strings) {
281 | tv_title.setText (strings[0]);
282 | tv_intro.setText (strings[1]);
283 | tv_detail.setText (strings[2]);
284 | searchStr = strings[4];
285 | Glide.with(BookDetailActivity.this).load(strings[3]).into(iv_cover);
286 | new SetCoverTask (new Interface.GetCover () {
287 | @Override
288 | public void GetCoverOK(Bitmap bitmap) {
289 | cover_bit = bitmap;
290 | iv_cover.setImageBitmap (bitmap);
291 | }
292 | }).execute (strings[3]);
293 | cv.setVisibility (View.VISIBLE);
294 | cv.bringToFront ();
295 | refreshLayout.finishRefresh (500);
296 | }
297 |
298 | GetBookDetailTask gbd;
299 |
300 | @Override
301 | public void onRefresh(RefreshLayout refreshlayout) {
302 | gbd = new GetBookDetailTask (this);
303 | gbd.execute (url);
304 | }
305 |
306 | @Override
307 | public void outPutFailed() {
308 |
309 | }
310 |
311 | @Override
312 | public void outPutSuccess(int i) {
313 | switch (i){
314 | case 1:
315 | du.concelDialog ();
316 | Snackbar.make (toolbar,"书籍下载完毕!",Snackbar.LENGTH_LONG).show ();
317 | break;
318 | }
319 | }
320 |
321 | @Override
322 | protected void onDestroy(){
323 | if (gbd != null && gbd.getStatus() != AsyncTask.Status.FINISHED)
324 | gbd.cancel(true);
325 | super.onDestroy();
326 | }
327 |
328 | @Override
329 | protected void onActivityResult(int requestCode, int resultCode, Intent data) {
330 | super.onActivityResult(requestCode, resultCode, data);
331 | tv_dlNob.setOnClickListener (null);
332 | tv_dlNob.setText ("请稍后");
333 | if (data!=null) {
334 | Glide.with (BookDetailActivity.this).load (data.getStringExtra ("url")).into (iv_cover);
335 | new SetCoverTask (new Interface.GetCover () {
336 | @Override
337 | public void GetCoverOK(Bitmap bitmap) {
338 | cover_bit = bitmap;
339 | tv_dlNob.setText ("Nob下载");
340 | tv_dlNob.setOnClickListener (BookDetailActivity.this);
341 | }
342 | }).execute (data.getStringExtra ("url"));
343 | }else {
344 | tv_dlNob.setText ("Nob下载");
345 | tv_dlNob.setOnClickListener (BookDetailActivity.this);
346 | }
347 | }
348 | }
349 |
--------------------------------------------------------------------------------
/app/src/main/java/cc/zsakvo/ninecswd/CategoryActivity.java:
--------------------------------------------------------------------------------
1 | package cc.zsakvo.ninecswd;
2 |
3 | import android.content.Intent;
4 | import android.os.Bundle;
5 | import android.support.design.widget.FloatingActionButton;
6 | import android.support.design.widget.Snackbar;
7 | import android.support.v7.app.AppCompatActivity;
8 | import android.support.v7.widget.LinearLayoutManager;
9 | import android.support.v7.widget.RecyclerView;
10 | import android.support.v7.widget.Toolbar;
11 | import android.view.MenuItem;
12 | import android.view.View;
13 |
14 | import com.scwang.smartrefresh.header.MaterialHeader;
15 | import com.scwang.smartrefresh.layout.api.RefreshLayout;
16 | import com.scwang.smartrefresh.layout.listener.OnLoadmoreListener;
17 | import com.scwang.smartrefresh.layout.listener.OnRefreshListener;
18 |
19 | import java.util.ArrayList;
20 | import java.util.List;
21 |
22 | import cc.zsakvo.ninecswd.classes.BookList;
23 | import cc.zsakvo.ninecswd.listener.Interface;
24 | import cc.zsakvo.ninecswd.listener.ItemClickListener;
25 | import cc.zsakvo.ninecswd.task.GetCategoryListTask;
26 | import cc.zsakvo.ninecswd.adapter.ListAdapter;
27 |
28 |
29 | public class CategoryActivity extends AppCompatActivity implements ItemClickListener,View.OnClickListener,OnRefreshListener,OnLoadmoreListener,Interface.GetCategoryList{
30 |
31 | private RecyclerView recyclerView;
32 | Toolbar toolbar;
33 | FloatingActionButton fab;
34 | private List listDetails = new ArrayList<>();
35 | ListAdapter adapter;
36 | int page =1;
37 | String searchStr;
38 | Boolean isInit;
39 | int totalPage = 1;
40 | String str;
41 | String baseUrl = "http://www.99lib.net/book/index.php?type=";
42 | String Url;
43 | RefreshLayout refreshLayout;
44 |
45 | @Override
46 | protected void onCreate(Bundle savedInstanceState) {
47 | super.onCreate(savedInstanceState);
48 | setContentView(R.layout.activity_category);
49 | this.str = getIntent().getStringExtra("url");
50 | toolbar = (Toolbar)findViewById(R.id.c_toolBar);
51 | // fab = (FloatingActionButton)findViewById(R.id.c_fab);
52 | toolbar.setTitle(str);
53 | // fab.setOnClickListener(this);
54 | setSupportActionBar(toolbar);
55 | toolbar.setTitle("分类目录");
56 | if (getSupportActionBar() != null) {
57 | getSupportActionBar ().setDisplayHomeAsUpEnabled (true);
58 | }
59 | recyclerView = (RecyclerView)findViewById(R.id.c_novel_list);
60 | LinearLayoutManager layoutManager = new LinearLayoutManager(this);
61 | recyclerView.setLayoutManager(layoutManager);
62 | adapter = new ListAdapter (listDetails);
63 | adapter.setOnItemClickListener(CategoryActivity.this);
64 | recyclerView.setAdapter(adapter);
65 | refreshLayout = (RefreshLayout)findViewById(R.id.c_refreshLayout);
66 | refreshLayout.setOnRefreshListener (this);
67 | refreshLayout.setOnLoadmoreListener (this);
68 | MaterialHeader mMaterialHeader = (MaterialHeader) refreshLayout.getRefreshHeader ();
69 | refreshLayout.autoRefresh ();
70 | }
71 |
72 | private void initView(){
73 |
74 | }
75 |
76 | @Override
77 | public void onResume(){
78 | super.onResume();
79 | }
80 |
81 | private void searchBook(){
82 | toolbar.setTitle(str);
83 | Url = baseUrl+str+"&page="+page;
84 | GetCategoryListTask gct = new GetCategoryListTask (totalPage, listDetails, adapter,this);
85 | gct.execute (Url,page);
86 | }
87 |
88 | @Override
89 | public void onItemClick(View view,final int position){
90 | String url = String.valueOf(listDetails.get(position).getBook_url());
91 | Intent intent = new Intent(CategoryActivity.this, BookDetailActivity.class);
92 | intent.putExtra("url", url);
93 | startActivity(intent);
94 | }
95 |
96 | @Override
97 | public void onClick(View view) {
98 | switch (view.getId()){
99 | // case R.id.c_fab:
100 | // adapter = new ListAdapter(listDetails);
101 | // adapter.setOnItemClickListener(CategoryActivity.this);
102 | // recyclerView.setAdapter(adapter);
103 | // break;
104 | default:
105 | break;
106 | }
107 | }
108 |
109 | @Override
110 | public boolean onOptionsItemSelected(MenuItem item) {
111 | if(item.getItemId()==android.R.id.home){
112 | finish ();
113 | return true;
114 | }
115 | return super.onOptionsItemSelected(item);
116 | }
117 |
118 | @Override
119 | public void onLoadmore(RefreshLayout refreshlayout) {
120 | page++;
121 | searchBook();
122 | }
123 |
124 | @Override
125 | public void onRefresh(RefreshLayout refreshlayout) {
126 | listDetails.clear ();
127 | recyclerView.setAdapter (adapter);
128 | page = 1;
129 | searchBook();
130 | }
131 |
132 | @Override
133 | public void GetOK(List listDetails) {
134 | this.listDetails.addAll (listDetails);
135 | adapter.notifyDataSetChanged();
136 | if (refreshLayout.isRefreshing ()){
137 | refreshLayout.finishRefresh (500);
138 | }else {
139 | refreshLayout.finishLoadmore (500);
140 | }
141 | }
142 |
143 | @Override
144 | public void GetFailed() {
145 | refreshLayout.finishLoadmoreWithNoMoreData ();
146 | if (refreshLayout.isRefreshing ()){
147 | refreshLayout.finishRefresh (false);
148 | }else {
149 | refreshLayout.finishLoadmore (false);
150 | }
151 | Snackbar.make (recyclerView,"数据获取失败,请检查网络连接或重试",Snackbar.LENGTH_LONG).show ();
152 | }
153 | }
154 |
--------------------------------------------------------------------------------
/app/src/main/java/cc/zsakvo/ninecswd/ChangeCoverActivity.java:
--------------------------------------------------------------------------------
1 | package cc.zsakvo.ninecswd;
2 |
3 | import android.content.DialogInterface;
4 | import android.content.Intent;
5 | import android.support.design.widget.Snackbar;
6 | import android.support.v7.app.AlertDialog;
7 | import android.support.v7.app.AppCompatActivity;
8 | import android.os.Bundle;
9 | import android.support.v7.widget.RecyclerView;
10 | import android.support.v7.widget.StaggeredGridLayoutManager;
11 | import android.support.v7.widget.Toolbar;
12 | import android.util.Log;
13 | import android.view.Menu;
14 | import android.view.MenuItem;
15 | import android.view.View;
16 | import android.widget.Toast;
17 |
18 | import java.util.ArrayList;
19 | import java.util.List;
20 |
21 | import cc.zsakvo.ninecswd.adapter.CoverListAdapter;
22 | import cc.zsakvo.ninecswd.listener.Interface;
23 | import cc.zsakvo.ninecswd.listener.ItemClickListener;
24 | import cc.zsakvo.ninecswd.task.GetCoversTask;
25 |
26 | public class ChangeCoverActivity extends AppCompatActivity implements Interface.GetCoverUrls,ItemClickListener{
27 |
28 | // public enum Engine {
29 | // Bing,
30 | // Baidu,
31 | // Sogou
32 | // }
33 |
34 | Toolbar toolbar;
35 | String[] engine = new String[]{"Bing","Baidu"};
36 | private String searchStr;
37 | private String searchEngine = "Baidu";
38 | private RecyclerView recyclerView;
39 | private CoverListAdapter adapter;
40 | private List list = new ArrayList<> ();
41 |
42 | @Override
43 | protected void onCreate(Bundle savedInstanceState) {
44 | super.onCreate (savedInstanceState);
45 | setContentView (R.layout.activity_change_cover);
46 | toolbar = (Toolbar)findViewById (R.id.ccToolBar);
47 | toolbar.setTitle ("选择封面");
48 | recyclerView = (RecyclerView)findViewById (R.id.cover_recycler);
49 | setSupportActionBar (toolbar);
50 | if (getSupportActionBar ()!=null){
51 | getSupportActionBar ().setDisplayHomeAsUpEnabled (true);
52 | }
53 | searchStr = getIntent ().getStringExtra ("str");
54 | StaggeredGridLayoutManager layoutManager = new
55 | StaggeredGridLayoutManager(3,StaggeredGridLayoutManager.VERTICAL);
56 | recyclerView.setLayoutManager(layoutManager);
57 | adapter = new CoverListAdapter (list);
58 | adapter.setOnItemClickListener (this);
59 | recyclerView.setAdapter(adapter);
60 | new GetCoversTask (this).execute (searchStr,searchEngine);
61 | }
62 |
63 | @Override
64 | public boolean onCreateOptionsMenu(Menu menu){
65 | getMenuInflater().inflate(R.menu.select_engine_menu,menu);
66 | return true;
67 | }
68 |
69 | @Override
70 | public boolean onOptionsItemSelected(final MenuItem item) {
71 | if(item.getItemId()==android.R.id.home){
72 | finish ();
73 | return true;
74 | }
75 | switch (item.getItemId ()){
76 | case android.R.id.home:
77 | finish ();
78 | break;
79 | case R.id.select_engine:
80 | AlertDialog dialog = new AlertDialog.Builder(this).setTitle("选择搜索引擎")
81 | .setItems(engine, new DialogInterface.OnClickListener () {
82 | @Override
83 | public void onClick(DialogInterface dialog, int which) {
84 | list.clear ();
85 | switch (engine[which]){
86 | case "Bing":
87 | item.setIcon (R.drawable.ic_bing);
88 | searchEngine = "Bing";
89 | new GetCoversTask (ChangeCoverActivity.this).execute (searchStr,searchEngine);
90 | break;
91 | case "Baidu":
92 | item.setIcon (R.drawable.ic_baidu);
93 | searchEngine = "Baidu";
94 | new GetCoversTask (ChangeCoverActivity.this).execute (searchStr,searchEngine);
95 | break;
96 | // case "Sogou":
97 | // item.setIcon (R.drawable.ic_bing);
98 | // searchEngine = "Sogou";
99 | // new GetCoversTask (ChangeCoverActivity.this).execute (searchStr,searchEngine);
100 | // break;
101 | default:
102 | break;
103 | }
104 | }
105 | }).create();
106 | dialog.show();
107 | break;
108 | }
109 | return super.onOptionsItemSelected(item);
110 | }
111 |
112 | @Override
113 | public void GetCoverUrls(List list) {
114 | if (list.size ()==0){
115 | Snackbar.make (recyclerView,"没有找到合适的图片!",Snackbar.LENGTH_LONG).show ();
116 | }else {
117 | this.list.addAll (list);
118 | adapter.notifyDataSetChanged ();
119 | }
120 | }
121 |
122 | @Override
123 | public void GetCoverUrlsFailed() {
124 |
125 | }
126 |
127 | @Override
128 | public void onItemClick(View view, int postion) {
129 | Intent intent = new Intent ();
130 | intent.putExtra ("url",list.get (postion));
131 | setResult(1, intent);
132 | finish();
133 | }
134 |
135 | @Override
136 | public void onBackPressed(){
137 | super.onBackPressed ();
138 | }
139 | }
140 |
--------------------------------------------------------------------------------
/app/src/main/java/cc/zsakvo/ninecswd/MainActivity.java:
--------------------------------------------------------------------------------
1 | package cc.zsakvo.ninecswd;
2 |
3 | import android.content.Intent;
4 | import android.os.Bundle;
5 | import android.support.design.widget.Snackbar;
6 | import android.support.design.widget.TabLayout;
7 | import android.support.v4.view.ViewPager;
8 | import android.support.v7.app.AppCompatActivity;
9 | import android.support.v7.widget.Toolbar;
10 | import android.view.KeyEvent;
11 | import android.view.Menu;
12 | import android.view.MenuItem;
13 |
14 | import com.github.nukc.stateview.StateView;
15 |
16 | import cc.zsakvo.ninecswd.adapter.MyViewpagerAdapter;
17 | import cc.zsakvo.ninecswd.fragment.ArticleFragment;
18 | import cc.zsakvo.ninecswd.fragment.BaseFragment;
19 | import cc.zsakvo.ninecswd.fragment.BookStoreFragment;
20 | import cc.zsakvo.ninecswd.fragment.CategoryFragment;
21 | import km.lmy.searchview.SearchView;
22 |
23 |
24 | public class MainActivity extends AppCompatActivity{
25 | TabLayout tabLayout;
26 | ViewPager viewPager;
27 | String[] mTitle;
28 | BaseFragment[] mBaseFragment;
29 | Toolbar toolbar;
30 | SearchView searchView;
31 | MyViewpagerAdapter mMyViewpagerAdapter;
32 | private long firstClick;
33 |
34 | @Override
35 | protected void onCreate(Bundle savedInstanceState) {
36 | super.onCreate(savedInstanceState);
37 | setContentView(R.layout.activity_main);
38 | toolbar = (Toolbar)findViewById(R.id.toolBar);
39 | searchView=(SearchView)findViewById(R.id.searchView);
40 | setSupportActionBar(toolbar);
41 | initView();
42 | initDatas();
43 | initListener();
44 | }
45 |
46 |
47 | public boolean onCreateOptionsMenu(Menu menu){
48 | getMenuInflater().inflate(R.menu.main_menu,menu);
49 | return true;
50 | }
51 |
52 | @Override
53 | public boolean onOptionsItemSelected(MenuItem item){
54 | switch (item.getItemId()){
55 | case R.id.m_search:
56 | startActivity(new Intent(MainActivity.this,SearchActivity.class));
57 | break;
58 | // case R.id.m_setting:
59 | // Snackbar.make(toolbar,"设置",Snackbar.LENGTH_LONG).show();
60 | // break;
61 | // case R.id.m_about:
62 | // Snackbar.make(toolbar,"关于程序",Snackbar.LENGTH_LONG).show();
63 | // StateView mStateView = StateView.inject(this);
64 | // mStateView.setRetryResource (R.layout.layout_retry);
65 | // break;
66 | }
67 | return true;
68 | }
69 |
70 | private void initView() {
71 | tabLayout = (TabLayout) findViewById(R.id.tabLayout);
72 | viewPager = (ViewPager) findViewById(R.id.vp_content);
73 | }
74 |
75 | private void initDatas() {
76 |
77 | //为标题赋值
78 | mTitle = new String[]{
79 | "书库",
80 | "分类",
81 | "文库"
82 | };
83 | mBaseFragment = new BaseFragment[]{
84 | new BookStoreFragment(),
85 | new CategoryFragment (),
86 | new ArticleFragment()
87 | };
88 |
89 | setTabAndViewPager();
90 | }
91 |
92 | private void setTabAndViewPager() {
93 | mMyViewpagerAdapter = new MyViewpagerAdapter(getSupportFragmentManager(),mTitle);
94 | viewPager.setAdapter(mMyViewpagerAdapter);
95 | viewPager.setOffscreenPageLimit(0);
96 | tabLayout.setupWithViewPager(viewPager,true);
97 | }
98 |
99 | private void initListener() {
100 |
101 | }
102 |
103 | @Override
104 | public boolean onKeyDown(int keyCode, KeyEvent event) {
105 | // TODO Auto-generated method stub
106 | if(keyCode== KeyEvent.KEYCODE_BACK){
107 | if(System.currentTimeMillis()-firstClick>2000){
108 | firstClick=System.currentTimeMillis();
109 | Snackbar.make(toolbar,"再按一次退出",Snackbar.LENGTH_LONG).show();
110 | }else{
111 | System.exit(0);
112 | }
113 | return true;
114 | }
115 | return false;
116 | }
117 | }
--------------------------------------------------------------------------------
/app/src/main/java/cc/zsakvo/ninecswd/SearchActivity.java:
--------------------------------------------------------------------------------
1 | package cc.zsakvo.ninecswd;
2 |
3 | import android.content.Intent;
4 | import android.support.design.widget.FloatingActionButton;
5 | import android.support.design.widget.Snackbar;
6 | import android.support.v7.app.AppCompatActivity;
7 | import android.os.Bundle;
8 | import android.support.v7.widget.LinearLayoutManager;
9 | import android.support.v7.widget.RecyclerView;
10 | import android.support.v7.widget.Toolbar;
11 | import android.util.Log;
12 | import android.view.Menu;
13 | import android.view.MenuItem;
14 | import android.view.View;
15 |
16 | import com.github.nukc.stateview.StateView;
17 | import com.scwang.smartrefresh.header.MaterialHeader;
18 | import com.scwang.smartrefresh.layout.api.RefreshLayout;
19 | import com.scwang.smartrefresh.layout.listener.OnLoadmoreListener;
20 | import com.scwang.smartrefresh.layout.listener.OnRefreshListener;
21 |
22 | import java.util.ArrayList;
23 | import java.util.List;
24 |
25 | import cc.zsakvo.ninecswd.classes.BookList;
26 | import cc.zsakvo.ninecswd.listener.Interface;
27 | import cc.zsakvo.ninecswd.listener.ItemClickListener;
28 | import cc.zsakvo.ninecswd.task.GetSearchListTask;
29 | import cc.zsakvo.ninecswd.adapter.ListAdapter;
30 | import km.lmy.searchview.SearchView;
31 |
32 |
33 | public class SearchActivity extends AppCompatActivity implements ItemClickListener,View.OnClickListener,Interface.GetSearch,OnRefreshListener,OnLoadmoreListener{
34 |
35 | private RecyclerView recyclerView;
36 | private StateView mStateView;
37 | SearchView searchView;
38 | Toolbar toolbar;
39 | FloatingActionButton fab;
40 | private List listDetails = new ArrayList<>();
41 | ListAdapter adapter;
42 | int page;
43 | String searchStr;
44 | Boolean isInit;
45 | int totalPage = 1;
46 | RefreshLayout refreshLayout;
47 |
48 | @Override
49 | protected void onCreate(Bundle savedInstanceState) {
50 | super.onCreate(savedInstanceState);
51 | setContentView(R.layout.activity_search);
52 | toolbar = (Toolbar)findViewById(R.id.s_toolBar);
53 | searchView = (SearchView)findViewById(R.id.s_searchView);
54 | // fab = (FloatingActionButton)findViewById(R.id.s_fab);
55 | // fab.setOnClickListener(this);
56 | setSupportActionBar(toolbar);
57 | toolbar.setTitle("搜索书籍");
58 | setSupportActionBar(toolbar);
59 | if (getSupportActionBar() != null) {
60 | getSupportActionBar ().setDisplayHomeAsUpEnabled (true);
61 | }
62 | // mStateView = StateView.inject(findViewById (R.id.coord));
63 | recyclerView = (RecyclerView)findViewById(R.id.s_novel_list);
64 | LinearLayoutManager layoutManager = new LinearLayoutManager(this);
65 | recyclerView.setLayoutManager(layoutManager);
66 | recyclerView.removeAllViewsInLayout();
67 | adapter = new ListAdapter (listDetails);
68 | adapter.setOnItemClickListener(SearchActivity.this);
69 | recyclerView.setAdapter(adapter);
70 | refreshLayout = (RefreshLayout)findViewById(R.id.s_refreshLayout);
71 | refreshLayout.setOnRefreshListener(this);
72 | refreshLayout.setOnLoadmoreListener(this);
73 | MaterialHeader mMaterialHeader = (MaterialHeader) refreshLayout.getRefreshHeader ();
74 | searchView.defaultState (SearchView.OPEN);
75 | }
76 |
77 | private void initView(){
78 |
79 | }
80 |
81 | @Override
82 | public void onResume(){
83 | super.onResume();
84 | initSearchView();
85 | }
86 |
87 | @Override
88 | public boolean onCreateOptionsMenu(Menu menu){
89 | getMenuInflater().inflate(R.menu.search_menu,menu);
90 | return true;
91 | }
92 |
93 | @Override
94 | public boolean onPrepareOptionsMenu(Menu menu){
95 | // searchView.open ();
96 | return true;
97 | }
98 |
99 |
100 | @Override
101 | public boolean onOptionsItemSelected(MenuItem item){
102 | switch (item.getItemId()){
103 | case R.id.s_search:
104 | searchView.autoOpenOrClose();
105 | break;
106 | case android.R.id.home:
107 | finish ();
108 | break;
109 | }
110 | return true;
111 | }
112 |
113 | private void initSearchView(){
114 | searchView.setHintText ("请输入关键字,如 人间椅子");
115 | // searchView.setSearchEditText ("我的");
116 | searchView.setHistoryItemClickListener(new SearchView.OnHistoryItemClickListener() {
117 | @Override
118 | public void onClick(String historyStr, int position) {
119 | searchView.close();
120 | searchStr = historyStr;
121 | page = 1;
122 | isInit = true;
123 | onRefresh (refreshLayout);
124 | }
125 | });
126 |
127 | //设置软键盘搜索按钮点击事件
128 | searchView.setOnSearchActionListener(new SearchView.OnSearchActionListener() {
129 | @Override
130 | public void onSearchAction(String searchText) {
131 | searchView.close();
132 | searchView.addOneHistory(searchText);
133 | page = 1;
134 | isInit = true;
135 | searchStr = searchText;
136 | onRefresh (refreshLayout);
137 | }
138 | });
139 | }
140 |
141 | private Boolean canSearch(String value) {
142 | Boolean hasEng=false;
143 | Boolean hasChi=false;
144 | Boolean result=false;
145 | int valueLength = 0;
146 | String chinese = "[\u0391-\uFFE5]";
147 | /* 获取字段值的长度,如果含中文字符,则每个中文字符长度为2,否则为1 */
148 | for (int i = 0; i < value.length(); i++) {
149 | /* 获取一个字符 */
150 | String temp = value.substring(i, i + 1);
151 | /* 判断是否为中文字符 */
152 | if (temp.matches(chinese)) {
153 | /* 中文字符长度为2 */
154 | valueLength += 2;
155 | hasChi = true;
156 | } else {
157 | /* 其他字符长度为1 */
158 | valueLength += 1;
159 | hasEng = true;
160 | }
161 | }
162 | if (hasChi&&hasEng){
163 | result = true;
164 | }else if (valueLength>=4){
165 | result = true;
166 | }
167 | return result;
168 | }
169 |
170 | private void searchBook(){
171 | if (!canSearch(searchStr)){
172 | Snackbar.make(toolbar,"搜索关键字不得少于2个中文或4个英文!",Snackbar.LENGTH_LONG).show();
173 | return;
174 | }
175 | toolbar.setTitle("搜索:"+searchStr);
176 | String url = "http://www.99lib.net/book/search.php?keyword="+searchStr+"&page="+page;
177 | GetSearchListTask gst = new GetSearchListTask (this);
178 | gst.execute (url,page);
179 | }
180 |
181 | @Override
182 | public void onBackPressed(){
183 | if (searchView.isOpen()){
184 | searchView.close();
185 | if (listDetails.size ()==0){
186 | super.onBackPressed ();
187 | }
188 | }else {
189 | super.onBackPressed();
190 | }
191 | }
192 |
193 | @Override
194 | public void onItemClick(View view,final int position){
195 | String url = String.valueOf(listDetails.get(position).getBook_url());
196 | Intent intent = new Intent(SearchActivity.this, BookDetailActivity.class);
197 | intent.putExtra("url", url);
198 | startActivity(intent);
199 | }
200 |
201 | @Override
202 | public void onClick(View view) {
203 | switch (view.getId()){
204 | // case R.id.s_fab:
205 | // adapter = new ListAdapter(listDetails);
206 | // adapter.setOnItemClickListener(SearchActivity.this);
207 | // recyclerView.setAdapter(adapter);
208 | // break;
209 | default:
210 | break;
211 | }
212 | }
213 |
214 | @Override
215 | public void GetOK(List listDetails,int totalPages) {
216 | this.listDetails.addAll (listDetails);
217 | if (totalPages!=0) {
218 | this.totalPage = totalPages;
219 | }
220 | adapter.notifyDataSetChanged();
221 | if (refreshLayout.isRefreshing ()){
222 | refreshLayout.finishRefresh (500);
223 | }else {
224 | refreshLayout.finishLoadmore (500);
225 | }
226 | }
227 |
228 | @Override
229 | public void GetFailed() {
230 | refreshLayout.finishLoadmoreWithNoMoreData ();
231 | if (refreshLayout.isRefreshing ()){
232 | refreshLayout.finishRefresh (false);
233 | }else {
234 | refreshLayout.finishLoadmore (false);
235 | }
236 | Snackbar.make (recyclerView,"数据获取失败,请检查网络连接或换个关键词~",Snackbar.LENGTH_LONG).show ();
237 | }
238 |
239 | @Override
240 | public void onLoadmore(RefreshLayout refreshlayout) {
241 | Log.e ("onLoadmore: ",page+"ppp"+totalPage );
242 | if (page>=totalPage){
243 | refreshLayout.finishLoadmoreWithNoMoreData ();
244 | Snackbar.make (recyclerView,"已经是最后一页了!",Snackbar.LENGTH_LONG).show ();
245 | }else {
246 | page++;
247 | searchBook();
248 | }
249 | }
250 |
251 | @Override
252 | public void onRefresh(RefreshLayout refreshlayout) {
253 | page = 1;
254 | listDetails.clear ();
255 | recyclerView.setAdapter (adapter);
256 | refreshlayout.resetNoMoreData ();
257 | searchBook();
258 | }
259 |
260 |
261 | }
262 |
--------------------------------------------------------------------------------
/app/src/main/java/cc/zsakvo/ninecswd/adapter/ArticleAdapter.java:
--------------------------------------------------------------------------------
1 | package cc.zsakvo.ninecswd.adapter;
2 |
3 | import android.support.v7.widget.RecyclerView;
4 | import android.view.LayoutInflater;
5 | import android.view.View;
6 | import android.view.ViewGroup;
7 | import android.widget.TextView;
8 |
9 |
10 | import java.util.List;
11 |
12 | import cc.zsakvo.ninecswd.R;
13 | import cc.zsakvo.ninecswd.classes.ArticleList;
14 | import cc.zsakvo.ninecswd.listener.ItemClickListener;
15 |
16 | /**
17 | * Created by akvo on 2018/2/19.
18 | */
19 |
20 | public class ArticleAdapter extends RecyclerView.Adapter{
21 |
22 | private List articleList;
23 | private ItemClickListener mItemClickListener;
24 |
25 | public ArticleAdapter(List articleList){
26 | this.articleList = articleList;
27 | }
28 |
29 | public void setOnItemClickListener(ItemClickListener listener){
30 | this.mItemClickListener = listener;
31 | }
32 |
33 | @Override
34 | public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
35 | View view = LayoutInflater.from(parent.getContext())
36 | .inflate(R.layout.articlelist,parent,false);
37 | ViewHolder holder = new ViewHolder(view,mItemClickListener);
38 | return holder;
39 | }
40 |
41 | @Override
42 | public void onBindViewHolder(ViewHolder holder, int position) {
43 | ArticleList listDetail = this.articleList.get(position);
44 | holder.tv_article_name.setText(listDetail.getArticleName());
45 | holder.tv_article_intro.setText(listDetail.getArticleAuthor());
46 | }
47 |
48 | @Override
49 | public int getItemCount() {
50 | return articleList.size();
51 | }
52 |
53 | static class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{
54 | private ItemClickListener mClickListener;
55 | TextView tv_article_name;
56 | TextView tv_article_intro;
57 |
58 | public ViewHolder(View view,ItemClickListener clickListener){
59 | super(view);
60 | this.mClickListener = clickListener;
61 | view.findViewById(R.id.alist).setOnClickListener(this);
62 | tv_article_name = view.findViewById(R.id.alist_name);
63 | tv_article_intro = view.findViewById(R.id.alist_intro);
64 | }
65 |
66 | @Override
67 | public void onClick(View v) {
68 | switch (v.getId()){
69 | case R.id.alist:
70 | if(mClickListener != null){
71 | mClickListener.onItemClick(v,getAdapterPosition());
72 | }
73 | break;
74 | default:
75 | break;
76 | }
77 | }
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/app/src/main/java/cc/zsakvo/ninecswd/adapter/CategoryAdapter.java:
--------------------------------------------------------------------------------
1 | package cc.zsakvo.ninecswd.adapter;
2 |
3 | import android.support.v7.widget.RecyclerView;
4 | import android.util.DisplayMetrics;
5 | import android.view.LayoutInflater;
6 | import android.view.View;
7 | import android.view.ViewGroup;
8 | import android.widget.TextView;
9 |
10 |
11 | import cc.zsakvo.ninecswd.R;
12 | import cc.zsakvo.ninecswd.listener.ItemClickListener;
13 |
14 | /**
15 | * Created by akvo on 2018/2/18.
16 | */
17 |
18 | public class CategoryAdapter extends RecyclerView.Adapter{
19 |
20 | private String[] categorys;
21 | private ItemClickListener mItemClickListener;
22 |
23 | @Override
24 | public CategoryAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
25 | View view = LayoutInflater.from(parent.getContext())
26 | .inflate(R.layout.categorylist,parent,false);
27 | CategoryAdapter.ViewHolder holder = new CategoryAdapter.ViewHolder(view,mItemClickListener);
28 | return holder;
29 | }
30 |
31 | @Override
32 | public void onBindViewHolder(CategoryAdapter.ViewHolder holder, int position) {
33 | String category = this.categorys[position];
34 | holder.tv.setText(category);
35 | }
36 |
37 | @Override
38 | public int getItemCount() {
39 | return this.categorys.length;
40 | }
41 |
42 | public void setOnItemClickListener(ItemClickListener listener){
43 | this.mItemClickListener = listener;
44 | }
45 |
46 | public CategoryAdapter(String[] categorys){
47 | this.categorys = categorys;
48 | }
49 |
50 | static class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{
51 | private ItemClickListener mClickListener;
52 | DisplayMetrics dm;
53 | TextView tv;
54 |
55 | public ViewHolder(View view,ItemClickListener clickListener){
56 | super(view);
57 | this.mClickListener = clickListener;
58 | view.findViewById(R.id.clist).setOnClickListener(this);
59 | dm = view.getContext().getResources().getDisplayMetrics();
60 | int a = dm.widthPixels;
61 | int b = dm.heightPixels;
62 | tv = (TextView) view.findViewById(R.id.category_t);
63 | tv.setHeight(b/11);
64 | tv.setWidth(a/3);
65 | }
66 |
67 | @Override
68 | public void onClick(View v) {
69 | switch (v.getId()){
70 | case R.id.clist:
71 | if(mClickListener != null){
72 | mClickListener.onItemClick(v,getAdapterPosition());
73 | }
74 | break;
75 | default:
76 | break;
77 | }
78 | }
79 | }
80 | }
81 |
--------------------------------------------------------------------------------
/app/src/main/java/cc/zsakvo/ninecswd/adapter/CoverListAdapter.java:
--------------------------------------------------------------------------------
1 | package cc.zsakvo.ninecswd.adapter;
2 |
3 | import android.support.v7.widget.RecyclerView;
4 | import android.util.DisplayMetrics;
5 | import android.util.Log;
6 | import android.view.LayoutInflater;
7 | import android.view.View;
8 | import android.view.ViewGroup;
9 | import android.widget.ImageView;
10 | import android.widget.TextView;
11 |
12 | import com.bumptech.glide.Glide;
13 |
14 | import java.util.List;
15 |
16 | import cc.zsakvo.ninecswd.BookDetailActivity;
17 | import cc.zsakvo.ninecswd.R;
18 | import cc.zsakvo.ninecswd.application.MyApplication;
19 | import cc.zsakvo.ninecswd.listener.ItemClickListener;
20 |
21 | /**
22 | * Created by akvo on 2018/3/31.
23 | */
24 |
25 | public class CoverListAdapter extends RecyclerView.Adapter {
26 |
27 | private ItemClickListener mItemClickListener;
28 | private List cover_url;
29 |
30 | @Override
31 | public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
32 | View view = LayoutInflater.from(parent.getContext())
33 | .inflate(R.layout.coverlist,parent,false);
34 | ViewHolder holder = new ViewHolder(view,mItemClickListener);
35 | return holder;
36 | }
37 |
38 | @Override
39 | public void onBindViewHolder(ViewHolder holder, int position) {
40 | String category = this.cover_url.get (position);
41 | try {
42 | Glide.with (MyApplication.getContext ()).load (category).into (holder.iv);
43 | }catch (Exception e){
44 | Glide.with (MyApplication.getContext ()).load (category).into (holder.iv);
45 | }
46 | }
47 |
48 |
49 | @Override
50 | public int getItemCount() {
51 | return this.cover_url.size ();
52 | }
53 |
54 | public void setOnItemClickListener(ItemClickListener listener){
55 | this.mItemClickListener = listener;
56 | }
57 |
58 | public CoverListAdapter(List cover_url){
59 | this.cover_url = cover_url;
60 | }
61 |
62 | static class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{
63 | private ItemClickListener mClickListener;
64 | DisplayMetrics dm;
65 | ImageView iv;
66 |
67 | public ViewHolder(View view,ItemClickListener clickListener){
68 | super(view);
69 | this.mClickListener = clickListener;
70 | view.findViewById(R.id.cover_list).setOnClickListener(this);
71 | dm = view.getContext().getResources().getDisplayMetrics();
72 | int a = dm.widthPixels;
73 | int b = dm.heightPixels;
74 | iv = (ImageView) view.findViewById(R.id.cover_t);
75 | ViewGroup.LayoutParams para = iv.getLayoutParams();
76 | float width = (a-96)/3;
77 | para.width = (int)width;
78 | para.height = (int)(width*1.435F);
79 | iv.setLayoutParams (para);
80 | }
81 |
82 | @Override
83 | public void onClick(View v) {
84 | switch (v.getId()){
85 | case R.id.cover_list:
86 | if(mClickListener != null){
87 | mClickListener.onItemClick(v,getAdapterPosition());
88 | }
89 | break;
90 | default:
91 | break;
92 | }
93 | }
94 | }
95 | }
96 |
--------------------------------------------------------------------------------
/app/src/main/java/cc/zsakvo/ninecswd/adapter/ListAdapter.java:
--------------------------------------------------------------------------------
1 | package cc.zsakvo.ninecswd.adapter;
2 |
3 | import android.support.v7.widget.RecyclerView;
4 | import android.view.LayoutInflater;
5 | import android.view.View;
6 | import android.view.ViewGroup;
7 | import android.widget.TextView;
8 |
9 | import java.util.List;
10 |
11 | import cc.zsakvo.ninecswd.R;
12 | import cc.zsakvo.ninecswd.classes.BookList;
13 | import cc.zsakvo.ninecswd.listener.ItemClickListener;
14 |
15 |
16 | /**
17 | * Created by akvo on 2018/2/9.
18 | */
19 |
20 | public class ListAdapter extends RecyclerView.Adapter {
21 |
22 | private List novelList;
23 | private ItemClickListener mItemClickListener;
24 |
25 | public void setOnItemClickListener(ItemClickListener listener){
26 | this.mItemClickListener = listener;
27 | }
28 |
29 | static class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{
30 | private ItemClickListener mClickListener;
31 | TextView tv_book_name;
32 | TextView tv_book_intro;
33 | TextView tv_book_detail;
34 | public ViewHolder(View view,ItemClickListener clickListener){
35 | super(view);
36 | this.mClickListener = clickListener;
37 | view.findViewById(R.id.blist).setOnClickListener(this);
38 | tv_book_name = (TextView)view.findViewById(R.id.blist_name);
39 | tv_book_intro = (TextView)view.findViewById(R.id.blist_intro);
40 | tv_book_detail = (TextView)view.findViewById(R.id.blist_detail);
41 | }
42 |
43 | @Override
44 | public void onClick(View v) {
45 | switch (v.getId()){
46 | case R.id.blist:
47 | if(mClickListener != null){
48 | mClickListener.onItemClick(v,getAdapterPosition());
49 | }
50 | break;
51 | default:
52 | break;
53 | }
54 | }
55 | }
56 |
57 | public ListAdapter(List novelList){
58 | this.novelList = novelList;
59 | }
60 |
61 | @Override
62 | public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType){
63 | View view = LayoutInflater.from(parent.getContext())
64 | .inflate(R.layout.booklist,parent,false);
65 | ViewHolder holder = new ViewHolder(view,mItemClickListener);
66 | return holder;
67 | }
68 |
69 | @Override
70 | public void onBindViewHolder(ViewHolder holder,int position){
71 | BookList listDetail = this.novelList.get(position);
72 | holder.tv_book_intro.setText(listDetail.getList_intro());
73 | holder.tv_book_name.setText(listDetail.getList_name());
74 | holder.tv_book_detail.setText(listDetail.getList_detail());
75 | }
76 |
77 | @Override
78 | public int getItemCount(){
79 | return this.novelList.size();
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/app/src/main/java/cc/zsakvo/ninecswd/adapter/MyViewpagerAdapter.java:
--------------------------------------------------------------------------------
1 | package cc.zsakvo.ninecswd.adapter;
2 |
3 | import android.support.v4.app.Fragment;
4 | import android.support.v4.app.FragmentManager;
5 | import android.support.v4.app.FragmentStatePagerAdapter;
6 |
7 | import cc.zsakvo.ninecswd.fragment.ArticleFragment;
8 | import cc.zsakvo.ninecswd.fragment.BookStoreFragment;
9 | import cc.zsakvo.ninecswd.fragment.CategoryFragment;
10 |
11 |
12 | public class MyViewpagerAdapter extends FragmentStatePagerAdapter {
13 |
14 | String[] mTabTitles;
15 |
16 |
17 | public MyViewpagerAdapter(FragmentManager fm, String[] titles) {
18 | super(fm);
19 | mTabTitles = titles;
20 |
21 | }
22 |
23 | @Override
24 | public Fragment getItem(int position) {
25 | Fragment fragment = null;
26 | switch(position) {
27 | case 0:
28 | fragment = BookStoreFragment.newInstance(position);
29 | break;
30 | case 1:
31 | fragment = CategoryFragment.newInstance(position);
32 | break;
33 | case 2:
34 | fragment = ArticleFragment.newInstance(position);
35 | break;
36 | case 3:
37 | break;
38 | }
39 | return fragment;
40 | }
41 |
42 | @Override
43 | public int getCount() {
44 | return mTabTitles.length;
45 | }
46 |
47 | @Override
48 | public CharSequence getPageTitle(int position) {
49 |
50 | return mTabTitles[position];
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/app/src/main/java/cc/zsakvo/ninecswd/application/MyApplication.java:
--------------------------------------------------------------------------------
1 | package cc.zsakvo.ninecswd.application;
2 |
3 | import android.app.Application;
4 | import android.content.Context;
5 |
6 | /**
7 | * Created by akvo on 2018/2/22.
8 | */
9 |
10 | public class MyApplication extends Application {
11 | private static Context context;
12 |
13 | @Override
14 | public void onCreate() {
15 | super.onCreate ();
16 | context = getApplicationContext ();
17 | }
18 |
19 | public static Context getContext(){
20 | return context;
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/app/src/main/java/cc/zsakvo/ninecswd/classes/ArticleList.java:
--------------------------------------------------------------------------------
1 | package cc.zsakvo.ninecswd.classes;
2 |
3 | /**
4 | * Created by akvo on 2018/2/19.
5 | */
6 |
7 | public class ArticleList {
8 | public String getArticleName() {
9 | return articleName;
10 | }
11 |
12 | public String getArticleAuthor() {
13 | return articleAuthor;
14 | }
15 |
16 | private String articleName;
17 | private String articleAuthor;
18 |
19 | public String getArticleUrl() {
20 | return articleUrl;
21 | }
22 |
23 | private String articleUrl;
24 | public ArticleList(String articleName,String articleAuthor,String articleUrl){
25 | this.articleName = articleName;
26 | this.articleAuthor = articleAuthor;
27 | this.articleUrl = articleUrl;
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/app/src/main/java/cc/zsakvo/ninecswd/classes/BookDetails.java:
--------------------------------------------------------------------------------
1 | package cc.zsakvo.ninecswd.classes;
2 |
3 | /**
4 | * Created by akvo on 2018/3/19.
5 | */
6 |
7 | public class BookDetails {
8 |
9 | }
10 |
--------------------------------------------------------------------------------
/app/src/main/java/cc/zsakvo/ninecswd/classes/BookList.java:
--------------------------------------------------------------------------------
1 | package cc.zsakvo.ninecswd.classes;
2 |
3 | /**
4 | * Created by akvo on 2018/2/9.
5 | */
6 |
7 | public class BookList {
8 | private String book_name;
9 | private String book_intro;
10 | private String book_detail;
11 |
12 | public String getBook_url() {
13 | return book_url;
14 | }
15 |
16 | private String book_url;
17 |
18 | public String getList_name() {
19 | return book_name;
20 | }
21 |
22 | public String getList_intro() {
23 | return book_intro;
24 | }
25 |
26 | public String getList_detail() {
27 | return book_detail;
28 | }
29 |
30 | public BookList(String book_name, String book_intro, String book_detail,String book_url){
31 | this.book_name = book_name;
32 | this.book_intro = book_intro;
33 | this.book_detail = book_detail;
34 | this.book_url = book_url;
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/app/src/main/java/cc/zsakvo/ninecswd/classes/DownloadDetails.java:
--------------------------------------------------------------------------------
1 | package cc.zsakvo.ninecswd.classes;
2 |
3 | import java.util.List;
4 |
5 | /**
6 | * Created by akvo on 2018/3/17.
7 | */
8 |
9 | public class DownloadDetails {
10 |
11 | public String getBookID() {
12 | return bookID;
13 | }
14 |
15 | public String getBookName() {
16 | return bookName;
17 | }
18 |
19 | public String getBookAuthor() {
20 | return bookAuthor;
21 | }
22 |
23 | public String getBookCoverURL() {
24 | return bookCoverURL;
25 | }
26 |
27 | public List getTitles() {
28 | return titles;
29 | }
30 |
31 | public List getChapters() {
32 | return chapters;
33 | }
34 |
35 | public List getChapterIDs() {
36 | return chapterIDs;
37 | }
38 |
39 | private String bookID;
40 | private String bookName;
41 | private String bookAuthor;
42 | private String bookCoverURL;
43 | private List titles;
44 |
45 | public void setChapters(List chapters) {
46 | this.chapters = chapters;
47 | }
48 |
49 | private List chapters;
50 | private List chapterIDs;
51 |
52 | public DownloadDetails(String bookID,String bookName,String bookAuthor,String bookCoverURL,List titles,List chapterIDs,List chapters){
53 | this.bookID = bookID;
54 | this.bookName = bookName;
55 | this.bookAuthor = bookAuthor;
56 | this.bookCoverURL = bookCoverURL;
57 | this.titles = titles;
58 | this.chapterIDs = chapterIDs;
59 | this.chapters = chapters;
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/app/src/main/java/cc/zsakvo/ninecswd/fragment/ArticleFragment.java:
--------------------------------------------------------------------------------
1 | package cc.zsakvo.ninecswd.fragment;
2 |
3 | import android.content.Intent;
4 | import android.os.Bundle;
5 | import android.support.design.widget.Snackbar;
6 | import android.support.v7.widget.LinearLayoutManager;
7 | import android.support.v7.widget.RecyclerView;
8 | import android.view.LayoutInflater;
9 | import android.view.View;
10 |
11 | import com.github.nukc.stateview.StateView;
12 | import com.scwang.smartrefresh.header.MaterialHeader;
13 | import com.scwang.smartrefresh.layout.api.RefreshLayout;
14 | import com.scwang.smartrefresh.layout.listener.OnLoadmoreListener;
15 | import com.scwang.smartrefresh.layout.listener.OnRefreshListener;
16 |
17 | import java.util.ArrayList;
18 | import java.util.List;
19 |
20 | import cc.zsakvo.ninecswd.ArticleActivity;
21 | import cc.zsakvo.ninecswd.R;
22 | import cc.zsakvo.ninecswd.adapter.ArticleAdapter;
23 | import cc.zsakvo.ninecswd.classes.ArticleList;
24 | import cc.zsakvo.ninecswd.listener.Interface;
25 | import cc.zsakvo.ninecswd.task.GetArticleListTask;
26 |
27 | /**
28 | * Created by akvo on 2018/2/19.
29 | */
30 |
31 | public class ArticleFragment extends BaseFragment implements View.OnClickListener,OnRefreshListener,OnLoadmoreListener,Interface.GetArticleList{
32 |
33 | private RecyclerView recyclerView;
34 | private StateView mStateView;
35 | private ArticleAdapter adapter;
36 | private RefreshLayout refreshLayout;
37 | private List listDetails = new ArrayList<>();
38 | int page = 1;
39 | String baseUrl = "http://www.99lib.net/article/index.php?page=";
40 | int totalPage;
41 |
42 | public static ArticleFragment newInstance(int sectionNumber){
43 | ArticleFragment fragment = new ArticleFragment();
44 | Bundle args = new Bundle();
45 | args.putInt("section_number",sectionNumber);
46 | return fragment;
47 | }
48 |
49 | @Override
50 | public void onClick(View view) {
51 | switch (view.getId()){
52 |
53 | }
54 | }
55 |
56 | @Override
57 | public void onItemClick(View view, int postion) {
58 | String url = String.valueOf(listDetails.get(postion).getArticleUrl());
59 | Intent intent = new Intent (getActivity (), ArticleActivity.class);
60 | intent.putExtra ("title",listDetails.get(postion).getArticleName ());
61 | intent.putExtra ("url",url);
62 | startActivity (intent);
63 | }
64 |
65 | @Override
66 | public View bindLayout(LayoutInflater inflater) {
67 | mRootView = inflater.inflate(R.layout.fragment_article,null);
68 | mStateView = StateView.inject(mRootView, true);
69 | return mRootView;
70 | }
71 |
72 | @Override
73 | public void initView() {
74 | refreshLayout = (RefreshLayout)mRootView.findViewById(R.id.arefreshLayout);
75 | recyclerView = mRootView.findViewById(R.id.nn_article_list);
76 | LinearLayoutManager layoutManager = new LinearLayoutManager(this.getContext());
77 | recyclerView.setLayoutManager(layoutManager);
78 | adapter = new ArticleAdapter(listDetails);
79 | adapter.setOnItemClickListener(ArticleFragment.this);
80 | recyclerView.setAdapter(adapter);
81 | }
82 |
83 | @Override
84 | protected void initData() {
85 | refreshLayout.setOnRefreshListener (this);
86 | refreshLayout.setOnLoadmoreListener (this);
87 | MaterialHeader mMaterialHeader = (MaterialHeader) refreshLayout.getRefreshHeader ();
88 | refreshLayout.autoRefresh ();
89 | }
90 |
91 |
92 | @Override
93 | public void onLoadmore(RefreshLayout refreshlayout) {
94 | page++;
95 | new GetArticleListTask (this).execute (baseUrl+page);
96 | }
97 |
98 | @Override
99 | public void onRefresh(RefreshLayout refreshlayout) {
100 | page = 1;
101 | listDetails.clear ();
102 | recyclerView.setAdapter (adapter);
103 | new GetArticleListTask (this).execute (baseUrl+page);
104 | }
105 |
106 | @Override
107 | public void GetOK(List listDetails, int totalPages) {
108 | this.listDetails.addAll (listDetails);
109 | this.totalPage = totalPages;
110 | adapter.notifyDataSetChanged();
111 | if (refreshLayout.isRefreshing ()){
112 | refreshLayout.finishRefresh (500);
113 | }else {
114 | refreshLayout.finishLoadmore (500);
115 | }
116 | }
117 |
118 | @Override
119 | public void GetFailed() {
120 | refreshLayout.finishLoadmoreWithNoMoreData ();
121 | if (refreshLayout.isRefreshing ()){
122 | refreshLayout.finishRefresh (false);
123 | }else {
124 | refreshLayout.finishLoadmore (false);
125 | }
126 | Snackbar.make (recyclerView,"数据获取失败,请检查网络连接或重试",Snackbar.LENGTH_LONG).show ();
127 | }
128 | }
129 |
--------------------------------------------------------------------------------
/app/src/main/java/cc/zsakvo/ninecswd/fragment/BaseFragment.java:
--------------------------------------------------------------------------------
1 | package cc.zsakvo.ninecswd.fragment;
2 |
3 | import android.content.Context;
4 | import android.os.Bundle;
5 | import android.support.annotation.NonNull;
6 | import android.support.annotation.Nullable;
7 | import android.support.v4.app.Fragment;
8 | import android.view.LayoutInflater;
9 | import android.view.View;
10 | import android.view.ViewGroup;
11 |
12 | import cc.zsakvo.ninecswd.listener.ItemClickListener;
13 |
14 |
15 | public abstract class BaseFragment extends Fragment implements ItemClickListener {
16 |
17 | public Context mContext;
18 | protected View mRootView;
19 |
20 | /**
21 | * 是否为可见状态
22 | */
23 | protected boolean isVisible;
24 | /**
25 | * 是否初始视图完成
26 | */
27 | private boolean isPrepared;
28 |
29 | @Override
30 | public void onCreate(@Nullable Bundle savedInstanceState) {
31 | super.onCreate(savedInstanceState);
32 | mContext = getActivity();
33 | }
34 |
35 |
36 | public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
37 | mRootView = bindLayout(inflater);
38 | initView();
39 | return mRootView;
40 | }
41 |
42 | @Override
43 | public void onActivityCreated(@Nullable Bundle savedInstanceState) {
44 |
45 | super.onActivityCreated(savedInstanceState);
46 | //这里 初始化view的各控件 数据
47 | isPrepared = true;
48 | lazyLoad();
49 |
50 | }
51 |
52 | /**
53 | * setUserVisibleHint是在onCreateView之前调用的
54 | *
55 | * @param isVisibleToUser
56 | */
57 | @Override
58 | public void setUserVisibleHint(boolean isVisibleToUser) {
59 |
60 | super.setUserVisibleHint(isVisibleToUser);
61 |
62 | /**
63 | * 判断是否可见
64 | */
65 | if(getUserVisibleHint()) {
66 |
67 | isVisible = true;
68 | //执行可见方法-初始化数据之类
69 | onVisible();
70 |
71 | } else {
72 |
73 | isVisible = false;
74 | //不可见
75 | onInvisible();
76 | }
77 |
78 | }
79 |
80 |
81 | /**
82 | * 可见做懒加载
83 | */
84 | private void onVisible() {
85 | lazyLoad();
86 | }
87 |
88 | /**
89 | * 懒加载
90 | */
91 | private void lazyLoad() {
92 | /**
93 | * 判断是否可见,或者 初始化view的各控件
94 | */
95 | if(!isVisible || !isPrepared) {
96 | return;
97 | }
98 | //可见 或者 控件初始化完成 就 加载数据
99 | initData();
100 |
101 | }
102 |
103 | /**
104 | * 不可见-做一些销毁工作
105 | */
106 | protected void onInvisible() {
107 |
108 |
109 | }
110 |
111 | /**
112 | * 绑定布局
113 | *
114 | * @param inflater
115 | * @return
116 | */
117 | public abstract View bindLayout(LayoutInflater inflater);
118 |
119 | /**
120 | * 初始化布局
121 | */
122 | public abstract void initView();
123 |
124 |
125 | /**
126 | * 初始化数据
127 | */
128 | protected abstract void initData();
129 | }
130 |
--------------------------------------------------------------------------------
/app/src/main/java/cc/zsakvo/ninecswd/fragment/BookStoreFragment.java:
--------------------------------------------------------------------------------
1 | package cc.zsakvo.ninecswd.fragment;
2 |
3 | import android.annotation.SuppressLint;
4 | import android.content.Intent;
5 | import android.os.Bundle;
6 | import android.support.design.widget.Snackbar;
7 | import android.support.v7.widget.LinearLayoutManager;
8 | import android.support.v7.widget.RecyclerView;
9 | import android.view.LayoutInflater;
10 | import android.view.View;
11 |
12 | import com.github.nukc.stateview.StateView;
13 | import com.scwang.smartrefresh.header.MaterialHeader;
14 | import com.scwang.smartrefresh.layout.api.RefreshLayout;
15 | import com.scwang.smartrefresh.layout.listener.OnLoadmoreListener;
16 | import com.scwang.smartrefresh.layout.listener.OnRefreshListener;
17 |
18 | import java.util.ArrayList;
19 | import java.util.List;
20 |
21 | import cc.zsakvo.ninecswd.BookDetailActivity;
22 | import cc.zsakvo.ninecswd.R;
23 | import cc.zsakvo.ninecswd.classes.BookList;
24 | import cc.zsakvo.ninecswd.listener.Interface;
25 | import cc.zsakvo.ninecswd.task.GetBookListTask;
26 |
27 |
28 | /**
29 | * Created by akvo on 2018/1/7.
30 | */
31 |
32 | public class BookStoreFragment extends BaseFragment implements View.OnClickListener,OnRefreshListener,OnLoadmoreListener,Interface.GetBookListFinish{
33 | private RecyclerView recyclerView;
34 | private StateView mStateView;
35 | private List listDetails = new ArrayList<>();
36 | cc.zsakvo.ninecswd.adapter.ListAdapter adapter;
37 | // FloatingActionButton fab;
38 | int page = 1;
39 | private RefreshLayout refreshLayout;
40 | private String baseURL = "http://www.99lib.net/book/index.php?page=";
41 |
42 | public BookStoreFragment(){
43 |
44 | }
45 |
46 | public static BookStoreFragment newInstance(int sectionNumber){
47 | BookStoreFragment fragment = new BookStoreFragment();
48 | Bundle args = new Bundle();
49 | args.putInt("section_number",sectionNumber);
50 | return fragment;
51 | }
52 |
53 | @SuppressLint("InflateParams")
54 | @Override
55 | public View bindLayout(LayoutInflater layoutInflater){
56 | mRootView = layoutInflater.inflate(R.layout.fragment_99lib,null);
57 | mStateView = StateView.inject(mRootView, true);
58 | return mRootView;
59 | }
60 |
61 | @Override
62 | public void initView() {
63 | recyclerView = mRootView.findViewById(R.id.nn_novel_list);
64 | // fab = (FloatingActionButton)mRootView.findViewById(R.id.fab);
65 | // fab.setOnClickListener(this);
66 | LinearLayoutManager layoutManager = new LinearLayoutManager(this.getContext());
67 | recyclerView.setLayoutManager(layoutManager);
68 | adapter = new cc.zsakvo.ninecswd.adapter.ListAdapter (listDetails);
69 | adapter.setOnItemClickListener(BookStoreFragment.this);
70 | recyclerView.setAdapter(adapter);
71 | }
72 |
73 | @Override
74 | protected void initData(){
75 | refreshLayout = (RefreshLayout) mRootView.findViewById (R.id.refreshLayout);
76 | refreshLayout.setOnRefreshListener(this);
77 | refreshLayout.setOnLoadmoreListener (this);
78 | refreshLayout.setEnableAutoLoadmore (true);
79 | MaterialHeader mMaterialHeader = (MaterialHeader) refreshLayout.getRefreshHeader ();
80 | refreshLayout.autoRefresh ();
81 | }
82 |
83 | @Override
84 | public void onItemClick(View view,final int position){
85 | String url = String.valueOf(listDetails.get(position).getBook_url());
86 | Intent intent = new Intent(getActivity(), BookDetailActivity.class);
87 | intent.putExtra("url", url);
88 | startActivity(intent);
89 | }
90 |
91 | @Override
92 | public void onClick(View view) {
93 | switch (view.getId()){
94 | // case R.id.fab:
95 | // recyclerView.setAdapter (adapter);
96 | // break;
97 | }
98 | }
99 |
100 | @Override
101 | public void onRefresh(RefreshLayout refreshlayout) {
102 | page = 1;
103 | listDetails.clear ();
104 | recyclerView.setAdapter (adapter);
105 | new GetBookListTask (BookStoreFragment.this).execute (baseURL+page);
106 | }
107 |
108 | @Override
109 | public void onLoadmore(RefreshLayout refreshlayout) {
110 | page++;
111 | new GetBookListTask (BookStoreFragment.this).execute (baseURL+page);
112 | }
113 |
114 | @Override
115 | public void bookList(List listDetails) {
116 | this.listDetails.addAll (listDetails);
117 | adapter.notifyDataSetChanged ();
118 | if (refreshLayout.isRefreshing ()){
119 | refreshLayout.finishRefresh (500);
120 | }else {
121 | refreshLayout.finishLoadmore (500);
122 | }
123 | }
124 |
125 | @Override
126 | public void booksGetFailed(){
127 | refreshLayout.finishLoadmoreWithNoMoreData ();
128 | if (refreshLayout.isRefreshing ()){
129 | refreshLayout.finishRefresh (500);
130 | }else {
131 | refreshLayout.finishLoadmore (500);
132 | }
133 | Snackbar.make (recyclerView,"数据获取失败,请检查网络连接或重试",Snackbar.LENGTH_LONG).show ();
134 | }
135 | }
136 |
--------------------------------------------------------------------------------
/app/src/main/java/cc/zsakvo/ninecswd/fragment/CategoryFragment.java:
--------------------------------------------------------------------------------
1 | package cc.zsakvo.ninecswd.fragment;
2 |
3 | import android.content.Intent;
4 | import android.os.Bundle;
5 | import android.support.design.widget.Snackbar;
6 | import android.support.v7.widget.RecyclerView;
7 | import android.support.v7.widget.StaggeredGridLayoutManager;
8 | import android.view.LayoutInflater;
9 | import android.view.View;
10 |
11 | import cc.zsakvo.ninecswd.CategoryActivity;
12 | import cc.zsakvo.ninecswd.R;
13 | import cc.zsakvo.ninecswd.adapter.CategoryAdapter;
14 |
15 | /**
16 | * Created by akvo on 2018/2/18.
17 | */
18 |
19 | public class CategoryFragment extends BaseFragment {
20 |
21 | private RecyclerView recyclerView;
22 | private CategoryAdapter adapter;
23 | String[] categorys = new String[] {"传记回忆","英文读本","杂文随笔","现代小说","言情小说",
24 | "历史小说","侦探推理","惊悚悬疑","网络玄幻","寓言童话","青春都市","社会心理","外国小说"
25 | ,"科幻小说","当代小说","武侠小说","纪实报告","中国历史","世界历史","科普学习"
26 | ,"诗歌戏曲","宗教哲学","文学理论","日语读物","作品集","国学/古籍","战争军事"
27 | ,"政治经济","古典文学","官场小说","轻小说"};
28 |
29 | public static CategoryFragment newInstance(int sectionNumber){
30 | CategoryFragment fragment = new CategoryFragment();
31 | Bundle args = new Bundle();
32 | args.putInt("section_number",sectionNumber);
33 | return fragment;
34 | }
35 |
36 | @Override
37 | public void onItemClick(View view, int postion) {
38 | String str = categorys[postion];
39 | Intent intent = new Intent(getActivity(), CategoryActivity.class);
40 | intent.putExtra("url",str);
41 | startActivity(intent);
42 | Snackbar.make(recyclerView,str,Snackbar.LENGTH_LONG).show();
43 | }
44 |
45 | @Override
46 | public View bindLayout(LayoutInflater inflater) {
47 | mRootView = inflater.inflate(R.layout.fragment_category,null);
48 | return mRootView;
49 | }
50 |
51 | @Override
52 | public void initView() {
53 | // LinearLayoutManager layoutManager = new LinearLayoutManager(this.getContext());
54 | // System.out.println("aaa");
55 | }
56 |
57 | @Override
58 | protected void initData() {
59 | recyclerView = mRootView.findViewById(R.id.category_list);
60 | StaggeredGridLayoutManager layoutManager = new
61 | StaggeredGridLayoutManager(3,StaggeredGridLayoutManager.VERTICAL);
62 | recyclerView.setLayoutManager(layoutManager);
63 | adapter = new CategoryAdapter (categorys);
64 | adapter.setOnItemClickListener(CategoryFragment.this);
65 | recyclerView.setAdapter(adapter);
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/app/src/main/java/cc/zsakvo/ninecswd/listener/Interface.java:
--------------------------------------------------------------------------------
1 | package cc.zsakvo.ninecswd.listener;
2 |
3 | import android.graphics.Bitmap;
4 |
5 | import java.util.List;
6 |
7 | import cc.zsakvo.ninecswd.classes.ArticleList;
8 | import cc.zsakvo.ninecswd.classes.BookList;
9 |
10 | /**
11 | * Created by akvo on 2018/3/19.
12 | */
13 |
14 | public class Interface {
15 | public interface GetBookListFinish{
16 | void bookList(List listDetails);
17 | void booksGetFailed();
18 | }
19 |
20 | public interface GetBookDetailFinish{
21 | void GetFailed();
22 | void GetSuccessful(String...strings);
23 | }
24 |
25 | public interface OutPutTxtFinish{
26 | void outPutFailed();
27 | void outPutSuccess(int i);
28 | }
29 |
30 | public interface GetCover{
31 | void GetCoverOK(Bitmap bitmap);
32 | }
33 |
34 | public interface GetCoverUrls{
35 | void GetCoverUrls(List list);
36 | void GetCoverUrlsFailed();
37 | }
38 |
39 | public interface GetArticleList{
40 | void GetOK(List listDetails, int totalPages);
41 | void GetFailed();
42 | }
43 |
44 | public interface GetArticle{
45 | void GetResult(Boolean result);
46 | }
47 |
48 | public interface GetCategoryList{
49 | void GetOK(List listDetails);
50 | void GetFailed();
51 | }
52 |
53 | public interface GetSearch{
54 | void GetOK(List listDetails,int totalPages);
55 | void GetFailed();
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/app/src/main/java/cc/zsakvo/ninecswd/listener/ItemClickListener.java:
--------------------------------------------------------------------------------
1 | package cc.zsakvo.ninecswd.listener;
2 |
3 | import android.view.View;
4 |
5 | /**
6 | * Created by akvo on 2018/2/14.
7 | */
8 |
9 | public interface ItemClickListener {
10 | void onItemClick(View view, int postion);
11 | }
12 |
--------------------------------------------------------------------------------
/app/src/main/java/cc/zsakvo/ninecswd/listener/OnDataFinishedListener.java:
--------------------------------------------------------------------------------
1 | package cc.zsakvo.ninecswd.listener;
2 |
3 | import cc.zsakvo.ninecswd.classes.DownloadDetails;
4 |
5 | /**
6 | * Created by akvo on 2018/2/22.
7 | */
8 |
9 | public interface OnDataFinishedListener {
10 | public void onDataSuccessfully(Object data);
11 | public void onDataSuccessfully(DownloadDetails data);
12 | public void onDownloadFinishedNum(int num);
13 | public void onDataFailed();
14 | }
15 |
--------------------------------------------------------------------------------
/app/src/main/java/cc/zsakvo/ninecswd/phrase/Book.java:
--------------------------------------------------------------------------------
1 | package cc.zsakvo.ninecswd.phrase;
2 |
3 | import java.util.List;
4 |
5 | /**
6 | * Created by akvo on 2018/2/16.
7 | */
8 |
9 | public class Book {
10 | private String bookID;
11 |
12 | public String getBookID() {
13 | return bookID;
14 | }
15 |
16 | public String getBookName() {
17 | return bookName;
18 | }
19 |
20 | public String getBookAuthor() {
21 | return bookAuthor;
22 | }
23 |
24 | public String getBookCoverURL() {
25 | return bookCoverURL;
26 | }
27 |
28 | public List getChapters() {
29 | return chapters;
30 | }
31 |
32 | public List getTitles() {
33 | return titles;
34 | }
35 |
36 | private String bookName;
37 | private String bookAuthor;
38 | private String bookCoverURL;
39 | private List chapters;
40 | private List titles;
41 |
42 | public Book(String bookID, String bookName, String bookAuthor, String bookCoverURL, List chapters, List titles){
43 | this.bookID = bookID;
44 | this.bookName = bookName;
45 | this.bookAuthor = bookAuthor;
46 | this.bookCoverURL = bookCoverURL;
47 | this.chapters = chapters;
48 | this.titles = titles;
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/app/src/main/java/cc/zsakvo/ninecswd/phrase/PhraseBookDetail.java:
--------------------------------------------------------------------------------
1 | //package cc.zsakvo.a99demo.phrase;
2 | //
3 | //import android.annotation.SuppressLint;
4 | //import android.os.Handler;
5 | //import android.os.Message;
6 | //
7 | //
8 | //import org.jsoup.Jsoup;
9 | //import org.jsoup.nodes.Document;
10 | //import org.jsoup.nodes.Element;
11 | //import org.jsoup.select.Elements;
12 | //
13 | //import java.io.IOException;
14 | //import java.util.ArrayList;
15 | //import java.util.List;
16 | //
17 | //import SearchActivity;
18 | //import DecodeUtils;
19 | //
20 | ///**
21 | // * Created by akvo on 2018/2/16.
22 | // */
23 | //
24 | //public class PhraseBookDetail {
25 | //
26 | // String url;
27 | // private String bookID;
28 | // private String bookName;
29 | // private String bookAuthor;
30 | // private String bookCoverURL;
31 | // private List chapters;
32 | // private List titles;
33 | // static Book book;
34 | //
35 | // public PhraseBookDetail(String url){
36 | // this.url = url;
37 | // }
38 | // public static Book url(String url){
39 | // new PhraseBookDetail(url).deal();
40 | // return book;
41 | // }
42 | //
43 | // private void deal(){
44 | // bookID = url.replace("http://www.99lib.net/book/","").replace("/index.htm","");
45 | // Message msg = new Message();
46 | // @SuppressLint("HandlerLeak")
47 | // android.os.Handler handler = new android.os.Handler() {
48 | // @Override
49 | // public void handleMessage(Message msg) {
50 | // switch (msg.what) {
51 | // case 1:
52 | // book = new Book(bookID,bookName,bookAuthor,bookCoverURL,chapters,titles);
53 | // default:
54 | // break;
55 | // }
56 | // }
57 | // };
58 | // new getResult(handler,msg).start();
59 | // }
60 | //
61 | // class getResult extends Thread{
62 | // Handler handler;
63 | // Message msg;
64 | // public getResult(Handler handler, Message msg){
65 | // this.handler = handler;
66 | // this.msg = msg;
67 | // }
68 | //
69 | // private String splitElement(Element element){
70 | // Elements es = element.select("a");
71 | // String str = "";
72 | // for (Element e:es){
73 | // String tmp = e.text()+" ";
74 | // str = str + tmp;
75 | // }
76 | // element.select("a").remove();
77 | // String tmp = element.text()+" ";
78 | // str = tmp+str;
79 | // return str;
80 | // }
81 | //
82 | // @Override
83 | // public void run() {
84 | // super.run();
85 | // try {
86 | // Document doc = Jsoup.connect(url).timeout(20000).get();
87 | // bookName = doc.selectFirst("h2").text();
88 | // bookAuthor = splitElement(doc.selectFirst("h4"));
89 | // bookCoverURL = "http://www.99lib.net"+doc.selectFirst("img").attr("src");
90 | // Elements elements_drags = doc.getElementById("right").select("dd");
91 | // titles = new ArrayList<>();
92 | // chapters = new ArrayList<>();
93 | // for (Element e:elements_drags){
94 | // titles.add(e.selectFirst("a").text());
95 | // chapters.add(DecodeUtils.url("http://www.99lib.net"+e.selectFirst("a").attr("href")));
96 | // }
97 | // } catch (IOException e) {
98 | // e.printStackTrace();
99 | // }
100 | // msg.what = 1;
101 | // handler.sendMessage(msg);
102 | // }
103 | // }
104 | //
105 | //}
106 |
--------------------------------------------------------------------------------
/app/src/main/java/cc/zsakvo/ninecswd/task/DownloadTask.java:
--------------------------------------------------------------------------------
1 | package cc.zsakvo.ninecswd.task;
2 |
3 | import android.os.AsyncTask;
4 |
5 | import java.util.concurrent.ConcurrentHashMap;
6 |
7 | import cc.zsakvo.ninecswd.listener.OnDataFinishedListener;
8 | import cc.zsakvo.ninecswd.utils.DecodeUtils;
9 | import cc.zsakvo.ninecswd.utils.DialogUtils;
10 |
11 | /**
12 | * Created by akvo on 2018/3/17.
13 | */
14 |
15 | public class DownloadTask extends AsyncTask {
16 |
17 | private int downloadsNum;
18 | private ConcurrentHashMap ch;
19 | private String bookID;
20 | private DialogUtils du;
21 | private int allNum;
22 | private int nowNum;
23 | private int type;
24 | private OnDataFinishedListener onDataFinishedListener;
25 |
26 | public DownloadTask(String bookID, ConcurrentHashMap ch, DialogUtils du,int allNum,int nowNum,int type,OnDataFinishedListener onDataFinishedListener){
27 | this.bookID = bookID;
28 | this.ch = ch;
29 | this.du = du;
30 | this.allNum = allNum;
31 | this.nowNum = nowNum;
32 | this.type = type;
33 | this.onDataFinishedListener = onDataFinishedListener;
34 | }
35 |
36 | @Override
37 | protected Integer doInBackground(int[]... ints) {
38 | String hostURL = "http://www.99lib.net/book/";
39 | int[] integers = ints[0];
40 | this.downloadsNum = integers.length;
41 | int p = 1;
42 | for (int i:integers){
43 | String url = hostURL +bookID+"/"+i+".htm";
44 | if (i==0){
45 | continue;
46 | }
47 | ch.put (i, DecodeUtils.url (url,type));
48 | publishProgress();
49 | }
50 | nowNum+=integers.length;
51 | return null;
52 | }
53 |
54 | @Override
55 | protected void onProgressUpdate(Integer...integers){
56 | super.onProgressUpdate (integers);
57 | du.addProgress (allNum);
58 | }
59 |
60 | @Override
61 | protected void onPostExecute(Integer integer){
62 | super.onPostExecute (integer);
63 | onDataFinishedListener.onDownloadFinishedNum (this.downloadsNum);
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/app/src/main/java/cc/zsakvo/ninecswd/task/GetArticleContentTask.java:
--------------------------------------------------------------------------------
1 | package cc.zsakvo.ninecswd.task;
2 |
3 | import android.os.AsyncTask;
4 | import android.support.v7.widget.Toolbar;
5 | import android.widget.TextView;
6 |
7 | import com.github.nukc.stateview.StateView;
8 | import com.zzhoujay.richtext.RichText;
9 |
10 | import cc.zsakvo.ninecswd.listener.Interface;
11 | import cc.zsakvo.ninecswd.utils.DecodeUtils;
12 |
13 | /**
14 | * Created by akvo on 2018/2/21.
15 | */
16 |
17 | public class GetArticleContentTask extends AsyncTask {
18 |
19 | private TextView textView;
20 | private Toolbar toolbar;
21 | private StateView mStateView;
22 | private Interface.GetArticle ga;
23 |
24 | public GetArticleContentTask(TextView textView, Toolbar toolbar, StateView mStateView, Interface.GetArticle ga){
25 | this.textView = textView;
26 | this.toolbar = toolbar;
27 | this.mStateView = mStateView;
28 | this.ga = ga;
29 | }
30 |
31 |
32 | @Override
33 | protected String doInBackground(String ... params) {
34 | String content = DecodeUtils.url (params[0],3);
35 | if (content==null){
36 | return null;
37 | }else {
38 | return content;
39 | }
40 | }
41 |
42 | @Override
43 | protected void onPostExecute(String string){
44 | super.onPostExecute (string);
45 | if (string==null){
46 | ga.GetResult (false);
47 | }else {
48 | RichText.fromHtml (string).into (textView);
49 | ga.GetResult (true);
50 | }
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/app/src/main/java/cc/zsakvo/ninecswd/task/GetArticleListTask.java:
--------------------------------------------------------------------------------
1 | package cc.zsakvo.ninecswd.task;
2 |
3 | import android.os.AsyncTask;
4 |
5 | import org.jsoup.Jsoup;
6 | import org.jsoup.nodes.Document;
7 | import org.jsoup.nodes.Element;
8 | import org.jsoup.select.Elements;
9 |
10 | import java.io.IOException;
11 | import java.util.ArrayList;
12 | import java.util.List;
13 |
14 | import cc.zsakvo.ninecswd.classes.ArticleList;
15 | import cc.zsakvo.ninecswd.listener.Interface;
16 |
17 | /**
18 | * Created by akvo on 2018/3/21.
19 | */
20 |
21 | public class GetArticleListTask extends AsyncTask> {
22 |
23 | private Interface.GetArticleList gal;
24 | private int totalPage = 0;
25 |
26 | public GetArticleListTask(Interface.GetArticleList gal){
27 | this.gal = gal;
28 | }
29 |
30 | @Override
31 | protected List doInBackground(String... strings) {
32 | String url = strings[0];
33 | int page = Integer.parseInt (url.replace ("http://www.99lib.net/article/index.php?page=",""));
34 | List listDetails = new ArrayList<> ();
35 | try {
36 | Document doc = Jsoup.connect(url).timeout(20000).get();
37 | if (page==1){
38 | listDetails.clear();
39 | totalPage = Integer.parseInt(doc.selectFirst("span.total").text().replace("1/",""));
40 | }
41 | Element element = doc.selectFirst("ul.list_box");
42 | Elements ele_li = element.select("li");
43 | for (Element e:ele_li){
44 | Element n = e.select("a").get(1);
45 | String author = e.selectFirst("span").text().replace("(","").replace(")","");
46 | String title = n.text();
47 | String artical_url = "http://www.99lib.net"+n.attr("href");
48 | listDetails.add(new ArticleList(title,author,artical_url));
49 | }
50 | if (isCancelled())
51 | {
52 | return (null);
53 | }
54 | return listDetails;
55 | } catch (IOException e) {
56 | e.printStackTrace();
57 | return null;
58 | }
59 | }
60 |
61 | @Override
62 | protected void onPostExecute(List listDetails){
63 | super.onPostExecute (listDetails);
64 | if (listDetails!=null) {
65 | gal.GetOK (listDetails,totalPage);
66 | }else {
67 | gal.GetFailed ();
68 | }
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/app/src/main/java/cc/zsakvo/ninecswd/task/GetBookDetailTask.java:
--------------------------------------------------------------------------------
1 | package cc.zsakvo.ninecswd.task;
2 |
3 | import android.os.AsyncTask;
4 | import android.util.Log;
5 |
6 |
7 | import org.jsoup.Jsoup;
8 | import org.jsoup.nodes.Document;
9 | import org.jsoup.nodes.Element;
10 |
11 | import java.io.IOException;
12 |
13 | import cc.zsakvo.ninecswd.listener.Interface;
14 | import cc.zsakvo.ninecswd.utils.SplitUtil;
15 |
16 | /**
17 | * Created by akvo on 2018/2/22.
18 | */
19 |
20 | public class GetBookDetailTask extends AsyncTask{
21 |
22 | private Interface.GetBookDetailFinish gbdf;
23 |
24 |
25 |
26 | public GetBookDetailTask(Interface.GetBookDetailFinish gbdf){
27 | this.gbdf = gbdf;
28 | }
29 |
30 | @Override
31 | protected String[] doInBackground(String... strings) {
32 | String url = strings[0];
33 | String title = "";
34 | String intro = "";
35 | String detail = "";
36 | String coverUrl = "";
37 | String searchStr = "";
38 | try {
39 | Document doc = Jsoup.connect(url).timeout(20000).get();
40 | Element element_info = doc.getElementById("book_info");
41 | title = element_info.selectFirst("h2").text();
42 | coverUrl = "http://www.99lib.net" + element_info.selectFirst("img").attr("src");
43 | detail = "书籍简介:"+element_info.selectFirst("div.intro").text();
44 | String author = SplitUtil.splitElement(element_info.selectFirst("h4"));
45 | // Log.e ("doInBackground: ",author.replace ("作者: ","") );
46 | searchStr = title+" "+author.replace ("作者: ","");
47 | int i = element_info.select("h4").size();
48 | if (i == 2){
49 | String label = SplitUtil.splitElement(element_info.select("h4").get(1),title,author.replace("作者:",""));
50 | intro = author+label;
51 | }else if (i == 3){
52 | String trans = SplitUtil.splitElement(element_info.select("h4").get(1));
53 | String label = SplitUtil.splitElement(element_info.select("h4").get(2),title,author.replace("作者:",""));
54 | author = author + " " + trans;
55 | intro = author+"\n\n"+label;
56 | }
57 | } catch (IOException e) {
58 | e.printStackTrace ();
59 | }
60 |
61 | if (isCancelled())
62 | {
63 | return (null);
64 | }
65 |
66 | return new String[]{title,intro,detail,coverUrl,searchStr};
67 | }
68 |
69 | @Override
70 | protected void onPostExecute(String[] strings){
71 | super.onPostExecute (strings);
72 | if (strings[3].length ()!=0){
73 | gbdf.GetSuccessful (strings[0],strings[1],strings[2],strings[3],strings[4]);
74 | }else {
75 | gbdf.GetFailed ();
76 | }
77 | }
78 |
79 | }
80 |
--------------------------------------------------------------------------------
/app/src/main/java/cc/zsakvo/ninecswd/task/GetBookListTask.java:
--------------------------------------------------------------------------------
1 | package cc.zsakvo.ninecswd.task;
2 |
3 | import android.annotation.SuppressLint;
4 | import android.os.AsyncTask;
5 |
6 |
7 | import com.github.nukc.stateview.StateView;
8 |
9 | import org.jsoup.Jsoup;
10 | import org.jsoup.nodes.Document;
11 | import org.jsoup.nodes.Element;
12 | import org.jsoup.select.Elements;
13 |
14 | import java.io.IOException;
15 | import java.util.ArrayList;
16 | import java.util.List;
17 |
18 | import cc.zsakvo.ninecswd.adapter.ListAdapter;
19 | import cc.zsakvo.ninecswd.classes.BookList;
20 | import cc.zsakvo.ninecswd.listener.Interface;
21 | import cc.zsakvo.ninecswd.utils.SplitUtil;
22 |
23 |
24 | /**
25 | * Created by akvo on 2018/2/21.
26 | */
27 |
28 | public class GetBookListTask extends AsyncTask> {
29 |
30 | private List listDetails;
31 | private ListAdapter adapter;
32 | @SuppressLint("StaticFieldLeak")
33 | private StateView mStateView;
34 | private Interface.GetBookListFinish gbf;
35 |
36 | public GetBookListTask(/*ListAdapter adapter, List listDetails, StateView mStateView, */Interface.GetBookListFinish gbf){
37 | // this.listDetails = listDetails;
38 | // this.adapter = adapter;
39 | // this.mStateView = mStateView;
40 | this.gbf = gbf;
41 | }
42 |
43 | @Override
44 | protected void onPreExecute() {
45 | // mStateView.showLoading ();
46 | }
47 |
48 | @Override
49 | protected List doInBackground(String... strings) {
50 | String url = strings[0];
51 | // String page = url.substring (url.indexOf ("page=")+5);
52 | List listDetails = new ArrayList<> ();
53 | try {
54 | Document doc = Jsoup.connect (url).timeout (20000).get ();
55 | Element element = doc.getElementById("list_box");
56 | Elements ele_li = element.select("li");
57 | for (Element e:ele_li){
58 | String title = e.selectFirst("a").attr("title");
59 | String author = SplitUtil.splitElement(e.select("h4").get(0));
60 | String category = SplitUtil.splitElement(e.select("h4").get(1));
61 | String label = SplitUtil.splitElement(e.select("h4").get(2),title,author.replace("作者:",""));
62 | String intro = "简介:"+e.selectFirst("div.intro").text();
63 | String book_url = "http://www.99lib.net"+e.selectFirst("a").attr("href");
64 | listDetails.add(new BookList (title,author+"\n"+category+"\n"+label,intro,book_url));
65 | }
66 | return listDetails;
67 | } catch (IOException e) {
68 | e.printStackTrace ();
69 | return null;
70 | }
71 | }
72 |
73 |
74 | @Override
75 | protected void onPostExecute(List listDetails){
76 | super.onPostExecute (listDetails);
77 | if (listDetails!=null) {
78 | gbf.bookList (listDetails);
79 | }else {
80 | gbf.booksGetFailed ();
81 | }
82 | // mStateView.showContent ();
83 | }
84 | }
85 |
--------------------------------------------------------------------------------
/app/src/main/java/cc/zsakvo/ninecswd/task/GetCategoryListTask.java:
--------------------------------------------------------------------------------
1 | package cc.zsakvo.ninecswd.task;
2 |
3 | import android.os.AsyncTask;
4 |
5 | import org.jsoup.Jsoup;
6 | import org.jsoup.nodes.Document;
7 | import org.jsoup.nodes.Element;
8 | import org.jsoup.select.Elements;
9 |
10 | import java.io.IOException;
11 | import java.util.ArrayList;
12 | import java.util.List;
13 |
14 | import cc.zsakvo.ninecswd.adapter.ListAdapter;
15 | import cc.zsakvo.ninecswd.classes.BookList;
16 | import cc.zsakvo.ninecswd.listener.Interface;
17 | import cc.zsakvo.ninecswd.utils.SplitUtil;
18 |
19 | /**
20 | * Created by akvo on 2018/2/22.
21 | */
22 |
23 | public class GetCategoryListTask extends AsyncTask
\n");
123 | break;
124 | case 2:
125 | content.append(childNode[i].text()+"\n");
126 | break;
127 | case 3:
128 | content.append(" "+childNode[i].text()+"
\n");
129 | break;
130 | }
131 | }
132 | }
133 | return content.toString();
134 | }
135 |
136 | private String base64(String a){
137 | String map = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
138 | String b = "";
139 | String binary = b;
140 | String[] sc = {"00000","0000","000","00","0",""};
141 | List binarys = new ArrayList<>();
142 | for (int i = 0; i < a.length(); i++) {
143 | if (a.substring(i, i+1).equals("=")) {
144 | break;
145 | }
146 | String c = Integer.toBinaryString(map.indexOf(a.charAt(i)));
147 | binary += sc[c.length()-1]+c;
148 | };
149 | for (int i=0;i=binary.length()){
151 | binarys.add(binary.substring(i));
152 | }else {
153 | binarys.add(binary.substring(i, i + 8));
154 | }
155 | }
156 | for (int i = 0; i < binarys.size(); i++) {
157 | b += "" + (char)(Integer.parseInt(binarys.get(i),2));
158 | };
159 | return b;
160 | }
161 | };
162 |
163 | public static String url(String url,int type){
164 | return new Decode99().getContent(url,type);
165 | }
166 |
167 | }
168 |
--------------------------------------------------------------------------------
/app/src/main/java/cc/zsakvo/ninecswd/utils/DialogUtils.java:
--------------------------------------------------------------------------------
1 | package cc.zsakvo.ninecswd.utils;
2 |
3 | import android.app.Dialog;
4 | import android.content.Context;
5 | import android.util.DisplayMetrics;
6 | import android.view.LayoutInflater;
7 | import android.view.View;
8 | import android.widget.LinearLayout;
9 | import android.widget.TextView;
10 |
11 | import cc.zsakvo.ninecswd.R;
12 |
13 | /**
14 | * Created by akvo on 2018/3/17.
15 | */
16 |
17 | public class DialogUtils {
18 |
19 | private Context context;
20 | private Dialog dialog;
21 | private int progress = 0;
22 | private int allNum;
23 |
24 | public DialogUtils(Context context,Dialog dialog){
25 | this.context = context;
26 | this.dialog = dialog;
27 | }
28 |
29 | public void setAllNum(int i){
30 | this.allNum = i;
31 | }
32 |
33 | public void initDialog(){
34 | progress = 0;
35 | LayoutInflater inflater = LayoutInflater.from (context);
36 | View v = inflater.inflate (R.layout.dialog, null); // 得到加载view
37 | DisplayMetrics displaymetrics = new DisplayMetrics ();
38 | displaymetrics = context.getResources ().getDisplayMetrics ();
39 | int screenWidth = displaymetrics.widthPixels;
40 | v.setMinimumWidth ((int) (screenWidth * 0.8));
41 | LinearLayout layout = (LinearLayout) v.findViewById (R.id.dia_lay); // 加载布局
42 | dialog = new Dialog (context); // 创建自定义样式dialog
43 | dialog.setCancelable (false); // 不可以用"返回键"取消
44 | dialog.setContentView (layout, new LinearLayout.LayoutParams (
45 | LinearLayout.LayoutParams.WRAP_CONTENT,
46 | LinearLayout.LayoutParams.WRAP_CONTENT));
47 | dialog.show ();
48 | }
49 |
50 | public void setDialogTitle(String title){
51 | TextView d_tv = dialog.findViewById(R.id.dia_text);
52 | d_tv.setText(title);
53 | }
54 |
55 | public void concelDialog(){
56 | dialog.dismiss ();
57 | }
58 |
59 | public void addProgress(int allNum){
60 | progress++;
61 | String text = "正在下载章节……"+progress+"/"+allNum;
62 | setDialogTitle (text);
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/app/src/main/java/cc/zsakvo/ninecswd/utils/EpubUtils.java:
--------------------------------------------------------------------------------
1 | package cc.zsakvo.ninecswd.utils;
2 |
3 | import android.annotation.SuppressLint;
4 | import android.os.Environment;
5 | import android.os.Handler;
6 | import android.os.Message;
7 |
8 | import org.jsoup.Jsoup;
9 | import org.jsoup.nodes.Element;
10 | import org.zeroturnaround.zip.NameMapper;
11 | import org.zeroturnaround.zip.ZipUtil;
12 |
13 | import java.io.BufferedWriter;
14 | import java.io.File;
15 | import java.io.FileOutputStream;
16 | import java.io.FileWriter;
17 | import java.io.IOException;
18 | import java.io.InputStream;
19 | import java.io.OutputStream;
20 | import java.net.MalformedURLException;
21 | import java.net.URL;
22 | import java.net.URLConnection;
23 | import java.util.List;
24 |
25 | /**
26 | * Created by akvo on 2018/2/1.
27 | */
28 |
29 | public class EpubUtils {
30 | private static String BOOKTOC = "\n" +
31 | "\n" +
32 | "\n" +
33 | "\n" +
34 | "\n" +
35 | "\n" +
36 | "Table Of Contents\n" +
37 | "\n" +
38 | "\n" +
39 | "\n" +
40 | "\n" +
41 | "目录
\n" +
42 | "\n" +
43 | "
\n" +
44 | "toreplace0\n" +
45 | "
\n" +
46 | "
\n" +
47 | "\n" +
48 | "\n";
49 | public static String CHAPTER = "\n" +
50 | "\n" +
51 | "\n" +
52 | "\n" +
53 | "\n" +
54 | "\n" +
55 | "\n" +
56 | "toreplace0 - 0\n" +
57 | "\n" +
58 | "\n" +
59 | "\n" +
60 | "\n" +
61 | "toreplace1\n"+
62 | "\n" +
63 | "";
64 | private static String CONTAINER = "\n" +
65 | "\n" +
66 | " \n" +
67 | " \n" +
68 | " \n" +
69 | "";
70 | private static String CONTENT = "\n" +
71 | "\n" +
72 | "\n" +
73 | "easypub-c260e840\n" +
74 | "toreplace0\n" +
75 | "toreplace1\n" +
76 | "2018\n" +
77 | "Created with EasyPub v1.50\n" +
78 | "zh-CN\n" +
79 | "\n" +
80 | "\n" +
81 | "toreplace2\n" +
82 | "toreplace3" +
83 | "\n" +
84 | "\n" +
85 | "\n" +
86 | "\n" +
87 | "\n" +
88 | "\n";
89 | private static String MIMETYPE = "application/epub+zip";
90 | private static String STYLE = "@font-face {\n" +
91 | " font-family: \"easypub\";\n" +
92 | " src: url(res:///system/fonts/DroidSansFallback.ttf),\n" +
93 | " url(res:///ebook/fonts/../../system/fonts/DroidSansFallback.ttf);\n" +
94 | "}\n" +
95 | "\n" +
96 | "@page { \n" +
97 | " margin-top: 0px;\n" +
98 | " margin-bottom: 0px;\n" +
99 | "}\n" +
100 | "\n" +
101 | "body { \n" +
102 | " font-family: \"easypub\";\n" +
103 | " padding: 0;\n" +
104 | " margin-left: 0px;\n" +
105 | " margin-right: 0px;\n" +
106 | " orphans: 0;\n" +
107 | " widows: 0;\n" +
108 | "}\n" +
109 | "\n" +
110 | "p { \n" +
111 | " font-family: \"easypub\";\n" +
112 | " font-size: 120%;\n" +
113 | " line-height: 125%;\n" +
114 | " margin-top: 5px;\n" +
115 | " margin-bottom: 0;\n" +
116 | " margin-left: 0;\n" +
117 | " margin-right: 0;\n" +
118 | " orphans: 0;\n" +
119 | " widows: 0;\n" +
120 | "}\n" +
121 | "\n" +
122 | ".a { \n" +
123 | " text-indent: 0em;\n" +
124 | "}\n" +
125 | "\n" +
126 | "div.centeredimage {\n" +
127 | " text-align:center;\n" +
128 | " display:block;\n" +
129 | " margin-top: 0.5em;\n" +
130 | " margin-bottom: 0.5em;\n" +
131 | "}\n" +
132 | "\n" +
133 | "img.attpic {\n" +
134 | " border: 1px solid #000000;\n" +
135 | " max-width: 100%;\n" +
136 | " margin: 0;\n" +
137 | "}\n" +
138 | "\n" +
139 | ".booktitle {\n" +
140 | " margin-top: 30%;\n" +
141 | " margin-bottom: 0;\n" +
142 | " border-style: none solid none none;\n" +
143 | " border-width: 50px;\n" +
144 | " border-color: #4E594D;\n" +
145 | " font-size: 3em;\n" +
146 | " line-height: 120%;\n" +
147 | " text-align: right;\n" +
148 | "}\n" +
149 | "\n" +
150 | ".bookauthor {\n" +
151 | " margin-top: 0;\n" +
152 | " border-style: none solid none none;\n" +
153 | " border-width: 50px;\n" +
154 | " border-color: #4E594D;\n" +
155 | " page-break-after: always;\n" +
156 | " font-size: large;\n" +
157 | " line-height: 120%;\n" +
158 | " text-align: right;\n" +
159 | "}\n" +
160 | "\n" +
161 | ".titletoc, .titlel1top, .titlel1std,.titlel2top, .titlel2std,.titlel3top, .titlel3std,.titlel4std {\n" +
162 | " margin-top: 0;\n" +
163 | " border-style: none double none solid;\n" +
164 | " border-width: 0px 5px 0px 20px;\n" +
165 | " border-color: #586357;\n" +
166 | " background-color: #C1CCC0;\n" +
167 | " padding: 45px 5px 5px 5px;\n" +
168 | " font-size: x-large;\n" +
169 | " line-height: 115%;\n" +
170 | " text-align: justify;\n" +
171 | "}\n" +
172 | "\n" +
173 | ".titlel1single,.titlel2single,.titlel3single {\n" +
174 | " margin-top: 35%;\n" +
175 | " border-style: none solid none none;\n" +
176 | " border-width: 30px;\n" +
177 | " border-color: #4E594D;\n" +
178 | " padding: 30px 5px 5px 5px;\n" +
179 | " font-size: x-large;\n" +
180 | " line-height: 125%;\n" +
181 | " text-align: right;\n" +
182 | "}\n" +
183 | "\n" +
184 | ".toc {\n" +
185 | " margin-left:16%;\n" +
186 | " padding:0px;\n" +
187 | " line-height:130%;\n" +
188 | " text-align: justify;\n" +
189 | "}\n" +
190 | "\n" +
191 | ".toc a { text-decoration: none; color: #000000; }\n" +
192 | "\n" +
193 | ".tocl1 {\n" +
194 | " margin-top:0.5em;\n" +
195 | " margin-left:-30px;\n" +
196 | " border-style: none double double solid;\n" +
197 | " border-width: 0px 5px 2px 20px;\n" +
198 | " border-color: #6B766A;\n" +
199 | " line-height: 135%;\n" +
200 | " font-size: 132%;\n" +
201 | "}\n" +
202 | "\n" +
203 | ".tocl2 {\n" +
204 | " margin-top: 0.5em;\n" +
205 | " margin-left:-20px;\n" +
206 | " border-style: none double none solid;\n" +
207 | " border-width: 0px 2px 0px 10px;\n" +
208 | " border-color: #939E92;\n" +
209 | " line-height: 123%;\n" +
210 | " font-size: 120%;\n" +
211 | "}\n" +
212 | "\n" +
213 | ".tocl3 {\n" +
214 | " margin-top: 0.5em;\n" +
215 | " margin-left:-20px;\n" +
216 | " border-style: none double none solid;\n" +
217 | " border-width: 0px 2px 0px 8px;\n" +
218 | " border-color: #939E92;\n" +
219 | " line-height: 112%;\n" +
220 | " font-size: 109%;\n" +
221 | "}\n" +
222 | "\n" +
223 | ".tocl4 {\n" +
224 | " margin-top: 0.5em;\n" +
225 | " margin-left:-20px;\n" +
226 | " border-style: none double none solid;\n" +
227 | " border-width: 0px 2px 0px 6px;\n" +
228 | " border-color: #939E92;\n" +
229 | " line-height: 115%;\n" +
230 | " font-size: 110%;\n" +
231 | "}\n" +
232 | "\n" +
233 | ".subtoc {\n" +
234 | " margin-left:15%;\n" +
235 | " padding:0px;\n" +
236 | " text-align: justify;\n" +
237 | "}\n" +
238 | "\n" +
239 | ".subtoclist {\n" +
240 | " margin-top: 0.5em;\n" +
241 | " margin-left:-20px;\n" +
242 | " border-style: none double none solid;\n" +
243 | " border-width: 0px 2px 0px 10px;\n" +
244 | " border-color: #939E92;\n" +
245 | " line-height: 123%;\n" +
246 | " font-size: 120%;\n" +
247 | "}\n" +
248 | "\n";
249 | private static String TOC = "\n" +
250 | "\n" +
251 | "\n" +
252 | "\n" +
253 | "\n" +
254 | "\n" +
255 | "\n" +
256 | "\n" +
257 | "\n" +
258 | "\n" +
259 | "\n" +
260 | "\n" +
261 | "\n" +
262 | "toreplace0\n" +
263 | "\n" +
264 | "\n" +
265 | "toreplace1\n" +
266 | "\n" +
267 | "\n" +
268 | "toreplace2" +
269 | "\n";
270 |
271 | private static String COVERHTML="\n" +
272 | "\n" +
273 | "\n" +
274 | "\n" +
275 | "\n" +
276 | "\n" +
277 | "\n" +
278 | "Cover\n" +
279 | "\n" +
280 | "\n" +
286 | "\n" +
287 | "\n" +
288 | "\n" +
289 | "\n" +
290 | "\n" +
291 | "
\n" +
292 | " \n" +
293 | " |
\n" +
294 | "
\n" +
295 | "\n" +
296 | "";
297 |
298 | private static String ELE_DT_A = "Table";
299 |
300 | private static String ELE_MANIFEST = "\n" +
301 | "- \n" +
302 | "
- \n" +
303 | "
- \n" +
304 | "
- \n" +
305 | "
- \n" +
306 | "
";
307 |
308 | private static String ELE_SPINE = "\n" +
309 | "\n" +
310 | "\n" +
311 | "";
312 |
313 | private static String ELE_NAV_MAP = "\n" +
314 | "\n" +
315 | "THETEXT\n" +
316 | "\n" +
317 | "\n";
318 |
319 | private static String ELE_CHAPTER_BODY = "\n" +
320 | "\n" +
321 | "\n" +
322 | "";
323 |
324 | private String sdPath = Environment.getExternalStorageDirectory().getPath()+"/99lib/";
325 | private String cachePath;
326 | private String bookPath;
327 | private String bookID;
328 | private String bookName;
329 | private String bookAuthor;
330 | private String bookCoverURL;
331 | private List chapters;
332 | private List titles;
333 | private int chapterNums = 0;
334 | private getResult gr;
335 | int threadNum = 4;
336 |
337 | public Boolean getOthersOK() {
338 | return isOthersOK;
339 | }
340 |
341 | public void setOthersOK(Boolean othersOK) {
342 | isOthersOK = othersOK;
343 | }
344 |
345 | public Boolean getChaptersOK() {
346 | return isChaptersOK;
347 | }
348 |
349 | public void setChaptersOK(Boolean chaptersOK) {
350 | isChaptersOK = chaptersOK;
351 | }
352 |
353 | private Boolean isOthersOK;
354 | private Boolean isChaptersOK;
355 |
356 | public interface getResult{
357 | void isGenerOk(int i);
358 | }
359 |
360 | public EpubUtils(String bookID, String bookName, String bookAuthor, String bookCoverURL, List chapters, List titles,getResult gr){
361 | this.bookID = bookID;
362 | this.bookName = bookName;
363 | this.bookAuthor = bookAuthor;
364 | this.bookCoverURL = bookCoverURL;
365 | this.chapters = chapters;
366 | this.titles = titles;
367 | this.gr = gr;
368 | chapterNums = chapters.size();
369 | cachePath = Environment.getExternalStorageDirectory().getPath()+"/99lib/cache/"+bookID;
370 | bookPath = Environment.getExternalStorageDirectory().getPath()+"/99lib/Epub/";
371 | new File(cachePath).mkdirs();
372 | if (!new File(bookPath).exists ()){
373 | new File(bookPath).mkdirs ();
374 | }
375 | }
376 |
377 | private void writeStr(String path,String str){
378 | File file = new File(path);
379 | if (file.exists()) file.delete();
380 | try {
381 | file.createNewFile();
382 | BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(file));
383 | bufferedWriter.write(str);
384 | bufferedWriter.flush();
385 | bufferedWriter.close();
386 | } catch (IOException e) {
387 | e.printStackTrace();
388 | }
389 | }
390 |
391 | private void generateOthers(){
392 | System.out.println(cachePath);
393 | new File(cachePath+"/META-INF").mkdirs();
394 | new File(cachePath+"/OEBPS").mkdirs();
395 | writeStr(cachePath+"/mimetype",MIMETYPE);
396 | writeStr(cachePath+"/META-INF/container.xml",CONTAINER);
397 | writeStr(cachePath+"/OEBPS/style.css",STYLE);
398 | generateCover();
399 | generateTocNcx();
400 | generateContentOpf();
401 | generateBookToc();
402 | generateCoverHtml();
403 | }
404 |
405 | private void generateCover(){
406 | try {
407 | URL url_cover = new URL(bookCoverURL);
408 | URLConnection uri = url_cover.openConnection();
409 | InputStream is = uri.getInputStream();
410 | OutputStream os = new FileOutputStream(new File(cachePath+"/OEBPS/cover.jpg"));
411 | byte[] buf = new byte[1024];
412 | int len = -1;
413 | while ((len = is.read(buf)) != -1) {
414 | os.write(buf, 0, len);
415 | }
416 | } catch (MalformedURLException e) {
417 | e.printStackTrace();
418 | } catch (IOException e) {
419 | generateCover();
420 | }
421 | }
422 |
423 | private void generateTocNcx(){
424 | String fileText = TOC;
425 | {
426 | StringBuilder d = new StringBuilder();
427 | String e = ELE_NAV_MAP;
428 | d.append(e.replace("POD","1").replace("THETEXT","封面").replace("THEHTML","cover.html"));
429 | d.append(e.replace("POD","2").replace("THETEXT","目录").replace("THEHTML","book-toc.html"));
430 | int playorder = 3;
431 | int chapter = 0;
432 | for (int i=0;i list, int num) {
42 | int size = list.size();
43 | int remainder = size % num;
44 | int threadNum;
45 | int[][] result;
46 | if (remainder == 0) {
47 | threadNum = size / num;
48 | result = new int[threadNum][num];
49 | for (int i = 0; i < threadNum; i++) {
50 | for (int j = 0; j < num; j++) {
51 | result[i][j] = list.get(i * num + j);
52 | }
53 | }
54 | } else {
55 | threadNum = size / num + 1;
56 | result = new int[threadNum][num];
57 | for (int i = 0; i < threadNum - 1; i++) {
58 | for (int j = 0; j < num; j++) {
59 | result[i][j] = list.get(i * num + j);
60 | }
61 | }
62 | for (int k = 0; k < remainder; k++) {
63 | result[threadNum - 1][k] = list.get((threadNum - 1) * num + k);
64 | }
65 | }
66 | return result;
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/app/src/main/java/cc/zsakvo/ninecswd/utils/TxtUtils.java:
--------------------------------------------------------------------------------
1 | package cc.zsakvo.ninecswd.utils;
2 |
3 | import android.os.Environment;
4 |
5 | import java.io.BufferedWriter;
6 | import java.io.File;
7 | import java.io.FileWriter;
8 | import java.io.IOException;
9 |
10 | /**
11 | * Created by akvo on 2018/3/20.
12 | */
13 |
14 | public class TxtUtils {
15 |
16 | private String cachePath;
17 |
18 | public static void generateTXT(String bookName,String BookChapters){
19 | new TxtUtils (bookName,BookChapters);
20 | }
21 |
22 | public TxtUtils(String bookName, String bookChapters){
23 | File dir = new File (Environment.getExternalStorageDirectory().getPath()+"/99lib/txt/");
24 | if (!dir.exists ()){
25 | dir.mkdirs ();
26 | }
27 | cachePath = Environment.getExternalStorageDirectory().getPath()+"/99lib/txt/"+bookName+".txt";
28 | writeStr (cachePath,bookChapters);
29 | }
30 |
31 | private void writeStr(String path,String bookChapters){
32 | File file = new File(path);
33 | if (file.exists()) file.delete();
34 | try {
35 | file.createNewFile();
36 | BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter (file));
37 | bufferedWriter.write(bookChapters);
38 | bufferedWriter.flush();
39 | bufferedWriter.close();
40 | } catch (IOException e) {
41 | e.printStackTrace();
42 | }
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-v24/ic_launcher_foreground.xml:
--------------------------------------------------------------------------------
1 |
7 |
12 |
13 |
19 |
22 |
25 |
26 |
27 |
28 |
34 |
35 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_baidu.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_bing.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_launcher_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
10 |
15 |
20 |
25 |
30 |
35 |
40 |
45 |
50 |
55 |
60 |
65 |
70 |
75 |
80 |
85 |
90 |
95 |
100 |
105 |
110 |
115 |
120 |
125 |
130 |
135 |
140 |
145 |
150 |
155 |
160 |
165 |
170 |
171 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_search.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_article.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
15 |
16 |
17 |
23 |
24 |
29 |
32 |
33 |
34 |
41 |
42 |
47 |
48 |
49 |
50 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_category.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
14 |
15 |
16 |
17 |
23 |
24 |
25 |
31 |
34 |
35 |
40 |
41 |
42 |
43 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_change_cover.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
13 |
14 |
15 |
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
16 |
17 |
18 |
25 |
26 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_search.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
16 |
17 |
18 |
19 |
20 |
27 |
33 |
34 |
40 |
43 |
44 |
49 |
50 |
51 |
52 |
53 |
54 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/articlelist.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
16 |
26 |
27 |
35 |
36 |
37 |
38 |
44 |
45 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/booklist.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
20 |
21 |
30 |
31 |
41 |
42 |
48 |
49 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/categorylist.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
16 |
17 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/coverlist.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
14 |
15 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/dialog.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
13 |
14 |
20 |
21 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_99lib.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
11 |
14 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_article.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
11 |
14 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_category.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/n_activity_book_detail.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
15 |
16 |
17 |
22 |
25 |
26 |
27 |
28 |
34 |
35 |
44 |
45 |
57 |
58 |
59 |
67 |
68 |
72 |
80 |
81 |
82 |
88 |
89 |
93 |
94 |
101 |
102 |
109 |
110 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
--------------------------------------------------------------------------------
/app/src/main/res/menu/main_menu.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/app/src/main/res/menu/search_menu.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/app/src/main/res/menu/select_engine_menu.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zsakvo/99LibraryDownloader/7cdde347dd734830c0ee7dfa3b97cc0cf2d7dfbf/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zsakvo/99LibraryDownloader/7cdde347dd734830c0ee7dfa3b97cc0cf2d7dfbf/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zsakvo/99LibraryDownloader/7cdde347dd734830c0ee7dfa3b97cc0cf2d7dfbf/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zsakvo/99LibraryDownloader/7cdde347dd734830c0ee7dfa3b97cc0cf2d7dfbf/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zsakvo/99LibraryDownloader/7cdde347dd734830c0ee7dfa3b97cc0cf2d7dfbf/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zsakvo/99LibraryDownloader/7cdde347dd734830c0ee7dfa3b97cc0cf2d7dfbf/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zsakvo/99LibraryDownloader/7cdde347dd734830c0ee7dfa3b97cc0cf2d7dfbf/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zsakvo/99LibraryDownloader/7cdde347dd734830c0ee7dfa3b97cc0cf2d7dfbf/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zsakvo/99LibraryDownloader/7cdde347dd734830c0ee7dfa3b97cc0cf2d7dfbf/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | 九九藏书
3 |
4 |
--------------------------------------------------------------------------------
/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
--------------------------------------------------------------------------------
/app/src/test/java/cc/zsakvo/a99demo/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package cc.zsakvo.a99demo;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.*;
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * @see Testing documentation
11 | */
12 | public class ExampleUnitTest {
13 | @Test
14 | public void addition_isCorrect() throws Exception {
15 | assertEquals(4, 2 + 2);
16 | }
17 | }
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 |
3 | buildscript {
4 |
5 | repositories {
6 | google()
7 | jcenter()
8 | }
9 | dependencies {
10 | classpath 'com.android.tools.build:gradle:3.0.1'
11 |
12 |
13 | // NOTE: Do not place your application dependencies here; they belong
14 | // in the individual module build.gradle files
15 | }
16 | }
17 |
18 | allprojects {
19 | repositories {
20 | google()
21 | jcenter()
22 | maven { url 'https://jitpack.io' }
23 | }
24 | }
25 |
26 | task clean(type: Delete) {
27 | delete rootProject.buildDir
28 | }
29 |
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | ## Project-wide Gradle settings.
2 | #
3 | # For more details on how to configure your build environment visit
4 | # http://www.gradle.org/docs/current/userguide/build_environment.html
5 | #
6 | # Specifies the JVM arguments used for the daemon process.
7 | # The setting is particularly useful for tweaking memory settings.
8 | # Default value: -Xmx1024m -XX:MaxPermSize=256m
9 | # org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
10 | #
11 | # When configured, Gradle will run in incubating parallel mode.
12 | # This option should only be used with decoupled projects. More details, visit
13 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
14 | # org.gradle.parallel=true
15 | #Wed Feb 14 17:16:12 CST 2018
16 | systemProp.https.proxyPort=1087
17 | systemProp.http.proxyHost=127.0.0.1
18 | org.gradle.jvmargs=-Xmx1536m
19 | systemProp.https.proxyHost=127.0.0.1
20 | systemProp.http.proxyPort=1087
21 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zsakvo/99LibraryDownloader/7cdde347dd734830c0ee7dfa3b97cc0cf2d7dfbf/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Wed Feb 14 17:16:07 CST 2018
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-4.1-all.zip
7 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
10 | DEFAULT_JVM_OPTS=""
11 |
12 | APP_NAME="Gradle"
13 | APP_BASE_NAME=`basename "$0"`
14 |
15 | # Use the maximum available, or set MAX_FD != -1 to use that value.
16 | MAX_FD="maximum"
17 |
18 | warn ( ) {
19 | echo "$*"
20 | }
21 |
22 | die ( ) {
23 | echo
24 | echo "$*"
25 | echo
26 | exit 1
27 | }
28 |
29 | # OS specific support (must be 'true' or 'false').
30 | cygwin=false
31 | msys=false
32 | darwin=false
33 | case "`uname`" in
34 | CYGWIN* )
35 | cygwin=true
36 | ;;
37 | Darwin* )
38 | darwin=true
39 | ;;
40 | MINGW* )
41 | msys=true
42 | ;;
43 | esac
44 |
45 | # Attempt to set APP_HOME
46 | # Resolve links: $0 may be a link
47 | PRG="$0"
48 | # Need this for relative symlinks.
49 | while [ -h "$PRG" ] ; do
50 | ls=`ls -ld "$PRG"`
51 | link=`expr "$ls" : '.*-> \(.*\)$'`
52 | if expr "$link" : '/.*' > /dev/null; then
53 | PRG="$link"
54 | else
55 | PRG=`dirname "$PRG"`"/$link"
56 | fi
57 | done
58 | SAVED="`pwd`"
59 | cd "`dirname \"$PRG\"`/" >/dev/null
60 | APP_HOME="`pwd -P`"
61 | cd "$SAVED" >/dev/null
62 |
63 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
64 |
65 | # Determine the Java command to use to start the JVM.
66 | if [ -n "$JAVA_HOME" ] ; then
67 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
68 | # IBM's JDK on AIX uses strange locations for the executables
69 | JAVACMD="$JAVA_HOME/jre/sh/java"
70 | else
71 | JAVACMD="$JAVA_HOME/bin/java"
72 | fi
73 | if [ ! -x "$JAVACMD" ] ; then
74 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
75 |
76 | Please set the JAVA_HOME variable in your environment to match the
77 | location of your Java installation."
78 | fi
79 | else
80 | JAVACMD="java"
81 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
82 |
83 | Please set the JAVA_HOME variable in your environment to match the
84 | location of your Java installation."
85 | fi
86 |
87 | # Increase the maximum file descriptors if we can.
88 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
89 | MAX_FD_LIMIT=`ulimit -H -n`
90 | if [ $? -eq 0 ] ; then
91 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
92 | MAX_FD="$MAX_FD_LIMIT"
93 | fi
94 | ulimit -n $MAX_FD
95 | if [ $? -ne 0 ] ; then
96 | warn "Could not set maximum file descriptor limit: $MAX_FD"
97 | fi
98 | else
99 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
100 | fi
101 | fi
102 |
103 | # For Darwin, add options to specify how the application appears in the dock
104 | if $darwin; then
105 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
106 | fi
107 |
108 | # For Cygwin, switch paths to Windows format before running java
109 | if $cygwin ; then
110 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
111 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
112 | JAVACMD=`cygpath --unix "$JAVACMD"`
113 |
114 | # We build the pattern for arguments to be converted via cygpath
115 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
116 | SEP=""
117 | for dir in $ROOTDIRSRAW ; do
118 | ROOTDIRS="$ROOTDIRS$SEP$dir"
119 | SEP="|"
120 | done
121 | OURCYGPATTERN="(^($ROOTDIRS))"
122 | # Add a user-defined pattern to the cygpath arguments
123 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
124 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
125 | fi
126 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
127 | i=0
128 | for arg in "$@" ; do
129 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
130 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
131 |
132 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
133 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
134 | else
135 | eval `echo args$i`="\"$arg\""
136 | fi
137 | i=$((i+1))
138 | done
139 | case $i in
140 | (0) set -- ;;
141 | (1) set -- "$args0" ;;
142 | (2) set -- "$args0" "$args1" ;;
143 | (3) set -- "$args0" "$args1" "$args2" ;;
144 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
145 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
146 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
147 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
148 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
149 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
150 | esac
151 | fi
152 |
153 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
154 | function splitJvmOpts() {
155 | JVM_OPTS=("$@")
156 | }
157 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
158 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
159 |
160 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
161 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
12 | set DEFAULT_JVM_OPTS=
13 |
14 | set DIRNAME=%~dp0
15 | if "%DIRNAME%" == "" set DIRNAME=.
16 | set APP_BASE_NAME=%~n0
17 | set APP_HOME=%DIRNAME%
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windowz variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 | if "%@eval[2+2]" == "4" goto 4NT_args
53 |
54 | :win9xME_args
55 | @rem Slurp the command line arguments.
56 | set CMD_LINE_ARGS=
57 | set _SKIP=2
58 |
59 | :win9xME_args_slurp
60 | if "x%~1" == "x" goto execute
61 |
62 | set CMD_LINE_ARGS=%*
63 | goto execute
64 |
65 | :4NT_args
66 | @rem Get arguments from the 4NT Shell from JP Software
67 | set CMD_LINE_ARGS=%$
68 |
69 | :execute
70 | @rem Setup the command line
71 |
72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if "%ERRORLEVEL%"=="0" goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
85 | exit /b 1
86 |
87 | :mainEnd
88 | if "%OS%"=="Windows_NT" endlocal
89 |
90 | :omega
91 |
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app'
2 |
--------------------------------------------------------------------------------