新增书架同步、关于界面

pull/5/head
fengyuecanzhu 4 years ago
parent c99a202297
commit f17c8e1406
  1. 1
      app/src/main/AndroidManifest.xml
  2. 3
      app/src/main/assets/disclaimer.fy
  3. 149
      app/src/main/assets/updatelog.fy
  4. 127
      app/src/main/java/xyz/fycz/myreader/application/MyApplication.java
  5. 1
      app/src/main/java/xyz/fycz/myreader/application/SysManager.java
  6. 83
      app/src/main/java/xyz/fycz/myreader/backup/UserService.java
  7. 5
      app/src/main/java/xyz/fycz/myreader/creator/APPDownloadTip.java
  8. 31
      app/src/main/java/xyz/fycz/myreader/creator/DialogCreator.java
  9. 10
      app/src/main/java/xyz/fycz/myreader/entity/Setting.java
  10. 86
      app/src/main/java/xyz/fycz/myreader/ui/about/AboutActivity.java
  11. 61
      app/src/main/java/xyz/fycz/myreader/ui/about/AboutPresent.java
  12. 24
      app/src/main/java/xyz/fycz/myreader/ui/bookinfo/BookInfoPresenter.java
  13. 127
      app/src/main/java/xyz/fycz/myreader/ui/home/bookcase/BookcaseDetailedAdapter.java
  14. 216
      app/src/main/java/xyz/fycz/myreader/ui/home/bookcase/BookcasePresenter.java
  15. 7
      app/src/main/java/xyz/fycz/myreader/ui/search/SearchBookPrensenter.java
  16. 7
      app/src/main/java/xyz/fycz/myreader/ui/user/LoginPresenter.java
  17. 24
      app/src/main/java/xyz/fycz/myreader/util/ShareUtils.java
  18. 11
      app/src/main/res/drawable/ic_about.xml
  19. 14
      app/src/main/res/drawable/ic_launch.xml
  20. 26
      app/src/main/res/drawable/ic_list.xml
  21. 11
      app/src/main/res/drawable/ic_online_syn.xml
  22. 14
      app/src/main/res/drawable/ic_share.xml
  23. 18
      app/src/main/res/layout/activity_about.xml
  24. 283
      app/src/main/res/layout/layout_about_content.xml
  25. 20
      app/src/main/res/menu/menu_book.xml
  26. 19
      app/src/main/res/values/strings.xml
  27. 4
      app/version_code.properties

@ -94,6 +94,7 @@
<activity android:name=".ui.user.RegisterActivity"> <activity android:name=".ui.user.RegisterActivity">
</activity> </activity>
<activity android:name=".ui.read.catalog.CatalogActivity"> <activity android:name=".ui.read.catalog.CatalogActivity">
</activity><activity android:name=".ui.about.AboutActivity">
</activity> </activity>
</application> </application>

@ -1,4 +1,7 @@
1、 风月读书是一款提供网络文学搜索的工具,为广大网络文学爱好者提供一种方便、快捷舒适的试读体验。 1、 风月读书是一款提供网络文学搜索的工具,为广大网络文学爱好者提供一种方便、快捷舒适的试读体验。
2、 当您搜索一本书的时,风月读书会将该书的书名以关键词的形式提交到各个第三方网络文学网站。各第三方网站返回的内容与风月读书无关,风月读书对其概不负责,亦不承担任何法律责任。任何通过使用风月读书而链接到的第三方网页均系他人制作或提供,您可能从第三方网页上获得其他服务,风月读书对其合法性概不负责,亦不承担任何法律责任。第三方搜索引擎结果根据您提交的书名自动搜索获得并提供试读,不代表风月读书赞成或被搜索链接到的第三方网页上的内容或立场。您应该对使用搜索引擎的结果自行承担风险。 2、 当您搜索一本书的时,风月读书会将该书的书名以关键词的形式提交到各个第三方网络文学网站。各第三方网站返回的内容与风月读书无关,风月读书对其概不负责,亦不承担任何法律责任。任何通过使用风月读书而链接到的第三方网页均系他人制作或提供,您可能从第三方网页上获得其他服务,风月读书对其合法性概不负责,亦不承担任何法律责任。第三方搜索引擎结果根据您提交的书名自动搜索获得并提供试读,不代表风月读书赞成或被搜索链接到的第三方网页上的内容或立场。您应该对使用搜索引擎的结果自行承担风险。
3、 风月读书不做任何形式的保证:不保证第三方搜索引擎的搜索结果满足您的要求,不保证搜索服务不中断,不保证搜索结果的安全性、正确性、及时性、合法性。因网络状况、通讯线路、第三方网站等任何原因而导致您不能正常使用阅读,风月读书不承担任何法律责任。风月读书尊重并保护所有使用风月读书用户的个人隐私权,您注册的用户名、电子邮件地址等个人资料,非经您亲自许可或根据相关法律、法规的强制性规定,风月读书不会主动地泄露给第三方。 3、 风月读书不做任何形式的保证:不保证第三方搜索引擎的搜索结果满足您的要求,不保证搜索服务不中断,不保证搜索结果的安全性、正确性、及时性、合法性。因网络状况、通讯线路、第三方网站等任何原因而导致您不能正常使用阅读,风月读书不承担任何法律责任。风月读书尊重并保护所有使用风月读书用户的个人隐私权,您注册的用户名、电子邮件地址等个人资料,非经您亲自许可或根据相关法律、法规的强制性规定,风月读书不会主动地泄露给第三方。
4、 风月读书致力于最大程度地减少网络文学阅读者在自行搜寻过程中的无意义的时间浪费,通过专业搜索展示不同网站中网络文学的最新章节。风月读书在为广大小说爱好者提供方便、快捷舒适的试读体验的同时,也使优秀网络文学得以迅速、更广泛的传播,从而达到了在一定程度促进网络文学充分繁荣发展之目的。风月读书鼓励广大小说爱好者通过风月读书发现优秀网络小说及其提供商,并建议阅读正版图书。任何单位或个人认为通过风月读书搜索链接到的第三方网页内容可能涉嫌侵犯其信息网络传播权,应该及时向风月读书提出书面权力通知,并提供身份证明、权属证明及详细侵权情况证明。风月读书在收到上述法律文件后,将会依法尽快断开相关链接内容。 4、 风月读书致力于最大程度地减少网络文学阅读者在自行搜寻过程中的无意义的时间浪费,通过专业搜索展示不同网站中网络文学的最新章节。风月读书在为广大小说爱好者提供方便、快捷舒适的试读体验的同时,也使优秀网络文学得以迅速、更广泛的传播,从而达到了在一定程度促进网络文学充分繁荣发展之目的。风月读书鼓励广大小说爱好者通过风月读书发现优秀网络小说及其提供商,并建议阅读正版图书。任何单位或个人认为通过风月读书搜索链接到的第三方网页内容可能涉嫌侵犯其信息网络传播权,应该及时向风月读书提出书面权力通知,并提供身份证明、权属证明及详细侵权情况证明。风月读书在收到上述法律文件后,将会依法尽快断开相关链接内容。

@ -0,0 +1,149 @@
2020.07.31
风月读书v1.20.073114
1、新增书架同步功能(需要注册登录)
2、新增每日自动同步书架功能(默认关闭)
3、新增书籍一键缓存功能(实验功能,存在bug)
4、新增关于界面(检查更新、免责声明移至此界面)
5、修复正在自动翻页退出阅读时闪退的问题
6、修复软件\字体下载api
2020.07.25
风月读书v1.20.072519
1、新增自动翻页
2、新增目录\书签章节标题搜索
3、升级SDK版本,更新各种依赖(因组件升级,会重置设置)
2020.07.22
风月读书v1.20.072217
1、修复书源“天籁小说”、“品书网”
2、新增书签功能
3、优化目录UI,并添加书签列表
4、修复概率性无法搜索到书籍的问题
5、修复阅读界面退出时概率性闪退问题
注:本次更新修复书源,故采用强制更新
2020.07.20
风月读书v1.20.072009
1、修复阅读界面“正在加载”时不显示章节内容的问题
2、修复阅读界面加载时退出闪退的问题
3、修复本地书籍重复添加的问题
4、修复阅读设置界面刷新按钮无效的问题
5、添加本地书籍缓存和源文件被删除后书籍无法加载的提示信息
6、行书字体更换为方正硬笔行书
2020.07.18
风月读书v1.20.071809
1、修复软件内更新下载字体下载失效的问题
2、修复添加本地书籍的已知bug
3、修复更换字体后阅读页面显示的问题
3、优化书籍阅读时下一章节加载速度
2020.07.14
风月读书v1.20.071415
1、新增本地书籍导入,支持直接打开txt书籍文件(如书籍文件太大,拆分章节较慢,请耐心等待)
2、新增登录与注册
3、新增网络备份与恢复
4、修复已知bug
2020.07.07
风月读书v1.20.070721
1、新增可选择本地字体
2、新增可在书架缓存书籍
3、新增书籍移至顶部
4、修复已知bug
2020.07.02
风月读书v1.20.070219
1、修复软件更新及字体下载获取连接失败的问题
2、提高连接获取速度
3、优化阅读界面初次加载速度
2020.06.30
风月读书v1.20.063020
1、新增软件内更新机制
2、优化字体下载机制,提升字体下载速度
3、修复字体下载失败时书籍无法阅读的问题
2020.06.08
风月读书v1.20.060815
1、优化书籍缓存机制,减小书籍章节数据占用的空间,提高章节加载速度
2、修复书籍换源\恢复后初次加载章节内容失败的问题
2020.06.05
风月读书v1.20.060518
1、修复部分书籍备份后无法恢复的问题
2、优化阅读界面设置切换速度
2020.05.26
风月读书v1.20.052610
1、优化最后一页提示
2、修复概率性最新章节显示错误的问题
2020.05.23
风月读书v1.20.052311
1、修复部分书籍换源时无显示的bug
2、修复书籍详情页移除书籍后添加书架失败的bug
3、新增缓存导出
4、修复其他已知bug
2020.05.22
风月读书v1.20.052210
1、安装包删除自带字体,减小安装包体积,字体可在软件内下载
2、新增小说缓存导出
3、修复换源时书源概率性重复的bug
4、修复初次加载或未联网时目录倒序不显示的bug
5、修复其他已知bug
2020.05.20
风月读书v1.20.052021
1、新增书源品书网(当前共4个书源)
2、新增书城笔趣阁书源可搜索
3、修复已知bug
2020.05.19
风月读书v1.20.051921
1、搜索界面合并不同书源的相同书籍
2、书籍详情新增切换书源功能
3、修复搜索是重复出现书籍列表的bug
4、修复其他已知bug
2020.05.18
风月读书v1.20.051816
1、修复更改书源后章节失去第一段的问题(需重新加载小说内容)
2、修复未联网进入软件闪退的问题
3、修复其他已知bug
2020.05.18
风月读书v1.20.051810
1、新增书城
2、新增书源天籁小说(可搜索)、笔趣阁(仅限在书城查找)
3、修复搜索界面只显示书名和作者的问题
4、修复其他已知bug
2020.05.17
风月读书v1.20.051716
1、更改小说源为笔趣44(由于风月小说网的问题,部分小说无法阅读,故做此修改,以后版本会添加多个书源)
2、特别注意:本次更新需要卸载原软件,会清除所有小说数据(可先备份书架再卸载)!!!
3、由于更改小说源,搜索界面暂时只显示书名和作者,进入详情页即可显示书籍其他信息
4、新增免责声明
2020.04.27
风月读书v1.20.042720
1、新增书架备份与恢复
2、新增登录界面(内测中,可通过网络进行书架备份与恢复)
3、修复已知bug
2020.04.24
风月读书v1.20.042420更新内容:
1、新增布局切换
2、优化刷新
3、新增阅读百分比
4、修复进入阅读界面时的亮度偏暗bug
5、更改更新策略:每次更新版本只会提示一次,取消后如需更新,可手动检查更新
2020.04.21
风月读书v1.1.4更新内容:
1、更换书架布局(列表布局),将在下个版本添加布局切换
2、新增缓存提示对话框
3、取消自动刷新,新增下拉刷新(需要安卓6.0以上版本)
4、修复若干已知bug

