diff --git a/.idea/misc.xml b/.idea/misc.xml index 96e6124..997510f 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -17,6 +17,7 @@ + @@ -30,38 +31,50 @@ + + + + + + - + + + + + + + diff --git a/app/build.gradle b/app/build.gradle index 059019b..8db0e34 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -277,7 +277,7 @@ dependencies { } greendao { - schemaVersion 33 + schemaVersion 34 daoPackage 'xyz.fycz.myreader.greendao.gen' // targetGenDir 'src/main/java' } diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index e75f044..de41b74 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -129,6 +129,7 @@ + diff --git a/app/src/main/java/xyz/fycz/myreader/application/App.java b/app/src/main/java/xyz/fycz/myreader/application/App.java index ac1c4b8..beeb52f 100644 --- a/app/src/main/java/xyz/fycz/myreader/application/App.java +++ b/app/src/main/java/xyz/fycz/myreader/application/App.java @@ -1,15 +1,12 @@ package xyz.fycz.myreader.application; -import static android.provider.ContactsContract.Directory.PACKAGE_NAME; - import android.annotation.TargetApi; import android.app.Activity; import android.app.ActivityManager; import android.app.Application; import android.app.NotificationChannel; import android.app.NotificationManager; -import android.app.Service; import android.content.Context; import android.content.Intent; import android.content.pm.ApplicationInfo; @@ -36,7 +33,6 @@ import org.jsoup.Jsoup; import org.jsoup.nodes.Document; import java.io.File; -import java.util.List; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; @@ -92,7 +88,8 @@ public class App extends Application { initNightTheme(); // LLog.init(APPCONST.LOG_DIR); initDialogX(); - AdUtils.initAd(); + if (!debug) + AdUtils.initAd(); } @@ -312,7 +309,7 @@ public class App extends Application { if (!StringHelper.isEmpty(downloadLink)) { spu.putString(getmContext().getString(R.string.downloadLink), downloadLink); } else { - spu.putString(getmContext().getString(R.string.downloadLink), URLCONST.APP_DIR_UR); + spu.putString(getmContext().getString(R.string.downloadLink), URLCONST.APP_DIR_URL); } String[] updateContents = updateContent.split("/"); for (String string : updateContents) { @@ -364,7 +361,7 @@ public class App extends Application { private void goDownload(Activity activity, String url) { String downloadLink = url; if (url == null || "".equals(url)) { - downloadLink = URLCONST.APP_DIR_UR; + downloadLink = URLCONST.APP_DIR_URL; } Intent intent = new Intent(); intent.setAction(Intent.ACTION_VIEW); diff --git a/app/src/main/java/xyz/fycz/myreader/common/APPCONST.java b/app/src/main/java/xyz/fycz/myreader/common/APPCONST.java index 94c6960..e87497e 100644 --- a/app/src/main/java/xyz/fycz/myreader/common/APPCONST.java +++ b/app/src/main/java/xyz/fycz/myreader/common/APPCONST.java @@ -102,6 +102,7 @@ public class APPCONST { public static final int REQUEST_GROUP_MANAGER = 1014; public static final int REQUEST_SEARCH_WORD = 1015; public static final int REQUEST_AUTH_EMAIL = 1016; + public static final int REQUEST_SETTING = 1017; public static final int REQUEST_READ = 1; diff --git a/app/src/main/java/xyz/fycz/myreader/common/URLCONST.java b/app/src/main/java/xyz/fycz/myreader/common/URLCONST.java index 67181d6..d36ab21 100644 --- a/app/src/main/java/xyz/fycz/myreader/common/URLCONST.java +++ b/app/src/main/java/xyz/fycz/myreader/common/URLCONST.java @@ -6,9 +6,11 @@ public class URLCONST { public static final String OFFICIAL_WEB = "https://reader." + getDefaultDomain() + "/"; - public static String APP_DIR_UR = "https://www.lanzous.com/b00ngso7e"; + public static String LAN_ZOU_URL = "https://fycz.lanzoum.com"; - public static String LAN_ZOUS_URL = "https://fycz.lanzoui.com"; + public static String APP_DIR_URL = LAN_ZOU_URL + "/b00ngso7e"; + + public static final String SUB_SOURCE_URL = LAN_ZOU_URL + "/b00pfkkgh"; //字体下载 public static final String FONT_DOWNLOAD_URL = "https://novel." + getDefaultDomain() + "/app/fonts/"; diff --git a/app/src/main/java/xyz/fycz/myreader/entity/AdBean.java b/app/src/main/java/xyz/fycz/myreader/entity/AdBean.java deleted file mode 100644 index 171549f..0000000 --- a/app/src/main/java/xyz/fycz/myreader/entity/AdBean.java +++ /dev/null @@ -1,74 +0,0 @@ -package xyz.fycz.myreader.entity; - -/** - * @author fengyue - * @date 2022/2/17 18:56 - */ -public class AdBean { - //是否云控 - private boolean isCloud; - //是否有广告 - private boolean hasAd; - //应用处于后台一段时间展示开屏广告(单位:分钟) - private int backAdTime; - //应用回到前台展示广告间隔(单位:分钟) - private int intervalAdTime; - //是否在详情页展示信息流广告 - private boolean showFlowAd; - - public AdBean() { - } - - public AdBean(boolean hasAd, int backAdTime, int intervalAdTime) { - this.hasAd = hasAd; - this.backAdTime = backAdTime; - this.intervalAdTime = intervalAdTime; - } - - public AdBean(boolean hasAd, int backAdTime, int intervalAdTime, boolean showFlowAd) { - this.hasAd = hasAd; - this.backAdTime = backAdTime; - this.intervalAdTime = intervalAdTime; - this.showFlowAd = showFlowAd; - } - - public boolean isCloud() { - return isCloud; - } - - public void setCloud(boolean cloud) { - isCloud = cloud; - } - - public boolean isHasAd() { - return hasAd; - } - - public void setHasAd(boolean hasAd) { - this.hasAd = hasAd; - } - - public int getBackAdTime() { - return backAdTime; - } - - public void setBackAdTime(int backAdTime) { - this.backAdTime = backAdTime; - } - - public int getIntervalAdTime() { - return intervalAdTime; - } - - public void setIntervalAdTime(int intervalAdTime) { - this.intervalAdTime = intervalAdTime; - } - - public boolean isShowFlowAd() { - return showFlowAd; - } - - public void setShowFlowAd(boolean showFlowAd) { - this.showFlowAd = showFlowAd; - } -} diff --git a/app/src/main/java/xyz/fycz/myreader/entity/ad/AdBean.kt b/app/src/main/java/xyz/fycz/myreader/entity/ad/AdBean.kt new file mode 100644 index 0000000..61124ec --- /dev/null +++ b/app/src/main/java/xyz/fycz/myreader/entity/ad/AdBean.kt @@ -0,0 +1,10 @@ +package xyz.fycz.myreader.entity.ad + +/** + * @author fengyue + * @date 2022/3/3 15:00 + */ +data class AdBean( + val status: Int,// 广告展示状态:0:不展示,1:展示信息流广告,2:展示插屏广告 + val interval: Int,// 广告展示间隔(单位:分钟) +) diff --git a/app/src/main/java/xyz/fycz/myreader/entity/ad/AdConfig.java b/app/src/main/java/xyz/fycz/myreader/entity/ad/AdConfig.java new file mode 100644 index 0000000..9fe7cb8 --- /dev/null +++ b/app/src/main/java/xyz/fycz/myreader/entity/ad/AdConfig.java @@ -0,0 +1,137 @@ +package xyz.fycz.myreader.entity.ad; + +import androidx.annotation.NonNull; + +import xyz.fycz.myreader.util.utils.GsonExtensionsKt; + +/** + * @author fengyue + * @date 2022/2/17 18:56 + */ +public class AdConfig { + //是否云控 + private boolean isCloud; + //是否有广告 + private boolean hasAd; + //配置过期时间 + private int expireTime; + //应用处于后台一段时间展示开屏广告(单位:分钟) + private int backAdTime; + //应用回到前台展示广告间隔(单位:分钟) + private int intervalAdTime; + //单次激励视频可去广告时间(单位:小时),为0时表示关闭去广告 + private int removeAdTime; + //每日最大去除广告次数 + private int maxRemove; + //累计最高去除时间(单位:小时) + private int totalRemove; + //详情页广告配置 + private AdBean detail; + //搜索页广告配置 + private AdBean search; + + public AdConfig() { + } + + public AdConfig(boolean hasAd, int expireTime, int backAdTime, int intervalAdTime, int removeAdTime, int maxRemove, int totalRemove) { + this.hasAd = hasAd; + this.expireTime = expireTime; + this.backAdTime = backAdTime; + this.intervalAdTime = intervalAdTime; + this.removeAdTime = removeAdTime; + this.maxRemove = maxRemove; + this.totalRemove = totalRemove; + } + + public boolean isCloud() { + return isCloud; + } + + public void setCloud(boolean cloud) { + isCloud = cloud; + } + + public boolean isHasAd() { + return hasAd; + } + + public void setHasAd(boolean hasAd) { + this.hasAd = hasAd; + } + + public int getBackAdTime() { + return backAdTime; + } + + public void setBackAdTime(int backAdTime) { + this.backAdTime = backAdTime; + } + + public int getIntervalAdTime() { + return intervalAdTime; + } + + public void setIntervalAdTime(int intervalAdTime) { + this.intervalAdTime = intervalAdTime; + } + + public int getExpireTime() { + return expireTime; + } + + public void setExpireTime(int expireTime) { + this.expireTime = expireTime; + } + + public int getRemoveAdTime() { + return removeAdTime; + } + + public void setRemoveAdTime(int removeAdTime) { + this.removeAdTime = removeAdTime; + } + + public int getMaxRemove() { + return maxRemove; + } + + public void setMaxRemove(int maxRemove) { + this.maxRemove = maxRemove; + } + + public int getTotalRemove() { + return totalRemove; + } + + public void setTotalRemove(int totalRemove) { + this.totalRemove = totalRemove; + } + + public AdBean getDetail() { + if (detail == null) { + detail = new AdBean(2, 60); + } + return detail; + } + + public void setDetail(AdBean detail) { + this.detail = detail; + } + + public AdBean getSearch() { + if (search == null) { + search = new AdBean(0, 60); + } + return search; + } + + public void setSearch(AdBean search) { + this.search = search; + } + + @NonNull + @Override + public String toString() { + return GsonExtensionsKt.getGSON().toJson(this); + } +} diff --git a/app/src/main/java/xyz/fycz/myreader/entity/lanzou/LanZouFile.kt b/app/src/main/java/xyz/fycz/myreader/entity/lanzou/LanZouFile.kt new file mode 100644 index 0000000..a366296 --- /dev/null +++ b/app/src/main/java/xyz/fycz/myreader/entity/lanzou/LanZouFile.kt @@ -0,0 +1,12 @@ +package xyz.fycz.myreader.entity.lanzou + +/** + * @author fengyue + * @date 2022/3/3 8:53 + */ +data class LanZouFile( + var id: String, + var name_all: String, + var size: String, + var time: String +) \ No newline at end of file diff --git a/app/src/main/java/xyz/fycz/myreader/entity/LanZouBean.kt b/app/src/main/java/xyz/fycz/myreader/entity/lanzou/LanZouParseBean.kt similarity index 66% rename from app/src/main/java/xyz/fycz/myreader/entity/LanZouBean.kt rename to app/src/main/java/xyz/fycz/myreader/entity/lanzou/LanZouParseBean.kt index fce8743..b73803f 100644 --- a/app/src/main/java/xyz/fycz/myreader/entity/LanZouBean.kt +++ b/app/src/main/java/xyz/fycz/myreader/entity/lanzou/LanZouParseBean.kt @@ -1,10 +1,10 @@ -package xyz.fycz.myreader.entity +package xyz.fycz.myreader.entity.lanzou /** * @author fengyue * @date 2022/1/22 20:15 */ -data class LanZouBean( +data class LanZouParseBean( var zt: Int, var dom: String, var url: String, diff --git a/app/src/main/java/xyz/fycz/myreader/enums/Font.java b/app/src/main/java/xyz/fycz/myreader/enums/Font.java index f9a18f9..13ed0cf 100644 --- a/app/src/main/java/xyz/fycz/myreader/enums/Font.java +++ b/app/src/main/java/xyz/fycz/myreader/enums/Font.java @@ -6,28 +6,28 @@ public enum Font { 默认字体( "默认字体"), 本地字体( "默认字体"), - 方正楷体( URLCONST.LAN_ZOUS_URL + "/ilLFMe6kefe"), - 方正行楷( URLCONST.LAN_ZOUS_URL + "/imFvne6keji"), - 经典宋体(URLCONST.LAN_ZOUS_URL + "/idhI5e6keqf"), - 方正硬笔行书(URLCONST.LAN_ZOUS_URL + "/ilVh6ep9xja"), - 包图小白体(URLCONST.LAN_ZOUS_URL + "/i5qgAicrirc"), - 仓耳非白W02(URLCONST.LAN_ZOUS_URL + "/iHwRnicriuf"), - 仓耳舒圆体W02(URLCONST.LAN_ZOUS_URL + "/i3GVPicrj3e"), - 仓耳与墨W02(URLCONST.LAN_ZOUS_URL + "/ivhv9icrj7i"), - 方正仿宋简体(URLCONST.LAN_ZOUS_URL + "/iEcCHicrjef"), - 方正黑体简体(URLCONST.LAN_ZOUS_URL + "/iw8kKicrjij"), - 方正书宋简体(URLCONST.LAN_ZOUS_URL + "/i5976icrjmd"), - 品如手写体(URLCONST.LAN_ZOUS_URL + "/iZccuicrjyf"), - 千图小兔体(URLCONST.LAN_ZOUS_URL + "/iOONMicrkda"), - 手书体(URLCONST.LAN_ZOUS_URL + "/iqbmdicrkvi"), - 演示春风楷(URLCONST.LAN_ZOUS_URL + "/ioRJSicrldg"), - 演示秋鸿楷(URLCONST.LAN_ZOUS_URL + "/i8qnzicrlsb"), - 演示夏行楷(URLCONST.LAN_ZOUS_URL + "/iyYUTicrm6f"), - 演示悠然小楷(URLCONST.LAN_ZOUS_URL + "/ikKq7icrmrg"), - 杨任东竹石体(URLCONST.LAN_ZOUS_URL + "/iiWdVicrnbg"), - 站酷仓耳渔阳体(URLCONST.LAN_ZOUS_URL + "/if5weicrnje"), - 迷你隶书( URLCONST.LAN_ZOUS_URL + "/ihaXVe6kekj"), - 方正黄草(URLCONST.LAN_ZOUS_URL + "/iQg67e6keed"); + 方正楷体( URLCONST.LAN_ZOU_URL + "/ilLFMe6kefe"), + 方正行楷( URLCONST.LAN_ZOU_URL + "/imFvne6keji"), + 经典宋体(URLCONST.LAN_ZOU_URL + "/idhI5e6keqf"), + 方正硬笔行书(URLCONST.LAN_ZOU_URL + "/ilVh6ep9xja"), + 包图小白体(URLCONST.LAN_ZOU_URL + "/i5qgAicrirc"), + 仓耳非白W02(URLCONST.LAN_ZOU_URL + "/iHwRnicriuf"), + 仓耳舒圆体W02(URLCONST.LAN_ZOU_URL + "/i3GVPicrj3e"), + 仓耳与墨W02(URLCONST.LAN_ZOU_URL + "/ivhv9icrj7i"), + 方正仿宋简体(URLCONST.LAN_ZOU_URL + "/iEcCHicrjef"), + 方正黑体简体(URLCONST.LAN_ZOU_URL + "/iw8kKicrjij"), + 方正书宋简体(URLCONST.LAN_ZOU_URL + "/i5976icrjmd"), + 品如手写体(URLCONST.LAN_ZOU_URL + "/iZccuicrjyf"), + 千图小兔体(URLCONST.LAN_ZOU_URL + "/iOONMicrkda"), + 手书体(URLCONST.LAN_ZOU_URL + "/iqbmdicrkvi"), + 演示春风楷(URLCONST.LAN_ZOU_URL + "/ioRJSicrldg"), + 演示秋鸿楷(URLCONST.LAN_ZOU_URL + "/i8qnzicrlsb"), + 演示夏行楷(URLCONST.LAN_ZOU_URL + "/iyYUTicrm6f"), + 演示悠然小楷(URLCONST.LAN_ZOU_URL + "/ikKq7icrmrg"), + 杨任东竹石体(URLCONST.LAN_ZOU_URL + "/iiWdVicrnbg"), + 站酷仓耳渔阳体(URLCONST.LAN_ZOU_URL + "/if5weicrnje"), + 迷你隶书( URLCONST.LAN_ZOU_URL + "/ihaXVe6kekj"), + 方正黄草(URLCONST.LAN_ZOU_URL + "/iQg67e6keed"); public String downloadPath; diff --git a/app/src/main/java/xyz/fycz/myreader/experiment/BookWCEstimate.kt b/app/src/main/java/xyz/fycz/myreader/experiment/BookWCEstimate.kt index 8a644b7..3c3f70a 100644 --- a/app/src/main/java/xyz/fycz/myreader/experiment/BookWCEstimate.kt +++ b/app/src/main/java/xyz/fycz/myreader/experiment/BookWCEstimate.kt @@ -53,7 +53,7 @@ class BookWCEstimate { cachedChapterSize++ } } - if (cachedChapterSize < 20 && chapters.size > 50) return -2 + if ((cachedChapterSize < 20 && chapters.size > 50) || cachedChapterSize == 0) return -2 chapters.forEach { chapter -> if (ChapterService.isChapterCached(chapter.bookId, chapter.title)) { sum += countChar( diff --git a/app/src/main/java/xyz/fycz/myreader/greendao/entity/SubscribeFile.java b/app/src/main/java/xyz/fycz/myreader/greendao/entity/SubscribeFile.java new file mode 100644 index 0000000..246e4bb --- /dev/null +++ b/app/src/main/java/xyz/fycz/myreader/greendao/entity/SubscribeFile.java @@ -0,0 +1,77 @@ +package xyz.fycz.myreader.greendao.entity; + +import org.greenrobot.greendao.annotation.Entity; +import org.greenrobot.greendao.annotation.Id; +import org.greenrobot.greendao.annotation.Generated; + +/** + * @author fengyue + * @date 2022/3/3 14:40 + */ +@Entity +public class SubscribeFile { + @Id + private String id; + + private String name; + + private String url; + + private String date; + + private String size; + + @Generated(hash = 1850023033) + public SubscribeFile(String id, String name, String url, String date, + String size) { + this.id = id; + this.name = name; + this.url = url; + this.date = date; + this.size = size; + } + + @Generated(hash = 1590903919) + public SubscribeFile() { + } + + public String getId() { + return this.id; + } + + public void setId(String id) { + this.id = id; + } + + public String getName() { + return this.name; + } + + public void setName(String name) { + this.name = name; + } + + public String getUrl() { + return this.url; + } + + public void setUrl(String url) { + this.url = url; + } + + public String getDate() { + return this.date; + } + + public void setDate(String date) { + this.date = date; + } + + public String getSize() { + return this.size; + } + + public void setSize(String size) { + this.size = size; + } +} diff --git a/app/src/main/java/xyz/fycz/myreader/greendao/util/MySQLiteOpenHelper.java b/app/src/main/java/xyz/fycz/myreader/greendao/util/MySQLiteOpenHelper.java index bcc4dd4..5f37604 100644 --- a/app/src/main/java/xyz/fycz/myreader/greendao/util/MySQLiteOpenHelper.java +++ b/app/src/main/java/xyz/fycz/myreader/greendao/util/MySQLiteOpenHelper.java @@ -39,7 +39,7 @@ public class MySQLiteOpenHelper extends DaoMaster.OpenHelper { BookDao.class, ChapterDao.class, SearchHistoryDao.class, BookMarkDao.class, BookGroupDao.class, ReplaceRuleBeanDao.class, BookSourceDao.class, CookieBeanDao.class, ReadRecordDao.class, - SearchWordDao.class + SearchWordDao.class, SubscribeFileDao.class ); } diff --git a/app/src/main/java/xyz/fycz/myreader/model/sourceAnalyzer/BookSourceManager.java b/app/src/main/java/xyz/fycz/myreader/model/sourceAnalyzer/BookSourceManager.java index 8e9fe8b..9bff369 100644 --- a/app/src/main/java/xyz/fycz/myreader/model/sourceAnalyzer/BookSourceManager.java +++ b/app/src/main/java/xyz/fycz/myreader/model/sourceAnalyzer/BookSourceManager.java @@ -4,8 +4,6 @@ import android.database.Cursor; import android.text.TextUtils; import android.util.Log; -import androidx.annotation.NonNull; - import java.io.File; import java.util.ArrayList; import java.util.Collections; @@ -19,7 +17,6 @@ import io.reactivex.SingleOnSubscribe; import io.reactivex.functions.Function; import xyz.fycz.myreader.R; import xyz.fycz.myreader.application.App; -import xyz.fycz.myreader.entity.thirdsource.BookSource3Bean; import xyz.fycz.myreader.entity.thirdsource.BookSourceBean; import xyz.fycz.myreader.entity.thirdsource.ThirdSourceUtil; import xyz.fycz.myreader.entity.thirdsource.source3.Source3; @@ -271,7 +268,7 @@ public class BookSourceManager { }).compose(RxUtils::toSimpleSingle); } - public static List getEnableNoLocalGroupList() { + public static List getEnableGroupList() { List groupList = new ArrayList<>(); String sql = "SELECT DISTINCT " + BookSourceDao.Properties.SourceGroup.columnName @@ -292,17 +289,24 @@ public class BookSourceManager { return groupList; } - public static List getNoLocalGroupList() { + public static List getGroupList(boolean isSubscribe) { List groupList = new ArrayList<>(); - String sql = "SELECT DISTINCT " + BookSourceDao.Properties.SourceGroup.columnName + " FROM " + BookSourceDao.TABLENAME; + String sql = "SELECT DISTINCT " + BookSourceDao.Properties.SourceGroup.columnName + "," + + BookSourceDao.Properties.SourceEName.columnName + " FROM " + BookSourceDao.TABLENAME; Cursor cursor = DbManager.getDaoSession().getDatabase().rawQuery(sql, null); if (!cursor.moveToFirst()) return groupList; do { String group = cursor.getString(0); + String eName = cursor.getString(1); if (TextUtils.isEmpty(group) || TextUtils.isEmpty(group.trim())) continue; for (String item : group.split("\\s*[,;,;]\\s*")) { - if (TextUtils.isEmpty(item) || groupList.contains(item) || item.equals("内置书源")) - continue; + if (isSubscribe) { + if (TextUtils.isEmpty(eName) || TextUtils.isEmpty(item) || groupList.contains(item)) + continue; + } else { + if (!TextUtils.isEmpty(eName) || TextUtils.isEmpty(item) || groupList.contains(item) || item.equals("内置书源")) + continue; + } groupList.add(item); } } while (cursor.moveToNext()); @@ -326,7 +330,7 @@ public class BookSourceManager { return importSource(FileUtils.readText(string)); } if (string.matches("https://.+\\.lanzou[a-z]\\.com/[\\s\\S]*")) { - return LanZouApi.INSTANCE.getUrl(string) + return LanZouApi.INSTANCE.getFileUrl(string) .flatMap((Function>) s -> Observable.create(emitter -> { emitter.onNext(OkHttpUtils.getHtml(s)); emitter.onComplete(); diff --git a/app/src/main/java/xyz/fycz/myreader/model/third3/http/OkHttpUtils.kt b/app/src/main/java/xyz/fycz/myreader/model/third3/http/OkHttpUtils.kt index 3e6c47e..e526786 100644 --- a/app/src/main/java/xyz/fycz/myreader/model/third3/http/OkHttpUtils.kt +++ b/app/src/main/java/xyz/fycz/myreader/model/third3/http/OkHttpUtils.kt @@ -133,13 +133,13 @@ fun Request.Builder.get(url: String, queryMap: Map, encoded: Boo url(httpBuilder.build()) } -fun Request.Builder.postForm(form: Map, encoded: Boolean = false) { +fun Request.Builder.postForm(form: Map, encoded: Boolean = false) { val formBody = FormBody.Builder() form.forEach { if (encoded) { - formBody.addEncoded(it.key, it.value) + formBody.addEncoded(it.key, it.value.toString()) } else { - formBody.add(it.key, it.value) + formBody.add(it.key, it.value.toString()) } } post(formBody.build()) diff --git a/app/src/main/java/xyz/fycz/myreader/ui/activity/AboutActivity.java b/app/src/main/java/xyz/fycz/myreader/ui/activity/AboutActivity.java index 8b84b95..31cc541 100644 --- a/app/src/main/java/xyz/fycz/myreader/ui/activity/AboutActivity.java +++ b/app/src/main/java/xyz/fycz/myreader/ui/activity/AboutActivity.java @@ -3,7 +3,6 @@ package xyz.fycz.myreader.ui.activity; import android.content.ClipData; import android.content.ClipboardManager; import android.content.Context; -import android.content.DialogInterface; import android.content.Intent; import android.net.Uri; import android.view.View; @@ -33,7 +32,6 @@ import xyz.fycz.myreader.util.SharedPreUtils; import xyz.fycz.myreader.util.ToastUtils; import xyz.fycz.myreader.util.ZipUtils; import xyz.fycz.myreader.util.utils.FileUtils; -import xyz.fycz.myreader.util.utils.ImageLoader; import xyz.fycz.myreader.util.utils.OkHttpUtils; import xyz.fycz.myreader.util.utils.RxUtils; import xyz.fycz.myreader.webapi.LanZouApi; @@ -74,7 +72,7 @@ public class AboutActivity extends BaseActivity { binding.il.rlUpdateLog.setOnClickListener(v -> DialogCreator.createAssetTipDialog(this, "更新日志", "updatelog.fy")); binding.il.rlShare.setOnClickListener(v -> ShareUtils.share(this, getString(R.string.share_text) + - SharedPreUtils.getInstance().getString(getString(R.string.downloadLink), URLCONST.LAN_ZOUS_URL))); + SharedPreUtils.getInstance().getString(getString(R.string.downloadLink), URLCONST.LAN_ZOU_URL))); binding.il.rlQq.setOnClickListener(v -> { if (!App.joinQQGroup(this, "8PIOnHFuH6A38hgxvD_Rp2Bu-Ke1ToBn")) { //数据 @@ -120,7 +118,7 @@ public class AboutActivity extends BaseActivity { MyAlertDialog.createInputDia(this, getString(R.string.lan_zou_parse), "格式:链接+逗号+密码(没有密码就不用填)", "", true, 100, text -> str[0] = text, (dialog, which) -> { - LanZouApi.INSTANCE.getUrl(str[0]) + LanZouApi.INSTANCE.getFileUrl(str[0]) .compose(RxUtils::toSimpleSingle) .subscribe(new MyObserver() { @Override diff --git a/app/src/main/java/xyz/fycz/myreader/ui/activity/BookDetailedActivity.java b/app/src/main/java/xyz/fycz/myreader/ui/activity/BookDetailedActivity.java index a69c1d2..4765a04 100644 --- a/app/src/main/java/xyz/fycz/myreader/ui/activity/BookDetailedActivity.java +++ b/app/src/main/java/xyz/fycz/myreader/ui/activity/BookDetailedActivity.java @@ -42,6 +42,7 @@ import xyz.fycz.myreader.base.observer.MyObserver; import xyz.fycz.myreader.base.observer.MySingleObserver; import xyz.fycz.myreader.common.APPCONST; import xyz.fycz.myreader.databinding.ActivityBookDetailBinding; +import xyz.fycz.myreader.entity.ad.AdBean; import xyz.fycz.myreader.experiment.BookWCEstimate; import xyz.fycz.myreader.greendao.entity.Book; import xyz.fycz.myreader.greendao.entity.Chapter; @@ -55,6 +56,7 @@ import xyz.fycz.myreader.ui.dialog.BookGroupDialog; import xyz.fycz.myreader.ui.dialog.DialogCreator; import xyz.fycz.myreader.ui.dialog.LoadingDialog; import xyz.fycz.myreader.ui.dialog.SourceExchangeDialog; +import xyz.fycz.myreader.util.SharedPreUtils; import xyz.fycz.myreader.util.ToastUtils; import xyz.fycz.myreader.util.help.StringHelper; import xyz.fycz.myreader.util.utils.AdUtils; @@ -91,6 +93,7 @@ public class BookDetailedActivity extends BaseActivity { private List tagList = new ArrayList<>(); private Disposable chaptersDis; private Disposable wcDis; + private AdBean adBean; @SuppressLint("HandlerLeak") private Handler mHandler = new Handler() { @@ -257,7 +260,8 @@ public class BookDetailedActivity extends BaseActivity { } mSourceDialog.setABooks(aBooks); mSourceDialog.setSourceIndex(sourceIndex); - if (AdUtils.getAdConfig().isHasAd() && AdUtils.getAdConfig().isShowFlowAd()){ + adBean = AdUtils.getAdConfig().getDetail(); + if (AdUtils.getAdConfig().isHasAd() && AdUtils.adTime("detail", adBean)) { initAd(); } } @@ -267,26 +271,12 @@ public class BookDetailedActivity extends BaseActivity { @Override public void onSuccess(@NonNull Boolean aBoolean) { if (aBoolean) { - new DdSdkFlowAd().getFlowViews(BookDetailedActivity.this, 1, new DdSdkFlowAd.FlowCallback() { - // 信息流广告拉取完毕后返回的 views - @Override - public void getFlowView(View view) { - binding.ic.getRoot().addView(view, 2); - } - - // 信息流广告展示后调用 - @Override - public void show() { - AdUtils.adRecord("flow", "adShow"); - Log.d(TAG, "信息流广告展示成功"); - } - - // 广告拉取失败调用 - @Override - public void error(String msg) { - Log.d(TAG, "广告拉取失败\n" + msg); - } - }); + if (adBean.getStatus() == 1) { + AdUtils.getFlowAd(BookDetailedActivity.this, 1, + view -> binding.ic.getRoot().addView(view, 2), "detail"); + } else if (adBean.getStatus() == 2) { + AdUtils.showInterAd(BookDetailedActivity.this, "detail"); + } } } }); diff --git a/app/src/main/java/xyz/fycz/myreader/ui/activity/BookSourceActivity.java b/app/src/main/java/xyz/fycz/myreader/ui/activity/BookSourceActivity.java index 2205421..d094052 100644 --- a/app/src/main/java/xyz/fycz/myreader/ui/activity/BookSourceActivity.java +++ b/app/src/main/java/xyz/fycz/myreader/ui/activity/BookSourceActivity.java @@ -23,6 +23,7 @@ import xyz.fycz.myreader.base.BaseTabActivity; import xyz.fycz.myreader.databinding.ActivityBooksourceBinding; import xyz.fycz.myreader.ui.fragment.DIYSourceFragment; import xyz.fycz.myreader.ui.fragment.LocalSourceFragment; +import xyz.fycz.myreader.ui.fragment.SubscribeSourceFragment; /** * @author fengyue @@ -42,13 +43,13 @@ public class BookSourceActivity extends BaseTabActivity { @Override protected List createTabFragments() { - return Arrays.asList(new LocalSourceFragment(this), + return Arrays.asList(new SubscribeSourceFragment(this), new DIYSourceFragment(this)); } @Override protected List createTabTitles() { - return Arrays.asList("内置书源", "DIY书源"); + return Arrays.asList("订阅书源", "DIY书源"); } @Override @@ -73,7 +74,7 @@ public class BookSourceActivity extends BaseTabActivity { List fragments = getSupportFragmentManager().getFragments(); switch (tab.getPosition()) { case 0: - ((LocalSourceFragment) fragments.get(0)).startSearch(""); + ((SubscribeSourceFragment) fragments.get(0)).startSearch(""); break; case 1: ((DIYSourceFragment) fragments.get(1)).startSearch(""); @@ -112,7 +113,7 @@ public class BookSourceActivity extends BaseTabActivity { List fragments = getSupportFragmentManager().getFragments(); switch (binding.tabVp.getCurrentItem()) { case 0: - ((LocalSourceFragment) fragments.get(0)).startSearch(newText); + ((SubscribeSourceFragment) fragments.get(0)).startSearch(newText); break; case 1: ((DIYSourceFragment) fragments.get(1)).startSearch(newText); diff --git a/app/src/main/java/xyz/fycz/myreader/ui/activity/DonateActivity.java b/app/src/main/java/xyz/fycz/myreader/ui/activity/DonateActivity.java index fd6716f..dc28772 100644 --- a/app/src/main/java/xyz/fycz/myreader/ui/activity/DonateActivity.java +++ b/app/src/main/java/xyz/fycz/myreader/ui/activity/DonateActivity.java @@ -53,7 +53,6 @@ public class DonateActivity extends BaseActivity { @Override public void onSuccess(@NonNull Boolean aBoolean) { if (aBoolean) { - //AdUtils.initAd(); initAd(); } } @@ -82,7 +81,7 @@ public class DonateActivity extends BaseActivity { Log.d(TAG, "广告拉取失败\n" + msg); } });*/ - } + } @Override protected void initClick() { @@ -93,70 +92,11 @@ public class DonateActivity extends BaseActivity { MyAlertDialog.showFullWebViewDia(this, URLCONST.THANKS_URL, false, null)); - binding.llRewardedVideo.setOnClickListener(v -> { - DdSdkRewardAd.show(this, new DdSdkRewardAd.DdSdkRewardCallback() { - @Override - public void show() { - Log.i(TAG, "激励视频展示成功"); - AdUtils.adRecord("rewardVideo","adShow"); - } - - @Override - public void click() { - Log.i(TAG, "激励视频被点击"); - AdUtils.adRecord("rewardVideo","adClick"); - } - - @Override - public void error(String msg) { - } - - @Override - public void skip() { - Log.i(TAG, "激励视频被跳过"); - AdUtils.adRecord("rewardVideo","adSkip"); - } - - @Override - public void reward() { - Log.i(TAG, "激励视频计时完成"); - AdUtils.adRecord("rewardVideo","adFinishCount"); - } - }); - }); - - binding.llInterAd.setOnClickListener(v -> { - /* - * 参数 1 activity - * 参数 2 marginDp (float),插屏默认 margin 全屏幕的 24dp,此处允许开发者手动调节 margin 大小,单位为 dp,允许范围为 0dp (全屏) ~ 48dp,请开发者按需填写 - */ - DdSdkInterAd.show(this, 48f, new DdSdkInterAd.Callback() { - @Override - public void show() { - Log.i(TAG, "插屏广告展示成功"); - AdUtils.adRecord("inter","adShow"); - } - - @Override - public void click() { - Log.i(TAG, "插屏广告"); - AdUtils.adRecord("inter","adClick"); - } + binding.llRewardedVideo.setOnClickListener(v -> AdUtils.showRewardVideoAd(this, null)); - @Override - public void error(String msg) { - } - - @Override - public void close() { - Log.i(TAG, "插屏广告被关闭"); - AdUtils.adRecord("inter","adClose"); - } - }); - }); + binding.llInterAd.setOnClickListener(v -> AdUtils.showInterAd(this, null)); } - private void goDonate(String address) { try { Intent intent = new Intent(Intent.ACTION_VIEW); diff --git a/app/src/main/java/xyz/fycz/myreader/ui/activity/MoreSettingActivity.java b/app/src/main/java/xyz/fycz/myreader/ui/activity/MoreSettingActivity.java index 8cdd4fb..fcd40bf 100644 --- a/app/src/main/java/xyz/fycz/myreader/ui/activity/MoreSettingActivity.java +++ b/app/src/main/java/xyz/fycz/myreader/ui/activity/MoreSettingActivity.java @@ -71,6 +71,7 @@ public class MoreSettingActivity extends BaseActivity implements SharedPreferenc private boolean upMenu; private Setting mSetting; + private int mineShowMode; private boolean isVolumeTurnPage; private int resetScreenTime; private int sortStyle; @@ -115,6 +116,7 @@ public class MoreSettingActivity extends BaseActivity implements SharedPreferenc super.initData(savedInstanceState); needRefresh = false; mSetting = SysManager.getSetting(); + mineShowMode = SharedPreUtils.getInstance().getInt("mineShowMode", 0); isVolumeTurnPage = mSetting.isVolumeTurnPage(); alwaysNext = mSetting.isAlwaysNext(); resetScreenTime = mSetting.getResetScreen(); @@ -155,6 +157,7 @@ public class MoreSettingActivity extends BaseActivity implements SharedPreferenc protected void initWidget() { super.initWidget(); initSwitchStatus(); + initMineShowMode(); if (sortStyle == 1) { binding.tvBookSort.setText(getString(R.string.time_sort)); } else if (sortStyle == 2) { @@ -169,6 +172,23 @@ public class MoreSettingActivity extends BaseActivity implements SharedPreferenc binding.tvThreadNum.setText(getString(R.string.cur_thread_num, threadNum)); } + private void initMineShowMode() { + switch (mineShowMode){ + case 1: + binding.tvMineShow.setText(getString(R.string.show_cloud_only)); + break; + case 2: + binding.tvMineShow.setText(getString(R.string.show_user_cloud)); + break; + case 3: + binding.tvMineShow.setText(getString(R.string.hide_user_cloud)); + break; + default: + binding.tvMineShow.setText(getString(R.string.show_user_only)); + break; + } + } + @Override protected void processLogic() { SharedPreUtils.getInstance().getSharedPreferences().registerOnSharedPreferenceChangeListener(this); @@ -234,6 +254,18 @@ public class MoreSettingActivity extends BaseActivity implements SharedPreferenc setUpToolbar(); }); + binding.llMineShow.setOnClickListener(v -> { + BottomMenu.show(getString(R.string.mine_show_mode), getResources().getStringArray(R.array.mine_show)) + .setSelection(mineShowMode) + .setOnMenuItemClickListener((dialog, text, which) -> { + mineShowMode = which; + SharedPreUtils.getInstance().putInt("mineShowMode", mineShowMode); + initMineShowMode(); + needRefresh = true; + return false; + }).setCancelButton(R.string.cancel); + }); + binding.rlVolume.setOnClickListener( (v) -> { isVolumeTurnPage = !isVolumeTurnPage; diff --git a/app/src/main/java/xyz/fycz/myreader/ui/activity/SearchBookActivity.java b/app/src/main/java/xyz/fycz/myreader/ui/activity/SearchBookActivity.java index bbd443a..2be22e0 100644 --- a/app/src/main/java/xyz/fycz/myreader/ui/activity/SearchBookActivity.java +++ b/app/src/main/java/xyz/fycz/myreader/ui/activity/SearchBookActivity.java @@ -46,6 +46,7 @@ import xyz.fycz.myreader.common.APPCONST; import xyz.fycz.myreader.databinding.ActivitySearchBookBinding; import xyz.fycz.myreader.entity.SearchBookBean; import xyz.fycz.myreader.entity.Setting; +import xyz.fycz.myreader.entity.ad.AdBean; import xyz.fycz.myreader.greendao.entity.Book; import xyz.fycz.myreader.greendao.entity.SearchHistory; import xyz.fycz.myreader.greendao.entity.rule.BookSource; @@ -55,13 +56,12 @@ import xyz.fycz.myreader.model.SearchEngine; import xyz.fycz.myreader.model.mulvalmap.ConMVMap; import xyz.fycz.myreader.model.sourceAnalyzer.BookSourceManager; import xyz.fycz.myreader.ui.adapter.SearchAdapter; -import xyz.fycz.myreader.ui.adapter.SearchBookAdapter; -import xyz.fycz.myreader.ui.adapter.SearchHistoryAdapter; import xyz.fycz.myreader.ui.dialog.DialogCreator; import xyz.fycz.myreader.ui.dialog.MultiChoiceDialog; import xyz.fycz.myreader.util.SharedPreUtils; import xyz.fycz.myreader.util.ToastUtils; import xyz.fycz.myreader.util.help.StringHelper; +import xyz.fycz.myreader.util.utils.AdUtils; import xyz.fycz.myreader.util.utils.OkHttpUtils; import xyz.fycz.myreader.util.utils.RxUtils; import xyz.fycz.myreader.webapi.crawler.ReadCrawlerUtil; @@ -115,6 +115,7 @@ public class SearchBookActivity extends BaseActivity { private boolean foldSuggest; private boolean foldHistory; private boolean needReGetHistory; + private AdBean adBean; @Override protected void bindView() { @@ -278,6 +279,26 @@ public class SearchBookActivity extends BaseActivity { SharedPreUtils.getInstance().putBoolean("foldHistory", foldHistory); }); initHistoryList(); + adBean = AdUtils.getAdConfig().getSearch(); + if (AdUtils.getAdConfig().isHasAd() && AdUtils.adTime("search", adBean)) { + initAd(); + } + } + private void initAd() { + AdUtils.checkHasAd().subscribe(new MySingleObserver() { + @Override + public void onSuccess(@NonNull Boolean aBoolean) { + if (aBoolean) { + if (adBean.getStatus() == 1) { + AdUtils.getFlowAd(SearchBookActivity.this, 1, view ->{ + binding.getRoot().addView(view, 6); + }, "search"); + } else if (adBean.getStatus() == 2) { + AdUtils.showInterAd(SearchBookActivity.this, "search"); + } + } + } + }); } @Override @@ -397,16 +418,17 @@ public class SearchBookActivity extends BaseActivity { String searchGroup = SharedPreUtils.getInstance().getString("searchGroup"); menu.removeGroup(R.id.source_group); MenuItem item = menu.add(R.id.source_group, Menu.NONE, Menu.NONE, R.string.all_source); - MenuItem localItem = menu.add(R.id.source_group, Menu.NONE, Menu.NONE, R.string.local_source); - if ("".equals(searchGroup)) { - item.setChecked(true); - } else if (getString(R.string.local_source).equals(searchGroup)) { - localItem.setChecked(true); - } - List groupList = BookSourceManager.getEnableNoLocalGroupList(); + boolean hasChecked = false; + List groupList = BookSourceManager.getEnableGroupList(); for (String groupName : groupList) { item = menu.add(R.id.source_group, Menu.NONE, Menu.NONE, groupName); - if (groupName.equals(searchGroup)) item.setChecked(true); + if (groupName.equals(searchGroup)) { + item.setChecked(true); + hasChecked = true; + } + } + if (!hasChecked || "".equals(searchGroup)) { + item.setChecked(true); } menu.setGroupCheckable(R.id.source_group, true, true); } diff --git a/app/src/main/java/xyz/fycz/myreader/ui/activity/SourceSubscribeActivity.kt b/app/src/main/java/xyz/fycz/myreader/ui/activity/SourceSubscribeActivity.kt new file mode 100644 index 0000000..1c1cb7d --- /dev/null +++ b/app/src/main/java/xyz/fycz/myreader/ui/activity/SourceSubscribeActivity.kt @@ -0,0 +1,116 @@ +package xyz.fycz.myreader.ui.activity + +import android.os.Bundle +import androidx.appcompat.widget.Toolbar +import androidx.recyclerview.widget.LinearLayoutManager +import xyz.fycz.myreader.R +import xyz.fycz.myreader.base.BaseActivity +import xyz.fycz.myreader.base.adapter.BaseListAdapter +import xyz.fycz.myreader.base.adapter.IViewHolder +import xyz.fycz.myreader.common.URLCONST +import xyz.fycz.myreader.databinding.ActivitySourceSubscribeBinding +import xyz.fycz.myreader.entity.lanzou.LanZouFile +import xyz.fycz.myreader.greendao.entity.SubscribeFile +import xyz.fycz.myreader.ui.adapter.holder.SourceFileHolder +import xyz.fycz.myreader.util.ToastUtils +import xyz.fycz.myreader.webapi.LanZouApi + +/** + * @author fengyue + * @date 2022/3/3 9:56 + */ +class SourceSubscribeActivity : BaseActivity() { + private lateinit var binding: ActivitySourceSubscribeBinding + private lateinit var fileAdapter: BaseListAdapter + private var page = 1 + + override fun bindView() { + binding = ActivitySourceSubscribeBinding.inflate(layoutInflater) + setContentView(binding.root) + } + + override fun setUpToolbar(toolbar: Toolbar?) { + super.setUpToolbar(toolbar) + setStatusBarColor(R.color.colorPrimary, true) + supportActionBar?.title = "书源订阅" + } + + override fun initData(savedInstanceState: Bundle?) { + super.initData(savedInstanceState) + fileAdapter = object : BaseListAdapter() { + override fun createViewHolder(viewType: Int): IViewHolder { + return SourceFileHolder() + } + } + binding.rvFiles.layoutManager = LinearLayoutManager(this) + binding.rvFiles.adapter = fileAdapter + loadFiles() + } + + override fun initWidget() { + super.initWidget() + binding.srlFiles.setOnLoadMoreListener { loadFiles() } + binding.srlFiles.setOnRefreshListener { + page = 1 + loadFiles() + } + binding.loading.setOnReloadingListener { + page = 1 + loadFiles() + } + } + + private fun loadFiles() { + LanZouApi.getFoldFiles(URLCONST.SUB_SOURCE_URL, page, "fm9a") + .onSuccess { + if (it != null) { + if (page == 1) { + if (it.isEmpty()) { + binding.loading.showEmpty() + } else { + binding.loading.showFinish() + fileAdapter.refreshItems(lanZouFile2SubscribeFile(it)) + if (it.size < 50) { + binding.srlFiles.finishRefreshWithNoMoreData() + } else { + binding.srlFiles.finishRefresh() + } + } + } else { + fileAdapter.addItems(lanZouFile2SubscribeFile(it)) + if (it.size < 50) { + binding.srlFiles.finishLoadMoreWithNoMoreData() + } else { + binding.srlFiles.finishLoadMore() + } + } + page++ + } else { + binding.loading.showError() + } + }.onError { + ToastUtils.showError("" + it.localizedMessage) + } + } + + override fun initClick() { + super.initClick() + } + + private fun lanZouFile2SubscribeFile(lanZouFile: List): ArrayList { + val files = ArrayList() + lanZouFile.forEach { + val param = it.name_all.removeSuffix(".txt").split("#") + files.add( + SubscribeFile( + param[0], + param[1], + URLCONST.LAN_ZOU_URL + "/${it.id}", + param[2], + it.size + ) + ) + } + return files + } +} \ No newline at end of file diff --git a/app/src/main/java/xyz/fycz/myreader/ui/activity/SplashActivity.java b/app/src/main/java/xyz/fycz/myreader/ui/activity/SplashActivity.java index c2116cf..ece65ba 100644 --- a/app/src/main/java/xyz/fycz/myreader/ui/activity/SplashActivity.java +++ b/app/src/main/java/xyz/fycz/myreader/ui/activity/SplashActivity.java @@ -179,7 +179,6 @@ public class SplashActivity extends BaseActivity { @Override public void onSuccess(@NonNull Boolean aBoolean) { if (aBoolean) { - //AdUtils.initAd(); startWithAd(); binding.ivSplash.setVisibility(View.GONE); binding.llAd.setVisibility(View.VISIBLE); diff --git a/app/src/main/java/xyz/fycz/myreader/ui/adapter/SubscribeSourceAdapter.kt b/app/src/main/java/xyz/fycz/myreader/ui/adapter/SubscribeSourceAdapter.kt new file mode 100644 index 0000000..1763ec6 --- /dev/null +++ b/app/src/main/java/xyz/fycz/myreader/ui/adapter/SubscribeSourceAdapter.kt @@ -0,0 +1,58 @@ +package xyz.fycz.myreader.ui.adapter + +import android.widget.Filter +import xyz.fycz.myreader.base.adapter.IViewHolder +import xyz.fycz.myreader.greendao.entity.rule.BookSource +import xyz.fycz.myreader.ui.adapter.holder.SubscribeSourceHolder +import java.util.* + +/** + * @author fengyue + * @date 2022/3/3 12:08 + */ +class SubscribeSourceAdapter( + val sources: List, + private val onDelListener: OnDelListener +) : BaseSourceAdapter() { + override fun createViewHolder(viewType: Int): IViewHolder { + return SubscribeSourceHolder(checkMap, onDelListener) + } + + override fun getFilter(): Filter { + return object : Filter() { + override fun performFiltering(constraint: CharSequence): FilterResults { + val charString = constraint.toString() + var mFilterList: MutableList = ArrayList() + if (charString.isEmpty()) { + //没有过滤的内容,则使用源数据 + mFilterList = sources.toMutableList() + } else { + for (source in sources) { + //这里根据需求,添加匹配规则 + if (source.sourceName.contains(charString) || + source.sourceGroup.contains(charString) + ) { + mFilterList.add(source) + } + } + } + val filterResults = FilterResults() + filterResults.values = mFilterList + return filterResults + } + + //把过滤后的值返回出来 + override fun publishResults(constraint: CharSequence, results: FilterResults) { + refreshItems(results.values as List) + } + } + } + fun removeItem(pos: Int) { + mList.removeAt(pos) + notifyItemRemoved(pos) + if (pos != mList.size) notifyItemRangeChanged(pos, mList.size - pos) + } + interface OnDelListener { + fun onDel(which: Int, source: BookSource) + } +} \ No newline at end of file diff --git a/app/src/main/java/xyz/fycz/myreader/ui/adapter/holder/SourceFileHolder.kt b/app/src/main/java/xyz/fycz/myreader/ui/adapter/holder/SourceFileHolder.kt new file mode 100644 index 0000000..6888891 --- /dev/null +++ b/app/src/main/java/xyz/fycz/myreader/ui/adapter/holder/SourceFileHolder.kt @@ -0,0 +1,36 @@ +package xyz.fycz.myreader.ui.adapter.holder + +import android.annotation.SuppressLint +import android.widget.TextView +import androidx.recyclerview.widget.RecyclerView +import xyz.fycz.myreader.R +import xyz.fycz.myreader.base.adapter.ViewHolderImpl +import xyz.fycz.myreader.entity.lanzou.LanZouFile +import xyz.fycz.myreader.greendao.entity.SubscribeFile + +/** + * @author fengyue + * @date 2022/3/3 10:17 + */ +class SourceFileHolder : ViewHolderImpl() { + + private lateinit var name: TextView + private lateinit var sizeTime: TextView + + override fun getItemLayoutId(): Int { + return R.layout.item_lan_zou_file + } + + override fun initView() { + name = findById(R.id.tv_file_name) + sizeTime = findById(R.id.tv_file_size_time) + } + + @SuppressLint("SetTextI18n") + override fun onBind(holder: RecyclerView.ViewHolder?, data: SubscribeFile?, pos: Int) { + data?.let { + name.text = data.name + sizeTime.text = "${data.size} ${data.date}" + } + } +} \ No newline at end of file diff --git a/app/src/main/java/xyz/fycz/myreader/ui/adapter/holder/SubscribeSourceHolder.kt b/app/src/main/java/xyz/fycz/myreader/ui/adapter/holder/SubscribeSourceHolder.kt new file mode 100644 index 0000000..20c3f53 --- /dev/null +++ b/app/src/main/java/xyz/fycz/myreader/ui/adapter/holder/SubscribeSourceHolder.kt @@ -0,0 +1,96 @@ +package xyz.fycz.myreader.ui.adapter.holder + +import android.widget.CheckBox +import android.widget.TextView +import androidx.recyclerview.widget.RecyclerView +import io.reactivex.Observable +import io.reactivex.ObservableEmitter +import io.reactivex.ObservableOnSubscribe +import io.reactivex.android.schedulers.AndroidSchedulers +import io.reactivex.schedulers.Schedulers +import xyz.fycz.myreader.R +import xyz.fycz.myreader.base.adapter.ViewHolderImpl +import xyz.fycz.myreader.base.adapter2.onClick +import xyz.fycz.myreader.base.observer.MyObserver +import xyz.fycz.myreader.greendao.DbManager +import xyz.fycz.myreader.greendao.entity.rule.BookSource +import xyz.fycz.myreader.model.sourceAnalyzer.BookSourceManager +import xyz.fycz.myreader.ui.adapter.SubscribeSourceAdapter +import xyz.fycz.myreader.util.ToastUtils +import xyz.fycz.myreader.util.help.StringHelper +import xyz.fycz.myreader.util.utils.RxUtils +import java.util.* + +/** + * @author fengyue + * @date 2022/3/3 12:11 + */ +class SubscribeSourceHolder( + private val mCheckMap: HashMap, + private val onDelListener: SubscribeSourceAdapter.OnDelListener +) : ViewHolderImpl() { + + private var cbSource: CheckBox? = null + private var tvEnable: TextView? = null + private var tvDisable: TextView? = null + private var tvDelete: TextView? = null + + override fun getItemLayoutId(): Int { + return R.layout.item_subscribe_source + } + + override fun initView() { + cbSource = findById(R.id.cb_source) + tvEnable = findById(R.id.tv_enable) + tvDisable = findById(R.id.tv_disable) + tvDelete = findById(R.id.tv_delete) + } + + override fun onBind(holder: RecyclerView.ViewHolder, data: BookSource, pos: Int) { + banOrUse(data) + cbSource?.isChecked = mCheckMap[data] == true + tvEnable?.onClick { + data.enable = true + banOrUse(data) + DbManager.getDaoSession().bookSourceDao.insertOrReplace(data) + } + tvDisable?.onClick { + data.enable = false + banOrUse(data) + DbManager.getDaoSession().bookSourceDao.insertOrReplace(data) + } + tvDelete?.onClick { + Observable.create { e: ObservableEmitter -> + BookSourceManager.removeBookSource(data) + e.onNext(true) + }.compose { RxUtils.toSimpleSingle(it) } + .subscribe(object : MyObserver() { + override fun onNext(aBoolean: Boolean) { + onDelListener.onDel(pos, data) + } + + override fun onError(e: Throwable) { + ToastUtils.showError("删除失败") + } + }) + } + } + + private fun banOrUse(data: BookSource) { + if (data.enable) { + cbSource?.setTextColor(context.resources.getColor(R.color.textPrimary)) + if (!StringHelper.isEmpty(data.sourceGroup)) { + cbSource?.text = String.format("%s [%s]", data.sourceName, data.sourceGroup) + } else { + cbSource?.text = data.sourceName + } + } else { + cbSource?.setTextColor(context.resources.getColor(R.color.textSecondary)) + if (!StringHelper.isEmpty(data.sourceGroup)) { + cbSource?.text = String.format("(禁用中)%s [%s]", data.sourceName, data.sourceGroup) + } else { + cbSource?.text = String.format("(禁用中)%s", data.sourceName) + } + } + } +} \ No newline at end of file diff --git a/app/src/main/java/xyz/fycz/myreader/ui/fragment/DIYSourceFragment.java b/app/src/main/java/xyz/fycz/myreader/ui/fragment/DIYSourceFragment.java index dee88ce..5bf7791 100644 --- a/app/src/main/java/xyz/fycz/myreader/ui/fragment/DIYSourceFragment.java +++ b/app/src/main/java/xyz/fycz/myreader/ui/fragment/DIYSourceFragment.java @@ -3,9 +3,7 @@ package xyz.fycz.myreader.ui.fragment; import android.annotation.SuppressLint; import android.content.Intent; import android.os.Bundle; -import android.os.Parcelable; import android.text.TextUtils; -import android.util.Log; import android.view.Gravity; import android.view.LayoutInflater; import android.view.MenuInflater; @@ -19,18 +17,12 @@ import androidx.annotation.Nullable; import androidx.documentfile.provider.DocumentFile; import androidx.recyclerview.widget.ItemTouchHelper; import androidx.recyclerview.widget.LinearLayoutManager; -import androidx.recyclerview.widget.RecyclerView; -import com.hjq.permissions.OnPermissionCallback; -import com.hjq.permissions.XXPermissions; import com.kongzue.dialogx.dialogs.BottomMenu; import java.io.File; -import java.io.FileInputStream; import java.nio.charset.StandardCharsets; import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; import java.util.List; import io.reactivex.Observable; @@ -52,13 +44,11 @@ import xyz.fycz.myreader.ui.activity.BookSourceActivity; import xyz.fycz.myreader.ui.activity.SourceEditActivity; import xyz.fycz.myreader.ui.adapter.BookSourceAdapter; import xyz.fycz.myreader.ui.adapter.helper.ItemTouchCallback; -import xyz.fycz.myreader.ui.adapter.helper.OnStartDragListener; import xyz.fycz.myreader.ui.dialog.DialogCreator; import xyz.fycz.myreader.ui.dialog.LoadingDialog; import xyz.fycz.myreader.ui.dialog.MyAlertDialog; import xyz.fycz.myreader.util.ShareUtils; import xyz.fycz.myreader.util.ToastUtils; -import xyz.fycz.myreader.util.UriFileUtil; import xyz.fycz.myreader.util.utils.ClipBoardUtil; import xyz.fycz.myreader.util.utils.DocumentUtil; import xyz.fycz.myreader.util.utils.FileUtils; @@ -70,7 +60,6 @@ import xyz.fycz.myreader.widget.swipemenu.SwipeMenuLayout; import static android.app.Activity.RESULT_OK; import static android.text.TextUtils.isEmpty; -import static xyz.fycz.myreader.util.UriFileUtil.getPath; /** * @author fengyue @@ -364,7 +353,7 @@ public class DIYSourceFragment extends BaseFragment { */ public void showSourceGroupMenu(View view) { PopupMenu popupMenu = new PopupMenu(sourceActivity, view, Gravity.END); - List groupList = BookSourceManager.getNoLocalGroupList(); + List groupList = BookSourceManager.getGroupList(false); popupMenu.getMenu().add(0, 0, 0, "所有书源"); for (int i = 0; i < groupList.size(); i++) { popupMenu.getMenu().add(0, 0, i + 1, groupList.get(i)); diff --git a/app/src/main/java/xyz/fycz/myreader/ui/fragment/MineFragment.java b/app/src/main/java/xyz/fycz/myreader/ui/fragment/MineFragment.java index a5bdffe..6f867bb 100644 --- a/app/src/main/java/xyz/fycz/myreader/ui/fragment/MineFragment.java +++ b/app/src/main/java/xyz/fycz/myreader/ui/fragment/MineFragment.java @@ -3,6 +3,7 @@ package xyz.fycz.myreader.ui.fragment; import static android.app.Activity.RESULT_OK; import android.annotation.SuppressLint; +import android.content.Context; import android.content.Intent; import android.net.Uri; import android.os.Bundle; @@ -13,6 +14,8 @@ import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import androidx.activity.result.ActivityResultCallback; +import androidx.activity.result.contract.ActivityResultContract; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -136,6 +139,29 @@ public class MineFragment extends BaseFragment { binding.tvUser.setText(user.getUserName()); } binding.tvThemeModeSelect.setText(themeModeArr[themeMode]); + initShowMode(); + } + + private void initShowMode() { + int showMode = SharedPreUtils.getInstance().getInt("mineShowMode", 0); + switch (showMode){ + case 1: + binding.mineLlUser.setVisibility(View.GONE); + binding.mineLlCloud.setVisibility(View.VISIBLE); + break; + case 2: + binding.mineLlUser.setVisibility(View.VISIBLE); + binding.mineLlCloud.setVisibility(View.VISIBLE); + break; + case 3: + binding.mineLlUser.setVisibility(View.GONE); + binding.mineLlCloud.setVisibility(View.GONE); + break; + default: + binding.mineLlUser.setVisibility(View.VISIBLE); + binding.mineLlCloud.setVisibility(View.GONE); + break; + } } @Override @@ -312,9 +338,10 @@ public class MineFragment extends BaseFragment { binding.mineRlReadRecord.setOnClickListener(v -> { startActivity(new Intent(getContext(), ReadRecordActivity.class)); }); + binding.mineRlSetting.setOnClickListener(v -> { - Intent settingIntent = new Intent(getActivity(), MoreSettingActivity.class); - startActivity(settingIntent); + Intent intent = new Intent(getActivity(), MoreSettingActivity.class); + startActivityForResult(intent, APPCONST.REQUEST_SETTING); }); binding.mineRlThemeMode.setOnClickListener(v -> { /*if (themeModeDia != null) { @@ -586,15 +613,22 @@ public class MineFragment extends BaseFragment { @Override public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { if (resultCode == RESULT_OK) { + if (data == null) { + return; + } switch (requestCode) { case APPCONST.REQUEST_LOGIN: - assert data != null; isLogin = data.getBooleanExtra("isLogin", false); user = UserService.INSTANCE.readConfig(); if (isLogin && user != null) { binding.tvUser.setText(user.getUserName()); } break; + case APPCONST.REQUEST_SETTING: + if (data.getBooleanExtra(APPCONST.RESULT_NEED_REFRESH, false)){ + initShowMode(); + } + break; } } } diff --git a/app/src/main/java/xyz/fycz/myreader/ui/fragment/SubscribeSourceFragment.kt b/app/src/main/java/xyz/fycz/myreader/ui/fragment/SubscribeSourceFragment.kt new file mode 100644 index 0000000..0aeb580 --- /dev/null +++ b/app/src/main/java/xyz/fycz/myreader/ui/fragment/SubscribeSourceFragment.kt @@ -0,0 +1,202 @@ +package xyz.fycz.myreader.ui.fragment + +import android.content.DialogInterface +import android.content.Intent +import android.os.Bundle +import android.view.* +import android.widget.PopupMenu +import androidx.recyclerview.widget.LinearLayoutManager +import io.reactivex.Single +import io.reactivex.SingleEmitter +import xyz.fycz.myreader.R +import xyz.fycz.myreader.base.BaseFragment +import xyz.fycz.myreader.base.adapter2.onClick +import xyz.fycz.myreader.base.observer.MySingleObserver +import xyz.fycz.myreader.databinding.FragmentSubscribeSourceBinding +import xyz.fycz.myreader.greendao.DbManager +import xyz.fycz.myreader.greendao.entity.rule.BookSource +import xyz.fycz.myreader.model.sourceAnalyzer.BookSourceManager +import xyz.fycz.myreader.ui.activity.BookSourceActivity +import xyz.fycz.myreader.ui.activity.SourceSubscribeActivity +import xyz.fycz.myreader.ui.adapter.SubscribeSourceAdapter +import xyz.fycz.myreader.ui.dialog.DialogCreator +import xyz.fycz.myreader.util.ToastUtils +import xyz.fycz.myreader.util.utils.RxUtils +import xyz.fycz.myreader.widget.DividerItemDecoration +import java.util.ArrayList + +/** + * @author fengyue + * @date 2022/3/3 11:36 + */ +class SubscribeSourceFragment(private val sourceActivity: BookSourceActivity) : BaseFragment() { + private lateinit var binding: FragmentSubscribeSourceBinding + private var mBookSources: MutableList? = null + private var mAdapter: SubscribeSourceAdapter? = null + private var featuresMenu: PopupMenu? = null + override fun bindView(inflater: LayoutInflater, container: ViewGroup): View { + binding = FragmentSubscribeSourceBinding.inflate(inflater, container, false) + return binding.root + } + + override fun initData(savedInstanceState: Bundle?) { + super.initData(savedInstanceState) + Single.create { emitter: SingleEmitter> -> + emitter.onSuccess(BookSourceManager.getAllLocalSource()) + }.compose { RxUtils.toSimpleSingle(it) } + .subscribe(object : MySingleObserver>() { + override fun onSuccess(sources: List) { + mBookSources = sources.toMutableList() + initSourceList() + } + + override fun onError(e: Throwable) { + ToastUtils.showError(" 数据加载失败\n${e.localizedMessage}") + } + }) + } + + private fun initSourceList() { + mAdapter = + SubscribeSourceAdapter(mBookSources!!, object : SubscribeSourceAdapter.OnDelListener { + override fun onDel(which: Int, source: BookSource) { + mBookSources?.remove(source) + mAdapter?.removeItem(which) + } + }) + mAdapter?.setOnItemClickListener { _, pos -> + mAdapter?.setCheckedItem(pos) + } + binding.recyclerView.layoutManager = LinearLayoutManager(context) + binding.recyclerView.adapter = mAdapter + //设置分割线 + binding.recyclerView.addItemDecoration(DividerItemDecoration(context)) + mAdapter?.refreshItems(mBookSources) + } + + override fun initWidget(savedInstanceState: Bundle?) { + super.initWidget(savedInstanceState) + } + + override fun initClick() { + super.initClick() + binding.tvSubscribeSource.onClick { + startActivity(Intent(context, SourceSubscribeActivity::class.java)) + } + binding.ivGroup.setOnClickListener { view: View? -> + showSourceGroupMenu(view) + } + binding.ivMenu.setOnClickListener { v -> + if (featuresMenu == null) { + initFeaturesMenu(v) + } + featuresMenu?.show() + } + } + + /** + * 显示书源分组菜单 + */ + private fun showSourceGroupMenu(view: View?) { + val popupMenu = PopupMenu(sourceActivity, view, Gravity.END) + val groupList = BookSourceManager.getGroupList(true) + popupMenu.menu.add(0, 0, 0, "所有书源") + for (i in groupList.indices) { + popupMenu.menu.add(0, 0, i + 1, groupList[i]) + } + popupMenu.setOnMenuItemClickListener { menuItem: MenuItem -> + if (menuItem.order > 0) { + sourceActivity.searchView.onActionViewExpanded() + sourceActivity.searchView.clearFocus() + sourceActivity.searchView.setQuery(menuItem.title, false) + } else { + sourceActivity.searchView.onActionViewCollapsed() + } + true + } + popupMenu.show() + } + + private fun initFeaturesMenu(view: View) { + featuresMenu = PopupMenu(sourceActivity, view, Gravity.END) + //获取菜单填充器 + val inflater = featuresMenu?.menuInflater + //填充菜单 + inflater?.inflate(R.menu.menu_subscribe_source, featuresMenu?.menu) + featuresMenu?.setOnMenuItemClickListener { item: MenuItem -> + when (item.itemId) { + R.id.action_select_all -> { + mAdapter?.setCheckedAll(true) + } + R.id.action_reverse_selected -> { + mAdapter?.reverseChecked() + } + R.id.action_reverse_enable_selected -> { + val bookSources = + mAdapter?.checkedBookSources + reverseSources(bookSources) + } + R.id.action_delete_selected -> { + val bookSources = + mAdapter?.checkedBookSources + deleteSources(bookSources, false) + } + } + true + } + } + + private fun reverseSources(mBookSources: MutableList?) { + if (mBookSources != null) { + for (source in mBookSources) { + source.enable = !source.enable + } + DbManager.getDaoSession().bookSourceDao.insertOrReplaceInTx(mBookSources) + mAdapter?.notifyDataSetChanged() + } + } + + private fun deleteSources(mBookSources: MutableList?, isDisabled: Boolean) { + if (mBookSources == null || mBookSources.size == 0) { + ToastUtils.showWarring("当前没有选择任何书源,无法删除!") + return + } + val title: String + val msg: String + val successTip: String + if (isDisabled) { + title = "删除禁用书源" + msg = "确定要删除所有禁用书源吗?" + successTip = "禁用书源删除成功" + } else { + title = "删除选中书源" + msg = "确定要删除所有选中书源吗?" + successTip = "选中书源删除成功" + } + DialogCreator.createCommonDialog( + sourceActivity, title, + msg, true, + { _: DialogInterface?, _: Int -> + val sources: MutableList = + ArrayList() + if (isDisabled) { + for (source in mBookSources) { + if (!source.enable) { + sources.add(source) + } + } + } else { + sources.addAll(mBookSources) + } + BookSourceManager.removeBookSources(sources) + mBookSources.removeAll(sources) + mAdapter?.removeItems(sources) + ToastUtils.showSuccess(successTip) + }, null + ) + } + + fun startSearch(newText: String?) { + mAdapter?.filter?.filter(newText) + } +} \ No newline at end of file diff --git a/app/src/main/java/xyz/fycz/myreader/util/utils/AdUtils.java b/app/src/main/java/xyz/fycz/myreader/util/utils/AdUtils.java index 0996fa9..4cc4888 100644 --- a/app/src/main/java/xyz/fycz/myreader/util/utils/AdUtils.java +++ b/app/src/main/java/xyz/fycz/myreader/util/utils/AdUtils.java @@ -1,7 +1,12 @@ package xyz.fycz.myreader.util.utils; +import android.app.Activity; import android.util.Log; +import android.view.View; +import com.weaction.ddsdk.ad.DdSdkFlowAd; +import com.weaction.ddsdk.ad.DdSdkInterAd; +import com.weaction.ddsdk.ad.DdSdkRewardAd; import com.weaction.ddsdk.base.DdSdkHelper; import com.weaction.ddsdk.bean.DDSDK; @@ -17,7 +22,8 @@ import okhttp3.RequestBody; import xyz.fycz.myreader.application.App; import xyz.fycz.myreader.base.observer.MySingleObserver; import xyz.fycz.myreader.common.URLCONST; -import xyz.fycz.myreader.entity.AdBean; +import xyz.fycz.myreader.entity.ad.AdBean; +import xyz.fycz.myreader.entity.ad.AdConfig; import xyz.fycz.myreader.model.user.UserService; import xyz.fycz.myreader.util.SharedPreUtils; import xyz.fycz.myreader.util.help.DateHelper; @@ -29,20 +35,26 @@ import xyz.fycz.myreader.util.help.DateHelper; public class AdUtils { public static final String TAG = AdUtils.class.getSimpleName(); private static boolean hasInitAd = false; - private static AdBean adConfig; + private static AdConfig adConfig; static { - String config = SharedPreUtils.getInstance(true).getString("adConfig"); - adConfig = GsonExtensionsKt.getGSON().fromJson(config, AdBean.class); + String config = getSp().getString("adConfig"); + adConfig = GsonExtensionsKt.getGSON().fromJson(config, AdConfig.class); if (adConfig == null || adConfig.getBackAdTime() == 0) { - adConfig = new AdBean(false, 20, 60); + adConfig = new AdConfig(false, 60, 20, + 60, 6, 3, 48); } } + public static SharedPreUtils getSp() { + return SharedPreUtils.getInstance(true); + } + public static Single checkHasAd() { + initAd(); return Single.create((SingleOnSubscribe) emitter -> { boolean hasAd = false; - if (!adConfig.isCloud()) { + if (!adConfig.isCloud() || isExpire()) { MediaType mediaType = MediaType.parse("application/x-www-form-urlencoded"); String body = "type=adConfig" + UserService.INSTANCE.makeAuth(); RequestBody requestBody = RequestBody.create(mediaType, body); @@ -57,12 +69,13 @@ public class AdUtils { } } else { String res = jsonObject.getString("result"); - SharedPreUtils.getInstance(true).putString("adConfig", res); - adConfig = GsonExtensionsKt.getGSON().fromJson(res, AdBean.class); + adConfig = GsonExtensionsKt.getGSON().fromJson(res, AdConfig.class); adConfig.setCloud(true); hasAd = adConfig.isHasAd(); + getSp().putString("adConfig", res); + getSp().putLong("adConfigTime", System.currentTimeMillis()); } - Log.i(TAG, "hasAd:" + hasAd); + Log.i(TAG, "adConfig:" + adConfig); } catch (JSONException e) { e.printStackTrace(); } @@ -140,25 +153,152 @@ public class AdUtils { } public static void backTime() { - SharedPreUtils.getInstance(true).putLong("backTime", System.currentTimeMillis()); + getSp().putLong("backTime", System.currentTimeMillis()); } public static boolean backSplashAd() { if (!adConfig.isHasAd()) return false; - SharedPreUtils sp = SharedPreUtils.getInstance(true); - Long splashAdTime = sp.getLong("splashAdTime"); - Long backTime = sp.getLong("backTime"); - Long currentTime = System.currentTimeMillis(); + long splashAdTime = getSp().getLong("splashAdTime"); + long backTime = getSp().getLong("backTime"); + long currentTime = System.currentTimeMillis(); + Log.d(TAG, "currentTime - splashAdTime=" + (currentTime - splashAdTime)); + Log.d(TAG, "currentTime - backTime=" + (currentTime - splashAdTime)); + Log.d(TAG, "adConfig.getIntervalAdTime()=" + (adConfig.getIntervalAdTime() * 60L * 1000)); + Log.d(TAG, "adConfig.getBackAdTime()=" + (adConfig.getBackAdTime() * 60L * 1000)); return currentTime - splashAdTime >= adConfig.getIntervalAdTime() * 60L * 1000 || currentTime - backTime >= adConfig.getBackAdTime() * 60L * 1000; } - public static AdBean getAdConfig() { + private static boolean isExpire() { + long adConfigTime = getSp().getLong("adConfigTime"); + long currentTime = System.currentTimeMillis(); + return currentTime - adConfigTime >= adConfig.getExpireTime() * 60L * 1000; + } + + public static boolean adTime(String adTag, AdBean adBean){ + if (adBean.getStatus() == 0) return false; + long adTime = getSp().getLong(adTag + "Time"); + long currentTime = System.currentTimeMillis(); + return currentTime - adTime >= adBean.getInterval() * 60L * 1000; + } + + /** + * @param activity + * @param type 1小、4中 + * @param flowAd + */ + public static void getFlowAd(Activity activity, int type, FlowAd flowAd, String adTag) { + try { + new DdSdkFlowAd().getFlowViews(activity, type, new DdSdkFlowAd.FlowCallback() { + // 信息流广告拉取完毕后返回的 views + @Override + public void getFlowView(View view) { + flowAd.getView(view); + } + + // 信息流广告展示后调用 + @Override + public void show() { + AdUtils.adRecord("flow", "adShow"); + Log.d(TAG, "信息流广告展示成功"); + if (adTag != null) { + getSp().putLong(adTag + "Time", System.currentTimeMillis()); + } + } + + // 广告拉取失败调用 + @Override + public void error(String msg) { + Log.d(TAG, "广告拉取失败\n" + msg); + } + }); + } catch (Exception e) { + e.printStackTrace(); + } + } + + public static void showInterAd(Activity activity, String adTag) { + /* + * 参数 1 activity + * 参数 2 marginDp (float),插屏默认 margin 全屏幕的 24dp,此处允许开发者手动调节 margin 大小,单位为 dp,允许范围为 0dp (全屏) ~ 48dp,请开发者按需填写 + */ + try { + DdSdkInterAd.show(activity, 48f, new DdSdkInterAd.Callback() { + @Override + public void show() { + Log.i(TAG, "插屏广告展示成功"); + AdUtils.adRecord("inter", "adShow"); + if (adTag != null) { + getSp().putLong(adTag + "Time", System.currentTimeMillis()); + } + } + + @Override + public void click() { + Log.i(TAG, "插屏广告"); + AdUtils.adRecord("inter", "adClick"); + } + + @Override + public void error(String msg) { + } + + @Override + public void close() { + Log.i(TAG, "插屏广告被关闭"); + AdUtils.adRecord("inter", "adClose"); + } + }); + } catch (Exception e) { + e.printStackTrace(); + } + } + + public static void showRewardVideoAd(Activity activity, RewardAd rewardAd) { + try { + DdSdkRewardAd.show(activity, new DdSdkRewardAd.DdSdkRewardCallback() { + @Override + public void show() { + Log.i(TAG, "激励视频展示成功"); + AdUtils.adRecord("rewardVideo", "adShow"); + } + + @Override + public void click() { + Log.i(TAG, "激励视频被点击"); + AdUtils.adRecord("rewardVideo", "adClick"); + } + + @Override + public void error(String msg) { + } + + @Override + public void skip() { + Log.i(TAG, "激励视频被跳过"); + AdUtils.adRecord("rewardVideo", "adSkip"); + } + + @Override + public void reward() { + if (rewardAd != null) { + rewardAd.reward(); + } + Log.i(TAG, "激励视频计时完成"); + AdUtils.adRecord("rewardVideo", "adFinishCount"); + } + }); + } catch (Exception e) { + e.printStackTrace(); + } + } + + public static AdConfig getAdConfig() { return adConfig; } public static void initAd() { - /*if (!hasInitAd) { + if (!hasInitAd) { hasInitAd = true; DdSdkHelper.init(new DDSDK.Builder() .setUserId("1234") @@ -167,18 +307,17 @@ public class AdUtils { .setCsjAppId("5273043") .setApp(App.getApplication()) .setShowLog(App.isDebug()) + .setCustomRequestPermission(true) .create() ); - }*/ - DdSdkHelper.init(new DDSDK.Builder() - .setUserId("1234") - .setAppId("216") - .setAppKey("51716a16fbdf50905704b6575b1b3b60") - .setCsjAppId("5273043") - .setApp(App.getApplication()) - .setShowLog(App.isDebug()) - .setCustomRequestPermission(true) - .create() - ); + } + } + + public interface FlowAd { + void getView(View view); + } + + public interface RewardAd { + void reward(); } } diff --git a/app/src/main/java/xyz/fycz/myreader/util/utils/OkHttpUtils.java b/app/src/main/java/xyz/fycz/myreader/util/utils/OkHttpUtils.java index d9a6fde..08d0de5 100644 --- a/app/src/main/java/xyz/fycz/myreader/util/utils/OkHttpUtils.java +++ b/app/src/main/java/xyz/fycz/myreader/util/utils/OkHttpUtils.java @@ -41,6 +41,7 @@ import xyz.fycz.myreader.entity.StrResponse; import xyz.fycz.myreader.greendao.entity.rule.BookSource; import xyz.fycz.myreader.greendao.service.CookieStore; import xyz.fycz.myreader.model.third2.analyzeRule.AnalyzeUrl; +import xyz.fycz.myreader.model.third3.http.HttpHelperKt; import static xyz.fycz.myreader.util.help.SSLSocketClient.createSSLSocketFactory; import static xyz.fycz.myreader.util.help.SSLSocketClient.createTrustAllManager; @@ -48,22 +49,8 @@ import static xyz.fycz.myreader.util.help.SSLSocketClient.getHeaderInterceptor; public class OkHttpUtils { - public static OkHttpClient mClient; - - public static synchronized OkHttpClient getOkHttpClient() { - if (mClient == null) { - OkHttpClient.Builder builder = new OkHttpClient.Builder(); - builder.connectTimeout(5, TimeUnit.SECONDS) - .readTimeout(10, TimeUnit.SECONDS) - .writeTimeout(10, TimeUnit.SECONDS) - .sslSocketFactory(createSSLSocketFactory(), createTrustAllManager()) - .hostnameVerifier((hostname, session) -> true) - .protocols(Collections.singletonList(Protocol.HTTP_1_1)) - .addInterceptor(getHeaderInterceptor()); - mClient = builder - .build(); - } - return mClient; + public static OkHttpClient getOkHttpClient() { + return HttpHelperKt.getOkHttpClient(); } /** diff --git a/app/src/main/java/xyz/fycz/myreader/util/utils/ShareBookUtil.java b/app/src/main/java/xyz/fycz/myreader/util/utils/ShareBookUtil.java index 1d29e35..ab315f1 100644 --- a/app/src/main/java/xyz/fycz/myreader/util/utils/ShareBookUtil.java +++ b/app/src/main/java/xyz/fycz/myreader/util/utils/ShareBookUtil.java @@ -67,7 +67,7 @@ public class ShareBookUtil { ToastUtils.showInfo("正在生成分享图片"); Single.create((SingleOnSubscribe) emitter -> { // 使用url - String url = SharedPreUtils.getInstance().getString(context.getString(R.string.downloadLink), URLCONST.LAN_ZOUS_URL); + String url = SharedPreUtils.getInstance().getString(context.getString(R.string.downloadLink), URLCONST.LAN_ZOU_URL); if (url == null) url = ""; diff --git a/app/src/main/java/xyz/fycz/myreader/webapi/LanZouApi.kt b/app/src/main/java/xyz/fycz/myreader/webapi/LanZouApi.kt index 032ef89..42b241b 100644 --- a/app/src/main/java/xyz/fycz/myreader/webapi/LanZouApi.kt +++ b/app/src/main/java/xyz/fycz/myreader/webapi/LanZouApi.kt @@ -1,35 +1,94 @@ package xyz.fycz.myreader.webapi +import android.util.Log +import com.google.gson.JsonParser import io.reactivex.Observable +import kotlinx.coroutines.runBlocking import okhttp3.MediaType.Companion.toMediaTypeOrNull import okhttp3.RequestBody.Companion.toRequestBody import org.jsoup.Jsoup import xyz.fycz.myreader.common.URLCONST -import xyz.fycz.myreader.entity.LanZouBean +import xyz.fycz.myreader.entity.lanzou.LanZouFile +import xyz.fycz.myreader.entity.lanzou.LanZouParseBean +import xyz.fycz.myreader.model.third3.Coroutine +import xyz.fycz.myreader.model.third3.http.getProxyClient +import xyz.fycz.myreader.model.third3.http.newCallResponseBody +import xyz.fycz.myreader.model.third3.http.postForm +import xyz.fycz.myreader.model.third3.http.text +import xyz.fycz.myreader.util.ToastUtils import xyz.fycz.myreader.util.help.StringHelper -import xyz.fycz.myreader.util.utils.GSON -import xyz.fycz.myreader.util.utils.OkHttpUtils -import xyz.fycz.myreader.util.utils.fromJsonObject -import xyz.fycz.myreader.util.utils.splitNotBlank +import xyz.fycz.myreader.util.utils.* +import java.lang.Exception import java.net.HttpURLConnection import java.net.URL import java.util.* +import kotlin.collections.HashMap /** * @author fengyue * @date 2022/1/22 18:50 */ object LanZouApi { + private val paramCathe = mutableMapOf>() - fun getUrl(url: String): Observable { + fun getFoldFiles( + foldUrl: String, + page: Int, + pwd: String? = null + ): Coroutine?> { + return Coroutine.async { + val params = if (page == 1) { + getFoldParams(OkHttpUtils.getHtml(foldUrl), page, pwd) + } else { + paramCathe[foldUrl] ?: getFoldParams(OkHttpUtils.getHtml(foldUrl), page, pwd) + } + params["pg"] = page + paramCathe[foldUrl] = params + val res = getProxyClient().newCallResponseBody { + url(URLCONST.LAN_ZOU_URL + "/filemoreajax.php") + postForm(params) + }.text() + Log.d("getFoldFiles", params.toString()) + val json = JsonParser.parseString(res).asJsonObject + val zt = json["zt"].asInt + val info = json["info"].asString + if (zt == 1) { + val file = json["text"].toString() + GSON.fromJsonArray(file) + } else { + throw Exception(info) + } + } + } + + private fun getFoldParams(html: String, page: Int, pwd: String? = null): HashMap { + val params = HashMap() + params["lx"] = 2 + params["pg"] = page + params["fid"] = StringUtils.getSubString(html, "'fid':", ",") + params["uid"] = StringUtils.getSubString(html, "'uid':'", "',") + params["rep"] = 0 + val t = StringUtils.getSubString(html, "'t':", ",") + val k = StringUtils.getSubString(html, "'k':", ",") + params["t"] = StringUtils.getSubString(html, "var $t = '", "';") + params["k"] = StringUtils.getSubString(html, "var $k = '", "';") + params["up"] = 1 + pwd?.let { + params["ls"] = 1 + params["pwd"] = pwd + } + return params + } + + fun getFileUrl(url: String): Observable { url.replace("\\s".toRegex(), "").let { val regex = ",|,|密码:".toRegex() if (it.contains(regex)) { it.split(regex).let { arr -> - return getUrl(arr[0], arr[1]) + return getFileUrl(arr[0], arr[1]) } } else { - return getUrl(it, "") + return getFileUrl(it, "") } } } @@ -40,7 +99,7 @@ object LanZouApi { * @param url * @param password */ - private fun getUrl(url: String, password: String = ""): Observable { + private fun getFileUrl(url: String, password: String = ""): Observable { return Observable.create { val html = OkHttpUtils.getHtml(url) val url2 = if (password.isEmpty()) { @@ -61,7 +120,7 @@ object LanZouApi { private fun getUrl1(html: String): String { val doc = Jsoup.parse(html) - return URLCONST.LAN_ZOUS_URL + doc.getElementsByTag("iframe").attr("src") + return URLCONST.LAN_ZOU_URL + doc.getElementsByTag("iframe").attr("src") } private fun getKey(html: String): String { @@ -89,7 +148,7 @@ object LanZouApi { headers["Referer"] = referer val html = OkHttpUtils.getHtml( - URLCONST.LAN_ZOUS_URL + "/ajaxm.php", requestBody, + URLCONST.LAN_ZOU_URL + "/ajaxm.php", requestBody, "UTF-8", headers ) return getUrl2(html) @@ -105,7 +164,7 @@ object LanZouApi { var url = info[2].substring(info[2].indexOf(":") + 2, info[2].lastIndexOf("\"")) dom = dom.replace("\\", "") url = url.replace("\\", "")*/ - val lanZouBean = GSON.fromJsonObject(o) + val lanZouBean = GSON.fromJsonObject(o) lanZouBean?.run { return if (zt == 1) { "$dom/file/$url" diff --git a/app/src/main/java/xyz/fycz/myreader/webapi/LanZousApi.java b/app/src/main/java/xyz/fycz/myreader/webapi/LanZousApi.java index 679c297..f5ef2ce 100644 --- a/app/src/main/java/xyz/fycz/myreader/webapi/LanZousApi.java +++ b/app/src/main/java/xyz/fycz/myreader/webapi/LanZousApi.java @@ -133,7 +133,7 @@ public class LanZousApi { HashMap headers = new HashMap<>(); headers.put("Referer", referer); - String html = OkHttpUtils.getHtml(URLCONST.LAN_ZOUS_URL + "/ajaxm.php", requestBody, + String html = OkHttpUtils.getHtml(URLCONST.LAN_ZOU_URL + "/ajaxm.php", requestBody, "UTF-8", headers); emitter.onSuccess(getUrl2(html)); }).compose(RxUtils::toSimpleSingle).subscribe(new MySingleObserver() { @@ -151,7 +151,7 @@ public class LanZousApi { private static String getUrl1(String html) { Document doc = Jsoup.parse(html); - return URLCONST.LAN_ZOUS_URL + doc.getElementsByClass("ifr2").attr("src"); + return URLCONST.LAN_ZOU_URL + doc.getElementsByClass("ifr2").attr("src"); } private static String getKey(String html) { diff --git a/app/src/main/java/xyz/fycz/myreader/webapi/crawler/ReadCrawlerUtil.java b/app/src/main/java/xyz/fycz/myreader/webapi/crawler/ReadCrawlerUtil.java index 0a8a988..5b1411e 100644 --- a/app/src/main/java/xyz/fycz/myreader/webapi/crawler/ReadCrawlerUtil.java +++ b/app/src/main/java/xyz/fycz/myreader/webapi/crawler/ReadCrawlerUtil.java @@ -208,6 +208,9 @@ public class ReadCrawlerUtil { return new BaseSourceCrawlerNoInfo(crawler); } } else { + if (THIRD_3_SOURCE.equals(source.getSourceType())) { + return new Third3Crawler(source); + } Class clz = Class.forName(source.getSourceUrl()); return (ReadCrawler) clz.newInstance(); } diff --git a/app/src/main/res/layout/activity_more_setting.xml b/app/src/main/res/layout/activity_more_setting.xml index f7cff75..4f6b905 100644 --- a/app/src/main/res/layout/activity_more_setting.xml +++ b/app/src/main/res/layout/activity_more_setting.xml @@ -49,6 +49,32 @@ android:textColor="@color/textAssist" /> + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_mine.xml b/app/src/main/res/layout/fragment_mine.xml index ad34f60..89797bb 100644 --- a/app/src/main/res/layout/fragment_mine.xml +++ b/app/src/main/res/layout/fragment_mine.xml @@ -1,7 +1,6 @@ - + - - - + - + /> - + + + + - - + - + - + + - - + android:layout_height="wrap_content" + android:orientation="vertical"> + - + - + - + - + - + - + - + - + - + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_lan_zou_file.xml b/app/src/main/res/layout/item_lan_zou_file.xml new file mode 100644 index 0000000..58af23a --- /dev/null +++ b/app/src/main/res/layout/item_lan_zou_file.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_subscribe_source.xml b/app/src/main/res/layout/item_subscribe_source.xml new file mode 100644 index 0000000..a1e814f --- /dev/null +++ b/app/src/main/res/layout/item_subscribe_source.xml @@ -0,0 +1,60 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/menu/menu_subscribe_source.xml b/app/src/main/res/menu/menu_subscribe_source.xml new file mode 100644 index 0000000..d3b9d9c --- /dev/null +++ b/app/src/main/res/menu/menu_subscribe_source.xml @@ -0,0 +1,18 @@ + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 65827ed..0fc05c1 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -434,7 +434,9 @@ 校验 新建书源 导入书源 + 书源订阅 书源说明 + 订阅书源说明 取消全选 删除禁用书源 反转书源可用性 @@ -526,6 +528,13 @@ 清除搜索记录 收起 展开 + 拷贝书源 + 蓝奏云直链解析 + 我的界面显示方式 + 仅显示用户 + 仅显示云服务 + 显示用户及云服务 + 隐藏用户及云服务 @@ -541,10 +550,9 @@ 没有网络 网络连接超时 数据解析失败 - 拷贝书源 - 蓝奏云直链解析 + 跟随系统 常亮 @@ -634,4 +642,11 @@ 默认路径 系统文件夹选择器 + + + @string/show_user_only + @string/show_cloud_only + @string/show_user_cloud + @string/hide_user_cloud +