@ -3,6 +3,7 @@ package xyz.fycz.myreader.application;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
import android.annotation.TargetApi; import android.annotation.TargetApi;
import android.app.Activity;
import android.app.Application; import android.app.Application;
import android.app.NotificationChannel; import android.app.NotificationChannel;
import android.app.NotificationManager; import android.app.NotificationManager;
@ -239,57 +240,59 @@ public class MyApplication extends Application {
} }
}); });
}*/ }*/
public static void checkVersionByServer(final MainActivity activity, final boolean isManualCheck, public static void checkVersionByServer(final BaseActivity activity, final boolean isManualCheck,
final BookcaseFragment mBookcaseFragment) { final BookcaseFragment mBookcaseFragment) {
MyApplication.getApplication().newThread(new Runnable() { MyApplication.getApplication().newThread(() -> {
@Override Document doc = null;
public void run() { try {
Document doc = null; String url = "https://shimo.im/docs/cqkgjPRRydYYhQKt/read";
try { if (isApkInDebug(getmContext())){
String url = "https://shimo.im/docs/cqkgjPRRydYYhQKt/read"; url = "https://shimo.im/docs/zfzpda7MUGskOC9v/read";
if (isApkInDebug(getmContext())){ }
url = "https://shimo.im/docs/zfzpda7MUGskOC9v/read"; doc = Jsoup.connect(url).get();
} String content = doc.getElementsByClass("ql-editor").text();
doc = Jsoup.connect(url).get(); if (StringHelper.isEmpty(content)){
String content = doc.getElementsByClass("ql-editor").text(); TextHelper.showText("检查更新失败!");
if (StringHelper.isEmpty(content)){ return;
TextHelper.showText("检查更新失败!"); }
return; String[] contents = content.split(";");
} int newestVersion = 0;
String[] contents = content.split(";"); String updateContent = "";
int newestVersion = 0; String downloadLink = null;
String updateContent = ""; boolean isForceUpdate = false;
String downloadLink = null; StringBuilder s = new StringBuilder();
boolean isForceUpdate = false; newestVersion = Integer.parseInt(contents[0].substring(contents[0].indexOf(":") + 1));
StringBuilder s = new StringBuilder(); isForceUpdate = Boolean.parseBoolean(contents[1].substring(contents[1].indexOf(":") + 1));
newestVersion = Integer.parseInt(contents[0].substring(contents[0].indexOf(":") + 1)); downloadLink = contents[2].substring(contents[2].indexOf(":") + 1).trim();
isForceUpdate = Boolean.parseBoolean(contents[1].substring(contents[1].indexOf(":") + 1)); updateContent = contents[3].substring(contents[3].indexOf(":") + 1);
downloadLink = contents[2].substring(contents[2].indexOf(":") + 1); SharedPreUtils spu = SharedPreUtils.getInstance();
updateContent = contents[3].substring(contents[3].indexOf(":") + 1); spu.putString("lanzousKeyStart", contents[4].substring(contents[4].indexOf(":") + 1));
SharedPreUtils spu = SharedPreUtils.getInstance(); if (!StringHelper.isEmpty(downloadLink)){
spu.putString("lanzousKeyStart", contents[4].substring(contents[4].indexOf(":") + 1)); spu.putString("downloadLink", downloadLink);
String[] updateContents = updateContent.split("/"); }else {
for (String string : updateContents) { spu.putString("downloadLink", URLCONST.APP_DIR_UR);
s.append(string); }
s.append("\n"); String[] updateContents = updateContent.split("/");
} for (String string : updateContents) {
int versionCode = getVersionCode(); s.append(string);
if (newestVersion > versionCode) { s.append("\n");
MyApplication m = new MyApplication(); }
Setting setting = SysManager.getSetting(); int versionCode = getVersionCode();
if (isManualCheck || setting.getNewestVersionCode() < newestVersion || isForceUpdate) { if (newestVersion > versionCode) {
setting.setNewestVersionCode(newestVersion); MyApplication m = new MyApplication();
SysManager.saveSetting(setting); Setting setting = SysManager.getSetting();
m.updateApp(activity, downloadLink, newestVersion, s.toString(), isForceUpdate, if (isManualCheck || setting.getNewestVersionCode() < newestVersion || isForceUpdate) {
mBookcaseFragment); setting.setNewestVersionCode(newestVersion);
} SysManager.saveSetting(setting);
} else if (isManualCheck) { m.updateApp(activity, downloadLink, newestVersion, s.toString(), isForceUpdate,
TextHelper.showText("已经是最新版本!"); mBookcaseFragment);
} }
} catch (Exception e) { } else if (isManualCheck) {
e.printStackTrace(); TextHelper.showText("已经是最新版本!");
TextHelper.showText("无网络连接!");
} }
} catch (Exception e) {
e.printStackTrace();
TextHelper.showText("无网络连接!");
} }
}); });
} }
@ -300,7 +303,7 @@ public class MyApplication extends Application {
* @param activity * @param activity
* @param versionCode * @param versionCode
*/ */
public void updateApp(final MainActivity activity, final String url, final int versionCode, String message, public void updateApp(final BaseActivity activity, final String url, final int versionCode, String message,
final boolean isForceUpdate, final BookcaseFragment mBookcaseFragment) { final boolean isForceUpdate, final BookcaseFragment mBookcaseFragment) {
//String version = (versionCode / 100 % 10) + "." + (versionCode / 10 % 10) + "." + (versionCode % 10); //String version = (versionCode / 100 % 10) + "." + (versionCode / 10 % 10) + "." + (versionCode % 10);
String cancelTitle; String cancelTitle;
@ -309,6 +312,12 @@ public class MyApplication extends Application {
}else { }else {
cancelTitle = "忽略此版本"; cancelTitle = "忽略此版本";
} }
if (mBookcaseFragment == null){
DialogCreator.createCommonDialog(activity, "发现新版本:", message, true, "取消", "立即更新", null,
(dialog, which) -> goDownload(activity, url));
return;
}
DialogCreator.createThreeButtonDialog(activity, "发现新版本:", message, !isForceUpdate, cancelTitle, "直接下载", DialogCreator.createThreeButtonDialog(activity, "发现新版本:", message, !isForceUpdate, cancelTitle, "直接下载",
"浏览器下载", (dialog, which) -> { "浏览器下载", (dialog, which) -> {
if (isForceUpdate) { if (isForceUpdate) {
@ -329,20 +338,24 @@ public class MyApplication extends Application {
downloadTip.downloadApp(); downloadTip.downloadApp();
} }
}, (dialog, which) -> { }, (dialog, which) -> {
String downloadLink = url; goDownload(activity, url);
if (url == null || "".equals(url)) {
downloadLink = URLCONST.APP_DIR_UR;
}
Intent intent = new Intent();
intent.setAction(Intent.ACTION_VIEW);
intent.setData(Uri.parse(downloadLink));
activity.startActivity(intent);
if (isForceUpdate) { if (isForceUpdate) {
activity.finish(); activity.finish();
} }
}); });
} }
private void goDownload(Activity activity, String url){
String downloadLink = url;
if (url == null || "".equals(url)) {
downloadLink = URLCONST.APP_DIR_UR;
}
Intent intent = new Intent();
intent.setAction(Intent.ACTION_VIEW);
intent.setData(Uri.parse(downloadLink));
activity.startActivity(intent);
}
/** /**
* 判断当前应用是否是debug状态 * 判断当前应用是否是debug状态
*/ */

@ -62,6 +62,7 @@ public class SysManager {
setting.setBookcaseStyle(BookcaseStyle.listMode); setting.setBookcaseStyle(BookcaseStyle.listMode);
setting.setNewestVersionCode(getVersionCode()); setting.setNewestVersionCode(getVersionCode());
setting.setLocalFontName(""); setting.setLocalFontName("");
setting.setAutoSyn(false);
setting.setSettingVersion(APPCONST.SETTING_VERSION); setting.setSettingVersion(APPCONST.SETTING_VERSION);
return setting; return setting;
} }

@ -63,43 +63,40 @@ public class UserService {
} }
public static void register(final Map<String, String> userRegisterInfo, final ResultCallback resultCallback) { public static void register(final Map<String, String> userRegisterInfo, final ResultCallback resultCallback) {
MyApplication.getApplication().newThread(new Runnable() { MyApplication.getApplication().newThread(() -> {
@Override HttpURLConnection conn = null;
public void run() { try {
HttpURLConnection conn = null; URL url = new URL(URLCONST.APP_WEB_URL + "reg");
try { conn = (HttpURLConnection) url.openConnection();
URL url = new URL(URLCONST.APP_WEB_URL + "reg"); conn.setRequestMethod("POST");
conn = (HttpURLConnection) url.openConnection(); conn.setDoInput(true);
conn.setRequestMethod("POST"); conn.setDoOutput(true);
conn.setDoInput(true); String params = "username=" + userRegisterInfo.get("username") + "&password=" +
conn.setDoOutput(true); CyptoUtils.encode(APPCONST.KEY, userRegisterInfo.get("password")) + "&key=" +
String params = "username=" + userRegisterInfo.get("username") + "&password=" + CyptoUtils.encode(APPCONST.KEY, APPCONST.publicKey) + makeSignalParam();
CyptoUtils.encode(APPCONST.KEY, userRegisterInfo.get("password")) + "&key=" + // 获取URLConnection对象对应的输出流
CyptoUtils.encode(APPCONST.KEY, APPCONST.publicKey) + makeSignalParam(); PrintWriter out = new PrintWriter(conn.getOutputStream());
// 获取URLConnection对象对应的输出流 // 发送请求参数
PrintWriter out = new PrintWriter(conn.getOutputStream()); out.print(params);
// 发送请求参数 // flush输出流的缓冲
out.print(params); out.flush();
// flush输出流的缓冲 BufferedReader bw = new BufferedReader(new InputStreamReader(conn.getInputStream(), "utf-8"));
out.flush(); StringBuilder sb = new StringBuilder();
BufferedReader bw = new BufferedReader(new InputStreamReader(conn.getInputStream(), "utf-8")); String line = bw.readLine();
StringBuilder sb = new StringBuilder(); while (line != null) {
String line = bw.readLine(); sb.append(line);
while (line != null) { line = bw.readLine();
sb.append(line); }
line = bw.readLine(); resultCallback.onFinish(sb.toString(), 1);
} } catch (IOException e) {
resultCallback.onFinish(sb.toString(), 1); e.printStackTrace();
} catch (IOException e) { resultCallback.onError(e);
e.printStackTrace(); } finally {
resultCallback.onError(e); if (conn != null) {
} finally { conn.disconnect();
if (conn != null) {
conn.disconnect();
}
} }
} }
}); });
} }
@ -122,13 +119,7 @@ public class UserService {
e.printStackTrace(); e.printStackTrace();
return false; return false;
} finally { } finally {
if (fos != null) { IOUtils.close(fos);
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
} }
} }
@ -159,13 +150,7 @@ public class UserService {
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
}finally { }finally {
if (br != null) { IOUtils.close(br);
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
} }
return null; return null;
} }

@ -14,6 +14,7 @@ import android.provider.Settings;
import androidx.core.content.FileProvider; import androidx.core.content.FileProvider;
import android.view.View; import android.view.View;
import xyz.fycz.myreader.application.MyApplication; import xyz.fycz.myreader.application.MyApplication;
import xyz.fycz.myreader.base.BaseActivity;
import xyz.fycz.myreader.callback.ResultCallback; import xyz.fycz.myreader.callback.ResultCallback;
import xyz.fycz.myreader.common.APPCONST; import xyz.fycz.myreader.common.APPCONST;
import xyz.fycz.myreader.ui.home.MainActivity; import xyz.fycz.myreader.ui.home.MainActivity;
@ -42,10 +43,10 @@ public class APPDownloadTip {
private MainActivity activity; private MainActivity activity;
private boolean isForceUpdate; private boolean isForceUpdate;
public APPDownloadTip(String url, BookcaseFragment mBookcaseFragment, MainActivity activity, boolean isForceUpdate) { public APPDownloadTip(String url, BookcaseFragment mBookcaseFragment, BaseActivity activity, boolean isForceUpdate) {
this.url = url; this.url = url;
this.mBookcaseFragment = mBookcaseFragment; this.mBookcaseFragment = mBookcaseFragment;
this.activity = activity; this.activity = (MainActivity) activity;
this.isForceUpdate = isForceUpdate; this.isForceUpdate = isForceUpdate;
} }

@ -31,8 +31,13 @@ import xyz.fycz.myreader.enums.ReadStyle;
import xyz.fycz.myreader.greendao.entity.Book; import xyz.fycz.myreader.greendao.entity.Book;
import xyz.fycz.myreader.greendao.entity.Chapter; import xyz.fycz.myreader.greendao.entity.Chapter;
import xyz.fycz.myreader.util.BrightUtil; import xyz.fycz.myreader.util.BrightUtil;
import xyz.fycz.myreader.util.IOUtils;
import xyz.fycz.myreader.util.StringHelper; import xyz.fycz.myreader.util.StringHelper;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import static xyz.fycz.myreader.enums.ReadStyle.blueDeep; import static xyz.fycz.myreader.enums.ReadStyle.blueDeep;
import static xyz.fycz.myreader.enums.ReadStyle.breen; import static xyz.fycz.myreader.enums.ReadStyle.breen;
import static xyz.fycz.myreader.enums.ReadStyle.common; import static xyz.fycz.myreader.enums.ReadStyle.common;
@ -701,7 +706,7 @@ public class DialogCreator {
} }
}); });
} }
public static void createTipDialog(Context mContext, String title,String message){ public static void createTipDialog(Context mContext, String title, String message){
DialogCreator.createCommonDialog(mContext, title, DialogCreator.createCommonDialog(mContext, title,
message, true, "知道了", new DialogInterface.OnClickListener() { message, true, "知道了", new DialogInterface.OnClickListener() {
@Override @Override
@ -711,6 +716,30 @@ public class DialogCreator {
}); });
} }
/**
* 从assets文件夹之中读取文件并显示提示框
* @param mContext
* @param title
* @param assetName
*/
public static void createAssetTipDialog(Context mContext, String title, String assetName){
BufferedReader br = null;
try {
br = new BufferedReader(new InputStreamReader(mContext.getAssets().open(assetName)));
StringBuilder assetText = new StringBuilder();
String line = null;
while ((line = br.readLine()) != null) {
assetText.append(line);
assetText.append("\r\n");
}
DialogCreator.createTipDialog(mContext, title, assetText.toString());
} catch (IOException e) {
e.printStackTrace();
} finally {
IOUtils.close(br);
}
}
public interface OnClickPositiveListener { public interface OnClickPositiveListener {
void onClick(Dialog dialog, View view); void onClick(Dialog dialog, View view);
} }

@ -41,6 +41,8 @@ public class Setting implements Serializable {
private String localFontName;//本地字体名字 private String localFontName;//本地字体名字
private boolean isAutoSyn;//是否自动同步书架
private int settingVersion;//设置版本号 private int settingVersion;//设置版本号
public int getAutoScrollSpeed() { public int getAutoScrollSpeed() {
@ -163,6 +165,14 @@ public class Setting implements Serializable {
this.localFontName = localFontName; this.localFontName = localFontName;
} }
public boolean isAutoSyn() {
return isAutoSyn;
}
public void setAutoSyn(boolean autoSyn) {
isAutoSyn = autoSyn;
}
public int getSettingVersion() { public int getSettingVersion() {
return settingVersion; return settingVersion;
} }

@ -0,0 +1,86 @@
package xyz.fycz.myreader.ui.about;
import android.os.Bundle;
import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.cardview.widget.CardView;
import butterknife.BindView;
import butterknife.ButterKnife;
import com.google.android.material.tabs.TabLayout;
import xyz.fycz.myreader.R;
import xyz.fycz.myreader.base.BaseActivity;
/**
* @author fengyue
* @date 2020/7/31 11:32
*/
public class AboutActivity extends BaseActivity {
@BindView(R.id.ll_title_back)
LinearLayout llTitleBack;
@BindView(R.id.tv_title_text)
TextView tvTitleText;
@BindView(R.id.tv_version_name)
TextView tvVersionName;
@BindView(R.id.vm_author)
CardView vmAuthor;
@BindView(R.id.vw_share)
CardView vmShare;
@BindView(R.id.vw_update)
CardView vmUpdate;
@BindView(R.id.vw_update_log)
CardView vmUpdateLog;
@BindView(R.id.vw_git)
CardView vmGit;
@BindView(R.id.vw_disclaimer)
CardView vmDisclaimer;
private AboutPresent mAboutPresent;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_about);
ButterKnife.bind(this);
setStatusBar(R.color.sys_line);
mAboutPresent = new AboutPresent(this);
mAboutPresent.start();
}
public LinearLayout getLlTitleBack() {
return llTitleBack;
}
public TextView getTvTitleText() {
return tvTitleText;
}
public TextView getTvVersionName() {
return tvVersionName;
}
public CardView getVmAuthor() {
return vmAuthor;
}
public CardView getVmShare() {
return vmShare;
}
public CardView getVmUpdate() {
return vmUpdate;
}
public CardView getVmUpdateLog() {
return vmUpdateLog;
}
public CardView getVmGit() {
return vmGit;
}
public CardView getVmDisclaimer() {
return vmDisclaimer;
}
}

@ -0,0 +1,61 @@
package xyz.fycz.myreader.ui.about;
import android.annotation.SuppressLint;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import xyz.fycz.myreader.R;
import xyz.fycz.myreader.application.MyApplication;
import xyz.fycz.myreader.base.BasePresenter;
import xyz.fycz.myreader.creator.DialogCreator;
import xyz.fycz.myreader.util.ShareUtils;
import xyz.fycz.myreader.util.SharedPreUtils;
import xyz.fycz.myreader.util.TextHelper;
/**
* @author fengyue
* @date 2020/7/31 11:39
*/
public class AboutPresent implements BasePresenter {
private AboutActivity mAboutActivity;
public AboutPresent(AboutActivity mAboutActivity) {
this.mAboutActivity = mAboutActivity;
}
@SuppressLint("SetTextI18n")
@Override
public void start() {
mAboutActivity.getLlTitleBack().setOnClickListener(v -> mAboutActivity.finish());
mAboutActivity.getTvTitleText().setText("关于");
mAboutActivity.getTvVersionName().setText("风月读书v" + MyApplication.getStrVersionName());
mAboutActivity.getVmAuthor().setOnClickListener(v -> {
ClipboardManager mClipboardManager = (ClipboardManager) mAboutActivity.getSystemService(Context.CLIPBOARD_SERVICE);
//数据
ClipData mClipData = ClipData.newPlainText("Label", "fy@fycz.xyz");
//把数据设置到剪切板上
assert mClipboardManager != null;
mClipboardManager.setPrimaryClip(mClipData);
TextHelper.showText("邮箱复制成功!");
});
mAboutActivity.getVmShare().setOnClickListener(v -> ShareUtils.share(mAboutActivity, mAboutActivity.getString(R.string.share_text) +
SharedPreUtils.getInstance().getString("downloadLink")));
mAboutActivity.getVmUpdate().setOnClickListener(v -> MyApplication.checkVersionByServer(mAboutActivity, true, null));
mAboutActivity.getVmUpdateLog().setOnClickListener(v -> DialogCreator.createAssetTipDialog(mAboutActivity, "更新日志", "updatelog.fy"));
mAboutActivity.getVmGit().setOnClickListener(v -> openIntent(Intent.ACTION_VIEW, mAboutActivity.getString(R.string.this_github_url)));
mAboutActivity.getVmDisclaimer().setOnClickListener(v -> DialogCreator.createAssetTipDialog(mAboutActivity, "免责声明", "disclaimer.fy"));
}
void openIntent(String intentName, String address) {
try {
Intent intent = new Intent(intentName);
intent.setData(Uri.parse(address));
mAboutActivity.startActivity(intent);
} catch (Exception e) {
TextHelper.showText(e.getLocalizedMessage());
}
}
}

@ -108,29 +108,7 @@ public class BookInfoPresenter implements BasePresenter {
createChangeSourceDia(); createChangeSourceDia();
} }
}); });
mBookInfoActivity.getTvDisclaimer().setOnClickListener(v -> { mBookInfoActivity.getTvDisclaimer().setOnClickListener(v -> DialogCreator.createAssetTipDialog(mBookInfoActivity, "免责声明", "disclaimer.fy"));
BufferedReader br = null;
try {
br = new BufferedReader(new InputStreamReader(mBookInfoActivity.getAssets().open("disclaimer.fy")));
StringBuilder disclaimer = new StringBuilder();
String line = null;
while ((line = br.readLine()) != null) {
disclaimer.append(line);
disclaimer.append("\r\n\n");
}
DialogCreator.createTipDialog(mBookInfoActivity, "免责声明", disclaimer.toString());
} catch (IOException e) {
e.printStackTrace();
} finally {
if (br != null) {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
});
if (isBookCollected()) { if (isBookCollected()) {
mBookInfoActivity.getBtnAddBookcase().setText("移除书籍"); mBookInfoActivity.getBtnAddBookcase().setText("移除书籍");
mBookInfoActivity.getBtnReadBook().setText("继续阅读"); mBookInfoActivity.getBtnReadBook().setText("继续阅读");

@ -124,80 +124,65 @@ public class BookcaseDetailedAdapter extends BookcaseAdapter {
viewHolder.tvNoReadNum.setVisibility(View.GONE); viewHolder.tvNoReadNum.setVisibility(View.GONE);
} }
} }
viewHolder.llBookRead.setOnClickListener(new View.OnClickListener() { viewHolder.llBookRead.setOnClickListener(v -> {
@Override Intent intent = new Intent(mContext, ReadActivity.class);
public void onClick(View v) { intent.putExtra(APPCONST.BOOK, book);
Intent intent = new Intent(mContext, ReadActivity.class); book.setNoReadNum(0);
intent.putExtra(APPCONST.BOOK, book); mBookService.updateEntity(book);
book.setNoReadNum(0); mContext.startActivity(intent);
mBookService.updateEntity(book);
mContext.startActivity(intent);
}
}); });
viewHolder.ivBookImg.setOnClickListener(new View.OnClickListener() { viewHolder.ivBookImg.setOnClickListener(v -> {
@Override Intent intent = new Intent(mContext, BookInfoActivity.class);
public void onClick(View v) { intent.putExtra(APPCONST.BOOK, book);
Intent intent = new Intent(mContext, BookInfoActivity.class); mContext.startActivity(intent);
intent.putExtra(APPCONST.BOOK, book);
mContext.startActivity(intent);
}
}); });
viewHolder.llBookRead.setOnLongClickListener(new View.OnLongClickListener() { viewHolder.llBookRead.setOnLongClickListener(v -> {
@Override if (!ismEditState()) {
public boolean onLongClick(View v) { AlertDialog bookDialog = new AlertDialog.Builder(mContext)
if (!ismEditState()) { .setTitle(book.getName())
AlertDialog bookDialog = new AlertDialog.Builder(mContext) .setAdapter(new ArrayAdapter<>(mContext,
.setTitle(book.getName()) android.R.layout.simple_list_item_1, menu),
.setAdapter(new ArrayAdapter<>(mContext, (dialog, which) -> {
android.R.layout.simple_list_item_1, menu), switch (which) {
new DialogInterface.OnClickListener() { case 0:
@Override book.setSortCode(0);
public void onClick(DialogInterface dialog, int which) { mBookService.updateBook(book);
switch (which) { mBookcasePresenter.init();
case 0: TextHelper.showText("书籍《" + book.getName() + "》移至顶部成功!");
book.setSortCode(0); break;
mBookService.updateBook(book); case 1:
mBookcasePresenter.init(); downloadBook(book);
TextHelper.showText("书籍《" + book.getName() + "》移至顶部成功!"); break;
break; case 2:
case 1: MyApplication.getApplication().newThread(() -> {
downloadBook(book); try {
break; if (unionChapterCathe(book)) {
case 2: DialogCreator.createTipDialog(mContext,
MyApplication.getApplication().newThread(new Runnable() { "缓存导出成功,导出目录:"
@Override + APPCONST.TXT_BOOK_DIR);
public void run() { } else {
try { DialogCreator.createTipDialog(mContext,
if (unionChapterCathe(book)) { "章节目录为空或未找到缓存文件,缓存导出失败!");
DialogCreator.createTipDialog(mContext, }
"缓存导出成功,导出目录:" } catch (IOException e) {
+ APPCONST.TXT_BOOK_DIR); e.printStackTrace();
} else { DialogCreator.createTipDialog(mContext,
DialogCreator.createTipDialog(mContext, "章节目录为空或未找到缓存文件,缓存导出失败!");
"章节目录为空或未找到缓存文件,缓存导出失败!"); }
} });
} catch (IOException e) { break;
e.printStackTrace(); case 3:
DialogCreator.createTipDialog(mContext, showDeleteBookDialog(book);
"章节目录为空或未找到缓存文件,缓存导出失败!"); break;
} }
} })
}); .setNegativeButton(null, null)
break; .setPositiveButton(null, null)
case 3: .create();
showDeleteBookDialog(book); bookDialog.show();
break; return true;
}
}
})
.setNegativeButton(null, null)
.setPositiveButton(null, null)
.create();
bookDialog.show();
return true;
}
return false;
} }
return false;
}); });
} }
} }

@ -50,12 +50,11 @@ import xyz.fycz.myreader.greendao.entity.Book;
import xyz.fycz.myreader.greendao.entity.Chapter; import xyz.fycz.myreader.greendao.entity.Chapter;
import xyz.fycz.myreader.greendao.service.BookService; import xyz.fycz.myreader.greendao.service.BookService;
import xyz.fycz.myreader.greendao.service.ChapterService; import xyz.fycz.myreader.greendao.service.ChapterService;
import xyz.fycz.myreader.ui.about.AboutActivity;
import xyz.fycz.myreader.ui.home.MainActivity; import xyz.fycz.myreader.ui.home.MainActivity;
import xyz.fycz.myreader.ui.search.SearchBookActivity; import xyz.fycz.myreader.ui.search.SearchBookActivity;
import xyz.fycz.myreader.util.SharedPreUtils; import xyz.fycz.myreader.ui.user.LoginActivity;
import xyz.fycz.myreader.util.SharedPreferencesUtils; import xyz.fycz.myreader.util.*;
import xyz.fycz.myreader.util.StringHelper;
import xyz.fycz.myreader.util.TextHelper;
import xyz.fycz.myreader.util.utils.NetworkUtils; import xyz.fycz.myreader.util.utils.NetworkUtils;
import xyz.fycz.myreader.webapi.CommonApi; import xyz.fycz.myreader.webapi.CommonApi;
@ -71,15 +70,17 @@ public class BookcasePresenter implements BasePresenter {
private final ChapterService mChapterService; private final ChapterService mChapterService;
private final MainActivity mMainActivity; private final MainActivity mMainActivity;
private boolean isBookcaseStyleChange; private boolean isBookcaseStyleChange;
private final Setting mSetting; private Setting mSetting;
private final List<Book> errorLoadingBooks = new ArrayList<>(); private final List<Book> errorLoadingBooks = new ArrayList<>();
private int finishLoadBookCount = 0; private int finishLoadBookCount = 0;
private final BackupAndRestore mBackupAndRestore; private final BackupAndRestore mBackupAndRestore;
// private int notifyId = 11; // private int notifyId = 11;
private ExecutorService es = Executors.newFixedThreadPool(1);//更新/下载线程池 private ExecutorService es = Executors.newFixedThreadPool(1);//更新/下载线程池
public ExecutorService getEs() { public ExecutorService getEs() {
return es; return es;
} }
private String downloadingBook; private String downloadingBook;
private String downloadingChapter; private String downloadingChapter;
private boolean isDownloadFinish; private boolean isDownloadFinish;
@ -90,11 +91,10 @@ public class BookcasePresenter implements BasePresenter {
MyApplication.getmContext().getResources().getString(R.string.menu_backup_backup), MyApplication.getmContext().getResources().getString(R.string.menu_backup_backup),
MyApplication.getmContext().getResources().getString(R.string.menu_backup_restore), MyApplication.getmContext().getResources().getString(R.string.menu_backup_restore),
}; };
private final String[] webBackupMenu = { private final String[] webSynMenu = {
MyApplication.getmContext().getResources().getString(R.string.menu_backup_backup), MyApplication.getmContext().getString(R.string.menu_backup_webBackup),
MyApplication.getmContext().getResources().getString(R.string.menu_backup_restore), MyApplication.getmContext().getString(R.string.menu_backup_webRestore),
MyApplication.getmContext().getResources().getString(R.string.menu_backup_webRestore) MyApplication.getmContext().getString(R.string.menu_backup_autoSyn)
}; };
// private ChapterService mChapterService; // private ChapterService mChapterService;
@SuppressLint("HandlerLeak") @SuppressLint("HandlerLeak")
@ -138,12 +138,7 @@ public class BookcasePresenter implements BasePresenter {
mBookcaseFragment.getRlDownloadTip().setVisibility(View.VISIBLE); mBookcaseFragment.getRlDownloadTip().setVisibility(View.VISIBLE);
break; break;
case 11: case 11:
MyApplication.runOnUiThread(new Runnable() { MyApplication.runOnUiThread(() -> createMenu());
@Override
public void run() {
createMenu();
}
});
break; break;
case 12: case 12:
mBookcaseFragment.getTvStopDownload().setVisibility(View.GONE); mBookcaseFragment.getTvStopDownload().setVisibility(View.GONE);
@ -170,7 +165,9 @@ public class BookcasePresenter implements BasePresenter {
if (mSetting.getBookcaseStyle() == null) { if (mSetting.getBookcaseStyle() == null) {
mSetting.setBookcaseStyle(BookcaseStyle.listMode); mSetting.setBookcaseStyle(BookcaseStyle.listMode);
} }
synBookcase(); if (mSetting.isAutoSyn() && UserService.isLogin()) {
synBookcaseToWeb(true);
}
getData(); getData();
//是否启用下拉刷新(默认启用) //是否启用下拉刷新(默认启用)
if (android.os.Build.VERSION.SDK_INT < Build.VERSION_CODES.M) { if (android.os.Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
@ -206,10 +203,10 @@ public class BookcasePresenter implements BasePresenter {
//停止按钮监听器 //停止按钮监听器
mBookcaseFragment.getTvStopDownload().setOnClickListener(v -> { mBookcaseFragment.getTvStopDownload().setOnClickListener(v -> {
if (downloadProcess == 99){ if (downloadProcess == 99) {
TextHelper.showText("开始缓存下一本书籍!"); TextHelper.showText("开始缓存下一本书籍!");
isDownloadFinish = true; isDownloadFinish = true;
}else { } else {
isStopDownload = true; isStopDownload = true;
} }
}); });
@ -306,7 +303,7 @@ public class BookcasePresenter implements BasePresenter {
mHandler.sendMessage(mHandler.obtainMessage(3)); mHandler.sendMessage(mHandler.obtainMessage(3));
} }
for (final Book book : mBooks) { for (final Book book : mBooks) {
if ("本地书籍".equals(book.getType())){ if ("本地书籍".equals(book.getType())) {
mBookcaseAdapter.getIsLoading().put(book.getId(), false); mBookcaseAdapter.getIsLoading().put(book.getId(), false);
mHandler.sendMessage(mHandler.obtainMessage(1)); mHandler.sendMessage(mHandler.obtainMessage(1));
continue; continue;
@ -419,7 +416,7 @@ public class BookcasePresenter implements BasePresenter {
pm.getMenuInflater().inflate(R.menu.menu_book, pm.getMenu()); pm.getMenuInflater().inflate(R.menu.menu_book, pm.getMenu());
setIconEnable(pm.getMenu(), true); setIconEnable(pm.getMenu(), true);
if (MyApplication.isApkInDebug(mMainActivity)) { if (MyApplication.isApkInDebug(mMainActivity)) {
pm.getMenu().getItem(4).setVisible(true); pm.getMenu().getItem(5).setVisible(true);
} }
pm.setOnMenuItemClickListener(item -> { pm.setOnMenuItemClickListener(item -> {
switch (item.getItemId()) { switch (item.getItemId()) {
@ -441,31 +438,64 @@ public class BookcasePresenter implements BasePresenter {
return true; return true;
case R.id.action_addLocalBook: case R.id.action_addLocalBook:
TextHelper.showText("请选择一个txt格式的书籍文件"); TextHelper.showText("请选择一个txt格式的书籍文件");
Intent intent = new Intent(Intent.ACTION_GET_CONTENT); Intent addIntent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("text/plain"); addIntent.setType("text/plain");
intent.addCategory(Intent.CATEGORY_OPENABLE); addIntent.addCategory(Intent.CATEGORY_OPENABLE);
mMainActivity.startActivityForResult(intent, APPCONST.SELECT_FILE_CODE); mMainActivity.startActivityForResult(addIntent, APPCONST.SELECT_FILE_CODE);
break;
case R.id.action_syn:
if (!UserService.isLogin()){
TextHelper.showText("请先登录!");
Intent intent = new Intent(mMainActivity, LoginActivity.class);
mMainActivity.startActivity(intent);
return true;
}
if (mSetting.isAutoSyn()) {
webSynMenu[2] = MyApplication.getmContext().getString(R.string.menu_backup_autoSyn) + "已开启";
} else {
webSynMenu[2] = MyApplication.getmContext().getString(R.string.menu_backup_autoSyn) + "已关闭";
}
new AlertDialog.Builder(mMainActivity)
.setTitle(mMainActivity.getString(R.string.menu_bookcase_syn))
.setAdapter(new ArrayAdapter<>(mMainActivity,
android.R.layout.simple_list_item_1, webSynMenu),
(dialog, which) -> {
switch (which) {
case 0:
synBookcaseToWeb(false);
break;
case 1:
webRestore();
break;
case 2:
String tip = "";
if (mSetting.isAutoSyn()) {
mSetting.setAutoSyn(false);
tip = "每日自动同步已关闭!";
} else {
mSetting.setAutoSyn(true);
tip = "每日自动同步已开启!";
}
SysManager.saveSetting(mSetting);
TextHelper.showText(tip);
break;
}
})
.setNegativeButton(null, null)
.setPositiveButton(null, null)
.show();
break; break;
case R.id.action_download_all: case R.id.action_download_all:
DialogCreator.createCommonDialog(mMainActivity, "一键缓存(实验)", DialogCreator.createCommonDialog(mMainActivity, "一键缓存(实验)",
mMainActivity.getString(R.string.all_cathe_tip), true, mMainActivity.getString(R.string.all_cathe_tip), true,
(dialog, which) -> downloadAll(), null); (dialog, which) -> downloadAll(), null);
return true;
case R.id.action_update:
checkVersionByServer(mMainActivity, true, mBookcaseFragment);
return true; return true;
case R.id.action_backup: case R.id.action_backup:
final String[] menu;
if (UserService.isLogin()) {
menu = webBackupMenu;
} else {
menu = backupMenu;
}
AlertDialog bookDialog = new AlertDialog.Builder(mMainActivity) AlertDialog bookDialog = new AlertDialog.Builder(mMainActivity)
.setTitle(mMainActivity.getResources().getString(R.string.menu_bookcase_backup)) .setTitle(mMainActivity.getResources().getString(R.string.menu_bookcase_backup))
.setAdapter(new ArrayAdapter<>(mMainActivity, .setAdapter(new ArrayAdapter<>(mMainActivity,
android.R.layout.simple_list_item_1, menu), android.R.layout.simple_list_item_1, backupMenu),
(dialog, which) -> { (dialog, which) -> {
switch (which) { switch (which) {
case 0: case 0:
@ -474,9 +504,6 @@ public class BookcasePresenter implements BasePresenter {
case 1: case 1:
mHandler.sendMessage(mHandler.obtainMessage(6)); mHandler.sendMessage(mHandler.obtainMessage(6));
break; break;
case 2:
webRestore();
break;
} }
}) })
.setNegativeButton(null, null) .setNegativeButton(null, null)
@ -484,28 +511,9 @@ public class BookcasePresenter implements BasePresenter {
.create(); .create();
bookDialog.show(); bookDialog.show();
return true; return true;
case R.id.action_disclaimer: case R.id.action_about:
BufferedReader br = null; Intent aboutIntent = new Intent(mMainActivity, AboutActivity.class);
try { mMainActivity.startActivity(aboutIntent);
br = new BufferedReader(new InputStreamReader(mMainActivity.getAssets().open("disclaimer.fy")));
StringBuilder disclaimer = new StringBuilder();
String line = null;
while ((line = br.readLine()) != null) {
disclaimer.append(line);
disclaimer.append("\r\n\n");
}
DialogCreator.createTipDialog(mMainActivity, "免责声明", disclaimer.toString());
} catch (IOException e) {
e.printStackTrace();
} finally {
if (br != null) {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return true; return true;
} }
return false; return false;
@ -538,20 +546,10 @@ public class BookcasePresenter implements BasePresenter {
DialogCreator.createCommonDialog(mMainActivity, "确认备份吗?", "新备份会替换原有备份!", true, DialogCreator.createCommonDialog(mMainActivity, "确认备份吗?", "新备份会替换原有备份!", true,
(dialogInterface, i) -> { (dialogInterface, i) -> {
dialogInterface.dismiss(); dialogInterface.dismiss();
if (UserService.isLogin()) { if (mBackupAndRestore.backup("localBackup")) {
MyApplication.getApplication().newThread(() -> { DialogCreator.createTipDialog(mMainActivity, "备份成功,备份文件路径:" + APPCONST.BACKUP_FILE_DIR);
if (mBackupAndRestore.backup("localBackup") & UserService.webBackup()) {
DialogCreator.createTipDialog(mMainActivity, "备份(本地和网络)成功,本地备份文件路径:" + APPCONST.BACKUP_FILE_DIR);
} else {
DialogCreator.createTipDialog(mMainActivity, "未登录或未给予储存权限,备份失败!");
}
});
} else { } else {
if (mBackupAndRestore.backup("localBackup")) { DialogCreator.createTipDialog(mMainActivity, "未给予储存权限,备份失败!");
DialogCreator.createTipDialog(mMainActivity, "备份成功,备份文件路径:" + APPCONST.BACKUP_FILE_DIR);
} else {
DialogCreator.createTipDialog(mMainActivity, "未给予储存权限,备份失败!");
}
} }
}, (dialogInterface, i) -> dialogInterface.dismiss()); }, (dialogInterface, i) -> dialogInterface.dismiss());
} }
@ -567,6 +565,7 @@ public class BookcasePresenter implements BasePresenter {
mHandler.sendMessage(mHandler.obtainMessage(7)); mHandler.sendMessage(mHandler.obtainMessage(7));
// DialogCreator.createTipDialog(mMainActivity, // DialogCreator.createTipDialog(mMainActivity,
// "恢复成功!\n注意:本功能属于实验功能,书架恢复后,书籍初次加载时可能加载失败,返回重新加载即可!"); // "恢复成功!\n注意:本功能属于实验功能,书架恢复后,书籍初次加载时可能加载失败,返回重新加载即可!");
mSetting = SysManager.getSetting();
TextHelper.showText("书架恢复成功!"); TextHelper.showText("书架恢复成功!");
} else { } else {
DialogCreator.createTipDialog(mMainActivity, "未找到备份文件或未给予储存权限,恢复失败!"); DialogCreator.createTipDialog(mMainActivity, "未找到备份文件或未给予储存权限,恢复失败!");
@ -579,7 +578,11 @@ public class BookcasePresenter implements BasePresenter {
* 恢复 * 恢复
*/ */
private void webRestore() { private void webRestore() {
DialogCreator.createCommonDialog(mMainActivity, "确认恢复吗?", "恢复书架会覆盖原有书架!", true, if (!NetworkUtils.isNetWorkAvailable()){
TextHelper.showText("无网络连接!");
return;
}
DialogCreator.createCommonDialog(mMainActivity, "确认同步吗?", "将书架从网络同步至本地会覆盖原有书架!", true,
(dialogInterface, i) -> { (dialogInterface, i) -> {
dialogInterface.dismiss(); dialogInterface.dismiss();
MyApplication.getApplication().newThread(() -> { MyApplication.getApplication().newThread(() -> {
@ -587,9 +590,10 @@ public class BookcasePresenter implements BasePresenter {
mHandler.sendMessage(mHandler.obtainMessage(7)); mHandler.sendMessage(mHandler.obtainMessage(7));
// DialogCreator.createTipDialog(mMainActivity, // DialogCreator.createTipDialog(mMainActivity,
// "恢复成功!\n注意:本功能属于实验功能,书架恢复后,书籍初次加载时可能加载失败,返回重新加载即可!");、 // "恢复成功!\n注意:本功能属于实验功能,书架恢复后,书籍初次加载时可能加载失败,返回重新加载即可!");、
TextHelper.showText("书架恢复成功!"); mSetting = SysManager.getSetting();
TextHelper.showText("成功将书架从网络同步至本地!");
} else { } else {
DialogCreator.createTipDialog(mMainActivity, "未找到备份文件,恢复失败!"); DialogCreator.createTipDialog(mMainActivity, "未找到同步文件,同步失败!");
} }
}); });
}, (dialogInterface, i) -> dialogInterface.dismiss()); }, (dialogInterface, i) -> dialogInterface.dismiss());
@ -609,7 +613,7 @@ public class BookcasePresenter implements BasePresenter {
MyApplication.getApplication().newThread(() -> { MyApplication.getApplication().newThread(() -> {
downloadFor: downloadFor:
for (final Book book : mBooks) { for (final Book book : mBooks) {
if (BookSource.pinshu.toString().equals(book.getSource()) || "本地书籍".equals(book.getType())){ if (BookSource.pinshu.toString().equals(book.getSource()) || "本地书籍".equals(book.getType())) {
continue; continue;
} }
isDownloadFinish = false; isDownloadFinish = false;
@ -637,17 +641,18 @@ public class BookcasePresenter implements BasePresenter {
/** /**
* 添加下载 * 添加下载
*
* @param book * @param book
* @param mChapters * @param mChapters
* @param begin * @param begin
* @param end * @param end
*/ */
public void addDownload(final Book book, final ArrayList<Chapter> mChapters, int begin, int end) { public void addDownload(final Book book, final ArrayList<Chapter> mChapters, int begin, int end) {
if ("本地书籍".equals(book.getType())){ if ("本地书籍".equals(book.getType())) {
TextHelper.showText("《" + book.getName() + "》是本地书籍,不能缓存"); TextHelper.showText("《" + book.getName() + "》是本地书籍,不能缓存");
return; return;
} }
if (mChapters.size() == 0){ if (mChapters.size() == 0) {
TextHelper.showText("《" + book.getName() + "》章节目录为空,缓存失败,请刷新后重试"); TextHelper.showText("《" + book.getName() + "》章节目录为空,缓存失败,请刷新后重试");
return; return;
} }
@ -669,13 +674,13 @@ public class BookcasePresenter implements BasePresenter {
downloadingChapter = chapter.getTitle(); downloadingChapter = chapter.getTitle();
downloadProcess = curCacheChapterNum[0] * 100 / needCacheChapterNum; downloadProcess = curCacheChapterNum[0] * 100 / needCacheChapterNum;
mChapterService.saveOrUpdateChapter(chapter, (String) o); mChapterService.saveOrUpdateChapter(chapter, (String) o);
// isDownloadFinish[0] = true; // isDownloadFinish[0] = true;
mHandler.sendMessage(mHandler.obtainMessage(8)); mHandler.sendMessage(mHandler.obtainMessage(8));
} }
@Override @Override
public void onError(Exception e) { public void onError(Exception e) {
// isDownloadFinish[0] = true; // isDownloadFinish[0] = true;
curCacheChapterNum[0]++; curCacheChapterNum[0]++;
downloadProcess = curCacheChapterNum[0] * 100 / needCacheChapterNum; downloadProcess = curCacheChapterNum[0] * 100 / needCacheChapterNum;
mHandler.sendMessage(mHandler.obtainMessage(8)); mHandler.sendMessage(mHandler.obtainMessage(8));
@ -732,11 +737,12 @@ public class BookcasePresenter implements BasePresenter {
/** /**
* 添加本地书籍 * 添加本地书籍
*
* @param path * @param path
*/ */
public void addLocalBook(String path) { public void addLocalBook(String path) {
File file = new File(path); File file = new File(path);
if (!file.exists()){ if (!file.exists()) {
return; return;
} }
Book book = new Book(); Book book = new Book();
@ -751,7 +757,7 @@ public class BookcasePresenter implements BasePresenter {
//判断书籍是否已经添加 //判断书籍是否已经添加
Book existsBook = mBookService.findBookByAuthorAndName(book.getName(), book.getAuthor()); Book existsBook = mBookService.findBookByAuthorAndName(book.getName(), book.getAuthor());
if (book.equals(existsBook)){ if (book.equals(existsBook)) {
TextHelper.showText("该书籍已存在,请勿重复添加!"); TextHelper.showText("该书籍已存在,请勿重复添加!");
return; return;
} }
@ -763,36 +769,48 @@ public class BookcasePresenter implements BasePresenter {
/** /**
* 同步书架 * 同步书架
*/ */
private void synBookcase(){ private void synBookcaseToWeb(boolean isAutoSyn) {
if (UserService.isLogin()){ if (!NetworkUtils.isNetWorkAvailable()){
Date nowTime = new Date(); if (!isAutoSyn) {
SimpleDateFormat sdf = new SimpleDateFormat("yy-MM-dd"); TextHelper.showText("无网络连接!");
String nowTimeStr = sdf.format(nowTime);
SharedPreUtils spb = SharedPreUtils.getInstance();
String synTime = spb.getString("synTime");
if (!nowTimeStr.equals(synTime)) {
MyApplication.getApplication().newThread(() -> {
if (UserService.webBackup()){
spb.putString("synTime", nowTimeStr);
}
});
} }
return;
}
Date nowTime = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("yy-MM-dd");
String nowTimeStr = sdf.format(nowTime);
SharedPreUtils spb = SharedPreUtils.getInstance();
String synTime = spb.getString("synTime");
if (!nowTimeStr.equals(synTime) || !isAutoSyn) {
MyApplication.getApplication().newThread(() -> {
if (UserService.webBackup()) {
spb.putString("synTime", nowTimeStr);
if (!isAutoSyn) {
DialogCreator.createTipDialog(mMainActivity, "成功将书架同步至网络!");
}
} else {
if (!isAutoSyn) {
DialogCreator.createTipDialog(mMainActivity, "同步失败,请重试!");
}
}
});
} }
} }
/*****************************************用于返回按钮判断*************************************/ /*****************************************用于返回按钮判断*************************************/
/** /**
* 判断是否处于编辑状态 * 判断是否处于编辑状态
*
* @return * @return
*/ */
public boolean ismEditState(){ public boolean ismEditState() {
return mBookcaseAdapter.ismEditState(); return mBookcaseAdapter.ismEditState();
} }
/** /**
* 取消编辑状态 * 取消编辑状态
*/ */
public void cancelEdit(){ public void cancelEdit() {
editBookcase(false); editBookcase(false);
} }
/*class NotificationService extends Service{ /*class NotificationService extends Service{

@ -117,12 +117,7 @@ public class SearchBookPrensenter implements BasePresenter {
//换一批点击事件 //换一批点击事件
mSearchBookActivity.getRenewByText().setOnClickListener(new RenewSuggestionBook()); mSearchBookActivity.getRenewByText().setOnClickListener(new RenewSuggestionBook());
//返回 //返回
mSearchBookActivity.getLlTitleBack().setOnClickListener(new View.OnClickListener() { mSearchBookActivity.getLlTitleBack().setOnClickListener(view -> mSearchBookActivity.finish());
@Override
public void onClick(View view) {
mSearchBookActivity.finish();
}
});
//搜索框改变事件 //搜索框改变事件
mSearchBookActivity.getEtSearchKey().addTextChangedListener(new TextWatcher() { mSearchBookActivity.getEtSearchKey().addTextChangedListener(new TextWatcher() {

@ -53,12 +53,7 @@ public class LoginPresenter implements BasePresenter {
public void start() { public void start() {
mHandler.sendMessage(mHandler.obtainMessage(2)); mHandler.sendMessage(mHandler.obtainMessage(2));
mLoginActivity.getTvTitleText().setText("登录"); mLoginActivity.getTvTitleText().setText("登录");
mLoginActivity.getLlTitleBack().setOnClickListener(new View.OnClickListener() { mLoginActivity.getLlTitleBack().setOnClickListener(v -> mLoginActivity.finish());
@Override
public void onClick(View v) {
mLoginActivity.finish();
}
});
String username = UserService.readUsername(); String username = UserService.readUsername();
mLoginActivity.getUser().setText(username); mLoginActivity.getUser().setText(username);
mLoginActivity.getUser().requestFocus(username.length()); mLoginActivity.getUser().requestFocus(username.length());

@ -0,0 +1,24 @@
package xyz.fycz.myreader.util;
import android.content.Context;
import android.content.Intent;
import xyz.fycz.myreader.R;
/**
* Created by Zhouas666 on 2019-04-12
* Github: https://github.com/zas023
*/
public class ShareUtils {
public static void share(Context context, int stringRes) {
share(context, context.getString(stringRes));
}
public static void share(Context context, String extraText) {
Intent intent = new Intent(Intent.ACTION_SEND);
intent.setType("text/plain");
intent.putExtra(Intent.EXTRA_SUBJECT, context.getString(R.string.share));
intent.putExtra(Intent.EXTRA_TEXT, extraText);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(Intent.createChooser(intent, context.getString(R.string.share)));
}
}

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="#595757"
android:pathData="M7.699,18.758 L7.699,13.219 L4,9.742 L20,5.242 L13.332,18.574 L10.785,16.125 L7.699,18.758 Z M9.455,13.035 L12.888,16.267 L16.987,8.288 L9.455,13.035 Z M9.035,14.477 L9.035,15.887 L9.81,15.209 L9.035,14.477 Z M6.655,10.398 L8.449,12.086 L14.544,8.248 L6.655,10.398 Z" />
</vector>

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="#595757"
android:pathData="M18.545,18.304c0,0.131-0.11,0.242-0.241,0.242H5.696c-0.131,0-0.242-0.111-0.242-0.242V5.697 c0-0.131,0.111-0.243,0.242-0.243H12V4H5.696C4.76,4,4,4.762,4,5.697v12.606C4,19.239,4.76,20,5.696,20h12.607 C19.239,20,20,19.239,20,18.304v-6.303h-1.455V18.304z" />
<path
android:fillColor="#595757"
android:pathData="M 19.272 4 L 13.843 4 L 13.843 5.454 L 17.517 5.454 L 7.464 15.508 L 8.491 16.536 L 18.545 6.482 L 18.545 10.157 L 20 10.157 L 20 4.727 L 20 4 Z" />
</vector>

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="#595757"
android:pathData="M5.938,4v0.97H4v13.334C4,19.239,4.762,20,5.696,20h12.607C19.239,20,20,19.239,20,18.304V4H5.938z M5.454,18.304V6.424h0.484v11.88C5.938,18.57,5.454,18.57,5.454,18.304z M18.546,18.304c0,0.133-0.108,0.242-0.242,0.242H7.368 c0.013-0.08,0.025-0.159,0.025-0.242V5.454h11.152V18.304z" />
<path
android:fillColor="#595757"
android:pathData="M 9.089 11.061 H 16.849 V 11.97 H 9.089 V 11.061 Z" />
<path
android:fillColor="#595757"
android:pathData="M 9.089 13 H 16.849 V 13.909 H 9.089 V 13 Z" />
<path
android:fillColor="#595757"
android:pathData="M 9.089 7.182 H 16.849 V 8.091 H 9.089 V 7.182 Z" />
<path
android:fillColor="#595757"
android:pathData="M 9.089 9.12 H 16.849 V 10.03 H 9.089 V 9.12 Z" />
<path
android:fillColor="#595757"
android:pathData="M 9.089 14.939 H 16.849 V 15.848 H 9.089 V 14.939 Z" />
</vector>

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="#595757"
android:pathData="M5.689,20 C5.164,20,4.74,19.844,4.432,19.537 C3.242,18.345,4.772,15.546,5.863,13.892 C5.683,13.308,5.595,12.688,5.595,12 C5.595,8.469,8.467,5.596,11.998,5.596 C12.684,5.596,13.308,5.685,13.898,5.868 C15.013,5.131,16.948,4,18.339,4 C18.84,4,19.242,4.146,19.531,4.435 C20.308,5.212,20.118,6.648,18.965,8.697 C18.724,9.127,18.433,9.588,18.099,10.076 C18.296,10.703,18.396,11.345,18.396,11.986 C18.396,15.524,15.526,18.403,11.998,18.403 C11.349,18.403,10.7,18.304,10.067,18.103 C8.774,18.991,7.013,20,5.689,20 Z M6.51,15.317 C5.331,17.292,5.196,18.449,5.357,18.611 C5.418,18.673,5.543,18.706,5.709,18.706 C6.337,18.706,7.422,18.249,8.669,17.469 C7.791,16.935,7.046,16.193,6.51,15.317 Z M11.473,17.068 C11.651,17.087,11.826,17.096,11.998,17.096 C14.806,17.096,17.089,14.803,17.089,11.985 C17.089,11.82,17.081,11.651,17.063,11.482 C16.282,12.473,15.398,13.461,14.428,14.43 C13.48,15.38,12.47,16.28,11.473,17.068 Z M11.998,6.901 C9.188,6.901,6.902,9.19,6.902,12 C6.902,14.017,8.066,15.818,9.885,16.641 C11.084,15.764,12.301,14.711,13.504,13.508 C14.686,12.326,15.765,11.076,16.635,9.883 C15.811,8.068,14.011,6.901,11.998,6.901 Z M15.317,6.516 C16.19,7.051,16.929,7.791,17.461,8.666 C17.598,8.448,17.72,8.247,17.827,8.055 C18.848,6.24,18.729,5.482,18.607,5.36 C18.605,5.357,18.549,5.304,18.335,5.304 C18.084,5.304,17.163,5.396,15.317,6.516 Z" />
</vector>

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="#FFFFFF"
android:pathData="M9.866,9.9c-1.158,0-2.1,0.941-2.1,2.1s0.941,2.1,2.1,2.1s2.1-0.941,2.1-2.1S11.024,9.9,9.866,9.9z M9.866,13.1c-0.606,0-1.1-0.493-1.1-1.1s0.493-1.1,1.1-1.1s1.1,0.493,1.1,1.1S10.473,13.1,9.866,13.1z" />
<path
android:fillColor="#FFFFFF"
android:pathData="M16.267,16c-0.37,0-0.716,0.091-1.029,0.241l-1.656-1.657c0.513-0.734,0.817-1.623,0.817-2.584 s-0.305-1.85-0.817-2.584l1.656-1.657C15.551,7.909,15.896,8,16.267,8c1.323,0,2.399-1.077,2.399-2.4S17.59,3.2,16.267,3.2 s-2.4,1.076-2.4,2.399c0,0.369,0.091,0.715,0.241,1.028L12.45,8.285c-0.733-0.513-1.622-0.818-2.584-0.818 c-2.5,0-4.533,2.033-4.533,4.533s2.033,4.533,4.533,4.533c0.962,0,1.851-0.306,2.584-0.818l1.657,1.657 c-0.15,0.313-0.241,0.659-0.241,1.028c0,1.323,1.077,2.399,2.4,2.399s2.399-1.076,2.399-2.399S17.59,16,16.267,16z M16.267,4.8 c0.44,0,0.8,0.359,0.8,0.8c0,0.441-0.359,0.801-0.8,0.801c-0.441,0-0.801-0.359-0.801-0.801C15.466,5.159,15.825,4.8,16.267,4.8z M9.866,14.934c-1.617,0-2.934-1.316-2.934-2.934s1.316-2.934,2.934-2.934s2.933,1.316,2.933,2.934S11.483,14.934,9.866,14.934z M16.267,19.2c-0.441,0-0.801-0.359-0.801-0.8c0-0.441,0.359-0.801,0.801-0.801c0.44,0,0.8,0.359,0.8,0.801 C17.066,18.841,16.707,19.2,16.267,19.2z" />
</vector>

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
tools:context=".ui.about.AboutActivity">
<include layout="@layout/title_base"/>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<include layout="@layout/layout_about_content" />
</FrameLayout>
</LinearLayout>

@ -0,0 +1,283 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.core.widget.NestedScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:background="@color/white"
android:scrollbars="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_marginBottom="6dp">
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center_horizontal"
android:layout_marginTop="24dp"
android:src="@mipmap/ic_launcher"/>
<TextView
android:id="@+id/tv_version_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="4dp"
android:layout_marginBottom="4dp"
android:textSize="16sp"
android:textColor="@color/title_black"
tools:text="风月读书"/>
</LinearLayout>
<androidx.cardview.widget.CardView
android:id="@+id/vm_author"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_margin="6dp"
android:clickable="true"
android:focusable="true"
android:foreground="?attr/selectableItemBackground"
app:cardBackgroundColor="@color/little_grey">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="5dp"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="5dp"
android:layout_marginTop="5dp"
android:text="开发者"
android:textColor="@color/title_black"
android:textSize="16sp"/>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingBottom="6dp">
<xyz.fycz.myreader.custom.CircleImageView
android:id="@+id/ig_avatar_fycz"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_marginRight="16dp"
android:src="@mipmap/ic_avatar_fycz"/>
<TextView
android:id="@+id/fycz"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignTop="@id/ig_avatar_fycz"
android:layout_toEndOf="@id/ig_avatar_fycz"
android:text="ヅ风月の残烛"
android:textColor="@color/title_black"
tools:ignore="HardcodedText"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/fycz"
android:layout_toEndOf="@id/ig_avatar_fycz"
android:text="@string/email"
android:textColor="@color/title_black"/>
</RelativeLayout>
</LinearLayout>
</androidx.cardview.widget.CardView>
<androidx.cardview.widget.CardView
android:id="@+id/vw_share"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_margin="6dp"
android:clickable="true"
android:focusable="true"
android:foreground="?attr/selectableItemBackground"
app:cardBackgroundColor="@color/little_grey">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="5dp">
<ImageView
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_gravity="center_vertical"
android:src="@drawable/ic_share"
app:tint="@color/title_black"/>
<TextView
android:id="@+id/tv_share"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_margin="5dp"
android:gravity="center_vertical"
android:textColor="@color/title_black"
android:text="@string/share_app"/>
</LinearLayout>
</androidx.cardview.widget.CardView>
<androidx.cardview.widget.CardView
android:id="@+id/vw_update"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_margin="6dp"
android:clickable="true"
android:focusable="true"
android:foreground="?attr/selectableItemBackground"
app:cardBackgroundColor="@color/little_grey">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="5dp">
<ImageView
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_gravity="center_vertical"
android:src="@drawable/ic_update"
app:tint="@color/title_black"/>
<TextView
android:id="@+id/tv_update"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_margin="5dp"
android:gravity="center_vertical"
android:textColor="@color/title_black"
android:text="@string/update"/>
</LinearLayout>
</androidx.cardview.widget.CardView>
<androidx.cardview.widget.CardView
android:id="@+id/vw_update_log"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_margin="6dp"
android:clickable="true"
android:focusable="true"
android:foreground="?attr/selectableItemBackground"
app:cardBackgroundColor="@color/little_grey">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="5dp">
<ImageView
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_gravity="center_vertical"
android:src="@drawable/ic_list"
app:tint="@color/title_black"/>
<TextView
android:id="@+id/tv_update_log"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_margin="5dp"
android:gravity="center_vertical"
android:textColor="@color/title_black"
android:text="@string/update_log"/>
</LinearLayout>
</androidx.cardview.widget.CardView>
<androidx.cardview.widget.CardView
android:id="@+id/vw_git"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_margin="6dp"
android:clickable="true"
android:focusable="true"
android:foreground="?attr/selectableItemBackground"
app:cardBackgroundColor="@color/little_grey">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="5dp">
<ImageView
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_gravity="center_vertical"
android:src="@drawable/ic_launch"
app:tint="@color/title_black"/>
<TextView
android:id="@+id/tv_git"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_margin="5dp"
android:gravity="center_vertical"
android:textColor="@color/title_black"
android:text="@string/git_hub"/>
</LinearLayout>
</androidx.cardview.widget.CardView>
<androidx.cardview.widget.CardView
android:id="@+id/vw_disclaimer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_margin="6dp"
android:clickable="true"
android:focusable="true"
android:foreground="?attr/selectableItemBackground"
app:cardBackgroundColor="@color/little_grey">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="5dp">
<ImageView
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_gravity="center_vertical"
android:src="@drawable/ic_disclaimer"
app:tint="@color/title_black"/>
<TextView
android:id="@+id/tv_disclaimer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_margin="5dp"
android:gravity="center_vertical"
android:textColor="@color/title_black"
android:text="@string/disclaimer"/>
</LinearLayout>
</androidx.cardview.widget.CardView>
</LinearLayout>
</androidx.core.widget.NestedScrollView>

@ -22,6 +22,12 @@
android:icon="@drawable/ic_backup" android:icon="@drawable/ic_backup"
android:title="@string/menu_bookcase_backup" android:title="@string/menu_bookcase_backup"
app:showAsAction="never"/> app:showAsAction="never"/>
<item
android:id="@+id/action_syn"
android:icon="@drawable/ic_online_syn"
android:title="@string/menu_bookcase_syn"
app:showAsAction="never"/>
<!--<item <!--<item
android:id="@+id/action_webBackup" android:id="@+id/action_webBackup"
android:icon="@drawable/ic_backup" android:icon="@drawable/ic_backup"
@ -32,17 +38,11 @@
android:icon="@drawable/ic_download_line" android:icon="@drawable/ic_download_line"
android:title="@string/menu_bookcase_download_all" android:title="@string/menu_bookcase_download_all"
app:showAsAction="never" app:showAsAction="never"
android:visible="false"/> android:visible="true"/>
<item
android:id="@+id/action_update"
android:icon="@drawable/ic_update"
android:title="@string/menu_bookcase_update"
app:showAsAction="never"/>
<item <item
android:id="@+id/action_disclaimer" android:id="@+id/action_about"
android:icon="@drawable/ic_disclaimer" android:icon="@drawable/ic_about"
android:title="@string/disclaimer" android:title="@string/menu_bookcase_about"
app:showAsAction="never"/> app:showAsAction="never"/>
</menu> </menu>

@ -49,18 +49,25 @@
<string name="menu_bookcase_edit">编辑书架</string> <string name="menu_bookcase_edit">编辑书架</string>
<string name="menu_bookcase_style">切换布局</string> <string name="menu_bookcase_style">切换布局</string>
<string name="menu_bookcase_add">添加本地</string> <string name="menu_bookcase_add">添加本地</string>
<string name="menu_bookcase_update">检查更新</string> <string name="menu_bookcase_syn">同步书架</string>
<string name="menu_bookcase_download_all">一键缓存(实验)</string> <string name="menu_bookcase_download_all">一键缓存(实验)</string>
<string name="menu_bookcase_backup">备份/恢复</string> <string name="menu_bookcase_backup">备份/恢复</string>
<string name="menu_bookcase_webBackup">网络备份/恢复</string> <string name="menu_bookcase_about">关于软件</string>
<string name="menu_backup_backup">备份</string> <string name="menu_backup_backup">备份</string>
<string name="menu_backup_restore">恢复</string> <string name="menu_backup_restore">恢复</string>
<string name="menu_backup_webRestore">网络恢复</string>
<string name="menu_backup_webBackup">从本地同步至网络</string>
<string name="menu_backup_webRestore">从网络同步至本地</string>
<string name="menu_backup_autoSyn">每日自动同步:</string>
<string name="change_source">换源</string> <string name="change_source">换源</string>
<string name="end_page_tip">已经是最后一页了</string> <string name="end_page_tip">已经是最后一页了</string>
<string name="share">分享</string>
<string name="share_text">发现了一款非常好用的小说App「风月读书」,绿色健康、无广告,而且完全开源不收费,实在是太赞了! 推荐~:</string>
<string name="stop_download_tip">停止</string> <string name="stop_download_tip">停止</string>
<string name="text_login">登录</string> <string name="text_login">登录</string>
<string name="tv_register">新用户注册</string> <string name="tv_register">新用户注册</string>
@ -72,5 +79,11 @@
<string name="text_agreement_tip">我已阅读并同意《</string> <string name="text_agreement_tip">我已阅读并同意《</string>
<string name="link_agreement"><a href="https://shimo.im/docs/RgkDpd3D3Gp6t3rD">用户服务协议</a></string> <string name="link_agreement"><a href="https://shimo.im/docs/RgkDpd3D3Gp6t3rD">用户服务协议</a></string>
<string name="add_book_mark">添加书签</string> <string name="add_book_mark">添加书签</string>
<string name="share_app">分享软件</string>
<string name="update_log">更新日志</string>
<string name="git_hub">GitHub</string>
<string name="email">邮箱:fy@fycz.xyz</string>
<string name="this_github_url">https://github.com/fengyuecanzhu/FYReader</string>
<string name="update">检查更新</string>
</resources> </resources>

@ -1,2 +1,2 @@
#Sat Jul 25 19:48:00 CST 2020 #Fri Jul 31 14:26:22 CST 2020
VERSION_CODE=138 VERSION_CODE=140

Loading…
Cancel
Save