From 7d39207cfeff7e4233ca9ff1c2d1af2a8f385395 Mon Sep 17 00:00:00 2001 From: gedoor Date: Wed, 21 Apr 2021 08:29:35 +0800 Subject: [PATCH 01/48] =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/java/io/legado/app/ui/rss/read/ReadRssActivity.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/app/src/main/java/io/legado/app/ui/rss/read/ReadRssActivity.kt b/app/src/main/java/io/legado/app/ui/rss/read/ReadRssActivity.kt index 05789e00a..95aaf8325 100644 --- a/app/src/main/java/io/legado/app/ui/rss/read/ReadRssActivity.kt +++ b/app/src/main/java/io/legado/app/ui/rss/read/ReadRssActivity.kt @@ -37,7 +37,6 @@ class ReadRssActivity : VMBaseActivity override val viewModel: ReadRssViewModel by viewModels() - private val savePathRequestCode = 132 private val imagePathKey = "" private var starMenuItem: MenuItem? = null private var ttsMenuItem: MenuItem? = null From 9e0547b03532ee228a6ae2813013d5169adfef53 Mon Sep 17 00:00:00 2001 From: gedoor Date: Sun, 25 Apr 2021 19:24:05 +0800 Subject: [PATCH 02/48] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E9=AB=98=E5=88=B7?= =?UTF-8?q?=E8=AE=BE=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/io/legado/app/base/BaseActivity.kt | 20 +++++++++++++++++++ .../java/io/legado/app/constant/PreferKey.kt | 1 + .../java/io/legado/app/data/entities/Book.kt | 2 ++ app/src/main/res/values-zh-rHK/strings.xml | 2 ++ app/src/main/res/values-zh-rTW/strings.xml | 2 ++ app/src/main/res/values-zh/strings.xml | 2 ++ app/src/main/res/values/strings.xml | 2 ++ app/src/main/res/xml/pref_config_other.xml | 6 ++++++ 8 files changed, 37 insertions(+) diff --git a/app/src/main/java/io/legado/app/base/BaseActivity.kt b/app/src/main/java/io/legado/app/base/BaseActivity.kt index ef9c23953..7ae907b99 100644 --- a/app/src/main/java/io/legado/app/base/BaseActivity.kt +++ b/app/src/main/java/io/legado/app/base/BaseActivity.kt @@ -14,6 +14,7 @@ import androidx.viewbinding.ViewBinding import io.legado.app.App import io.legado.app.R import io.legado.app.constant.AppConst +import io.legado.app.constant.PreferKey import io.legado.app.constant.Theme import io.legado.app.help.AppConfig import io.legado.app.help.ThemeConfig @@ -66,6 +67,25 @@ abstract class BaseActivity( } override fun onCreate(savedInstanceState: Bundle?) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && + getPrefBoolean(PreferKey.highBrush) + ) { + /** + * 添加高刷新率支持 + */ + // 获取系统window支持的模式 + val modes = window.windowManager.defaultDisplay.supportedModes + // 对获取的模式,基于刷新率的大小进行排序,从小到大排序 + modes.sortBy { + it.refreshRate + } + window.let { + val lp = it.attributes + // 取出最大的那一个刷新率,直接设置给window + lp.preferredDisplayModeId = modes.last().modeId + it.attributes = lp + } + } window.decorView.disableAutoFill() initTheme() super.onCreate(savedInstanceState) diff --git a/app/src/main/java/io/legado/app/constant/PreferKey.kt b/app/src/main/java/io/legado/app/constant/PreferKey.kt index 0d1e5ef7e..651830256 100644 --- a/app/src/main/java/io/legado/app/constant/PreferKey.kt +++ b/app/src/main/java/io/legado/app/constant/PreferKey.kt @@ -73,6 +73,7 @@ object PreferKey { const val exportUseReplace = "exportUseReplace" const val useZhLayout = "useZhLayout" const val fullScreenGesturesSupport = "fullScreenGesturesSupport" + const val highBrush = "highBrush" const val cPrimary = "colorPrimary" const val cAccent = "colorAccent" diff --git a/app/src/main/java/io/legado/app/data/entities/Book.kt b/app/src/main/java/io/legado/app/data/entities/Book.kt index 5093c05c1..2ee782122 100644 --- a/app/src/main/java/io/legado/app/data/entities/Book.kt +++ b/app/src/main/java/io/legado/app/data/entities/Book.kt @@ -107,6 +107,8 @@ data class Book( fun getUnreadChapterNum() = max(totalChapterNum - durChapterIndex - 1, 0) + fun getDisplayTag() = if (customTag.isNullOrBlank()) kind else customTag + fun getDisplayCover() = if (customCoverUrl.isNullOrEmpty()) coverUrl else customCoverUrl fun getDisplayIntro() = if (customIntro.isNullOrEmpty()) intro else customIntro diff --git a/app/src/main/res/values-zh-rHK/strings.xml b/app/src/main/res/values-zh-rHK/strings.xml index 29e200c8c..cab096ed7 100644 --- a/app/src/main/res/values-zh-rHK/strings.xml +++ b/app/src/main/res/values-zh-rHK/strings.xml @@ -820,5 +820,7 @@ 正文源码 列表源码 此url已订阅 + 高刷 + 使用屏幕最高刷新率 diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index c04585a7d..a29b45531 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -822,5 +822,7 @@ 正文原始碼 列表原始碼 此url已訂閱 + 高刷 + 使用屏幕最高刷新率 diff --git a/app/src/main/res/values-zh/strings.xml b/app/src/main/res/values-zh/strings.xml index 05aa55b5a..240704cac 100644 --- a/app/src/main/res/values-zh/strings.xml +++ b/app/src/main/res/values-zh/strings.xml @@ -824,5 +824,7 @@ 正文源码 列表源码 此url已订阅 + 高刷 + 使用屏幕最高刷新率 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 04b53023e..501d88d96 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -827,5 +827,7 @@ 正文源码 列表源码 此url已订阅 + 高刷 + 使用屏幕最高刷新率 diff --git a/app/src/main/res/xml/pref_config_other.xml b/app/src/main/res/xml/pref_config_other.xml index c15aee51e..66a9cc4fa 100644 --- a/app/src/main/res/xml/pref_config_other.xml +++ b/app/src/main/res/xml/pref_config_other.xml @@ -55,6 +55,12 @@ android:key="userAgent" android:title="UserAgent" /> + + Date: Sun, 25 Apr 2021 19:24:47 +0800 Subject: [PATCH 03/48] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E9=AB=98=E5=88=B7?= =?UTF-8?q?=E8=AE=BE=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/assets/updateLog.md | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/assets/updateLog.md b/app/src/main/assets/updateLog.md index 8b4c3a008..f4478307a 100644 --- a/app/src/main/assets/updateLog.md +++ b/app/src/main/assets/updateLog.md @@ -5,6 +5,7 @@ **2021/04/18** * epub插图,epublib优化 by ag2s20150909 +* 添加高刷设置 **2021/04/16** * 去掉google统计,解决华为手机使用崩溃的bug From 7e92c0b2eef7049b0393b473d52d03ee94a11699 Mon Sep 17 00:00:00 2001 From: gedoor Date: Sun, 25 Apr 2021 19:40:59 +0800 Subject: [PATCH 04/48] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E9=AB=98=E5=88=B7?= =?UTF-8?q?=E8=AE=BE=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/assets/updateLog.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/assets/updateLog.md b/app/src/main/assets/updateLog.md index f4478307a..2c01253f8 100644 --- a/app/src/main/assets/updateLog.md +++ b/app/src/main/assets/updateLog.md @@ -4,7 +4,7 @@ * 旧版数据导入教程:先在旧版阅读(2.x)中进行备份,然后在新版阅读(3.x)【我的】->【备份与恢复】,选择【导入旧版本数据】。 **2021/04/18** -* epub插图,epublib优化 by ag2s20150909 +* epub插图,epublib优化,图片解码优化,epub读取导出优化。by ag2s20150909 * 添加高刷设置 **2021/04/16** From 243027f4d53cef879552d1c0fab147c41a2b9356 Mon Sep 17 00:00:00 2001 From: gedoor Date: Tue, 27 Apr 2021 09:58:11 +0800 Subject: [PATCH 05/48] =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../legado/app/model/webBook/BookContent.kt | 39 +++++++++---------- 1 file changed, 19 insertions(+), 20 deletions(-) diff --git a/app/src/main/java/io/legado/app/model/webBook/BookContent.kt b/app/src/main/java/io/legado/app/model/webBook/BookContent.kt index 8eef8d50b..1e55b9e8a 100644 --- a/app/src/main/java/io/legado/app/model/webBook/BookContent.kt +++ b/app/src/main/java/io/legado/app/model/webBook/BookContent.kt @@ -13,6 +13,8 @@ import io.legado.app.model.analyzeRule.AnalyzeUrl import io.legado.app.utils.HtmlFormatter import io.legado.app.utils.NetworkUtils import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers.IO +import kotlinx.coroutines.async import kotlinx.coroutines.withContext import splitties.init.appCtx @@ -75,29 +77,26 @@ object BookContent { } Debug.log(bookSource.bookSourceUrl, "◇本章总页数:${nextUrlList.size}") } else if (contentData.nextUrl.size > 1) { - val contentDataList = arrayListOf>() - for (item in contentData.nextUrl) { - if (!nextUrlList.contains(item)) - contentDataList.add(ContentData(nextUrl = item)) - } - for (item in contentDataList) { - withContext(scope.coroutineContext) { - val res = AnalyzeUrl( - ruleUrl = item.nextUrl, - book = book, - headerMapF = bookSource.getHeaderMap() - ).getStrResponse(bookSource.bookSourceUrl) - res.body?.let { nextBody -> - contentData = analyzeContent( - book, item.nextUrl, res.url, nextBody, contentRule, - bookChapter, bookSource, mNextChapterUrl, false + Debug.log(bookSource.bookSourceUrl, "◇并发解析目录,总页数:${contentData.nextUrl.size}") + withContext(IO) { + val asyncArray = Array(contentData.nextUrl.size) { + async(IO) { + val urlStr = contentData.nextUrl[it] + val analyzeUrl = AnalyzeUrl( + ruleUrl = urlStr, + book = book, + headerMapF = bookSource.getHeaderMap() ) - item.content = contentData.content + val res = analyzeUrl.getStrResponse(bookSource.bookSourceUrl) + analyzeContent( + book, urlStr, res.url, res.body!!, contentRule, + bookChapter, bookSource, mNextChapterUrl, false + ).content } } - } - for (item in contentDataList) { - content.append(item.content).append("\n") + asyncArray.forEach { coroutine -> + content.append(coroutine.await()).append("\n") + } } } content.deleteCharAt(content.length - 1) From 5fbf734f8959f9faf904eb92ba80058f17c312b1 Mon Sep 17 00:00:00 2001 From: gedoor Date: Tue, 27 Apr 2021 22:41:55 +0800 Subject: [PATCH 06/48] =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/assets/defaultData/readConfig.json | 50 +++++++++++++++++++ .../app/ui/rss/article/RssArticlesFragment.kt | 34 ++++++++----- .../ui/rss/favorites/RssFavoritesActivity.kt | 2 +- .../res/layout/activity_rss_favorites.xml | 15 ++++-- .../main/res/layout/fragment_rss_articles.xml | 15 +++--- 5 files changed, 88 insertions(+), 28 deletions(-) diff --git a/app/src/main/assets/defaultData/readConfig.json b/app/src/main/assets/defaultData/readConfig.json index 968141a0c..4b8c27ef4 100644 --- a/app/src/main/assets/defaultData/readConfig.json +++ b/app/src/main/assets/defaultData/readConfig.json @@ -1,4 +1,54 @@ [ + { + "bgStr": "#ffc0edc6", + "bgStrEInk": "#FFFFFF", + "bgStrNight": "#000000", + "bgType": 0, + "bgTypeEInk": 0, + "bgTypeNight": 0, + "darkStatusIcon": true, + "darkStatusIconEInk": true, + "darkStatusIconNight": false, + "footerMode": 0, + "footerPaddingBottom": 10, + "footerPaddingLeft": 13, + "footerPaddingRight": 17, + "footerPaddingTop": 0, + "headerMode": 0, + "headerPaddingBottom": 0, + "headerPaddingLeft": 19, + "headerPaddingRight": 16, + "headerPaddingTop": 10, + "letterSpacing": -0.14, + "lineSpacingExtra": 7, + "name": "微信读书", + "paddingBottom": 4, + "paddingLeft": 22, + "paddingRight": 22, + "paddingTop": 5, + "pageAnim": 3, + "pageAnimEInk": 3, + "paragraphIndent": "  ", + "paragraphSpacing": 6, + "showFooterLine": true, + "showHeaderLine": true, + "textBold": 0, + "textColor": "#ff0b0b0b", + "textColorEInk": "#000000", + "textColorNight": "#ADADAD", + "textSize": 24, + "tipColor": -10461088, + "tipFooterLeft": 7, + "tipFooterMiddle": 0, + "tipFooterRight": 6, + "tipHeaderLeft": 1, + "tipHeaderMiddle": 0, + "tipHeaderRight": 2, + "titleBottomSpacing": 0, + "titleMode": 0, + "titleSize": 4, + "titleTopSpacing": 0 + }, { "bgStr": "#FFFFFF", "bgStrNight": "#000000", diff --git a/app/src/main/java/io/legado/app/ui/rss/article/RssArticlesFragment.kt b/app/src/main/java/io/legado/app/ui/rss/article/RssArticlesFragment.kt index 221b296ae..8bdd5faa9 100644 --- a/app/src/main/java/io/legado/app/ui/rss/article/RssArticlesFragment.kt +++ b/app/src/main/java/io/legado/app/ui/rss/article/RssArticlesFragment.kt @@ -16,6 +16,7 @@ import io.legado.app.data.entities.RssArticle import io.legado.app.databinding.FragmentRssArticlesBinding import io.legado.app.databinding.ViewLoadMoreBinding import io.legado.app.lib.theme.ATH +import io.legado.app.lib.theme.accentColor import io.legado.app.ui.rss.read.ReadRssActivity import io.legado.app.ui.widget.recycler.LoadMoreView import io.legado.app.ui.widget.recycler.VerticalDivider @@ -50,18 +51,18 @@ class RssArticlesFragment : VMBaseFragment(R.layout.fragme override fun onFragmentCreated(view: View, savedInstanceState: Bundle?) { viewModel.init(arguments) initView() - binding.refreshRecyclerView.startLoading() initView() initData() } private fun initView() = with(binding) { - ATH.applyEdgeEffectColor(refreshRecyclerView.recyclerView) - refreshRecyclerView.recyclerView.layoutManager = if (activityViewModel.isGridLayout) { - refreshRecyclerView.recyclerView.setPadding(8, 0, 8, 0) + refreshLayout.setColorSchemeColors(accentColor) + ATH.applyEdgeEffectColor(recyclerView) + recyclerView.layoutManager = if (activityViewModel.isGridLayout) { + recyclerView.setPadding(8, 0, 8, 0) GridLayoutManager(requireContext(), 2) } else { - refreshRecyclerView.recyclerView.addItemDecoration(VerticalDivider(requireContext())) + recyclerView.addItemDecoration(VerticalDivider(requireContext())) LinearLayoutManager(requireContext()) } @@ -70,18 +71,15 @@ class RssArticlesFragment : VMBaseFragment(R.layout.fragme 2 -> RssArticlesAdapter2(requireContext(), this@RssArticlesFragment) else -> RssArticlesAdapter(requireContext(), this@RssArticlesFragment) } - refreshRecyclerView.recyclerView.adapter = adapter + recyclerView.adapter = adapter loadMoreView = LoadMoreView(requireContext()) adapter.addFooterView { ViewLoadMoreBinding.bind(loadMoreView) } - refreshRecyclerView.onRefreshStart = { - activityViewModel.rssSource?.let { - viewModel.loadContent(it) - } + refreshLayout.setOnRefreshListener { + loadArticles() } - refreshRecyclerView.recyclerView.addOnScrollListener(object : - RecyclerView.OnScrollListener() { + recyclerView.addOnScrollListener(object : RecyclerView.OnScrollListener() { override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) { super.onScrolled(recyclerView, dx, dy) if (!recyclerView.canScrollVertically(1)) { @@ -89,6 +87,10 @@ class RssArticlesFragment : VMBaseFragment(R.layout.fragme } } }) + refreshLayout.post { + refreshLayout.isRefreshing = true + loadArticles() + } } private fun initData() { @@ -101,6 +103,12 @@ class RssArticlesFragment : VMBaseFragment(R.layout.fragme } } + private fun loadArticles() { + activityViewModel.rssSource?.let { + viewModel.loadContent(it) + } + } + private fun scrollToBottom() { if (viewModel.isLoading) return if (loadMoreView.hasMore && adapter.getActualItemCount() > 0) { @@ -113,7 +121,7 @@ class RssArticlesFragment : VMBaseFragment(R.layout.fragme override fun observeLiveBus() { viewModel.loadFinally.observe(viewLifecycleOwner) { - binding.refreshRecyclerView.stopLoading() + binding.refreshLayout.isRefreshing = false if (it) { loadMoreView.startLoad() } else { diff --git a/app/src/main/java/io/legado/app/ui/rss/favorites/RssFavoritesActivity.kt b/app/src/main/java/io/legado/app/ui/rss/favorites/RssFavoritesActivity.kt index 403a06d2e..e317ae734 100644 --- a/app/src/main/java/io/legado/app/ui/rss/favorites/RssFavoritesActivity.kt +++ b/app/src/main/java/io/legado/app/ui/rss/favorites/RssFavoritesActivity.kt @@ -28,7 +28,7 @@ class RssFavoritesActivity : BaseActivity(), } private fun initView() { - binding.refreshRecyclerView.recyclerView.let { + binding.recyclerView.let { it.layoutManager = LinearLayoutManager(this) it.addItemDecoration(VerticalDivider(this)) adapter = RssFavoritesAdapter(this, this) diff --git a/app/src/main/res/layout/activity_rss_favorites.xml b/app/src/main/res/layout/activity_rss_favorites.xml index 7740c1981..098af211a 100644 --- a/app/src/main/res/layout/activity_rss_favorites.xml +++ b/app/src/main/res/layout/activity_rss_favorites.xml @@ -1,7 +1,6 @@ @@ -13,13 +12,19 @@ app:title="@string/favorites" app:layout_constraintTop_toTopOf="parent" /> - + app:layout_constraintVertical_bias="0.0"> + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_rss_articles.xml b/app/src/main/res/layout/fragment_rss_articles.xml index 5ca0c9574..cc0266316 100644 --- a/app/src/main/res/layout/fragment_rss_articles.xml +++ b/app/src/main/res/layout/fragment_rss_articles.xml @@ -1,15 +1,12 @@ - + android:layout_height="match_parent"> - - \ No newline at end of file + \ No newline at end of file From 66b1f5e08a47bd4f11361ab3d7de50a524397700 Mon Sep 17 00:00:00 2001 From: gedoor Date: Wed, 28 Apr 2021 10:25:24 +0800 Subject: [PATCH 07/48] =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ui/book/read/config/BgTextConfigDialog.kt | 25 ++++++++++++++----- .../main/res/layout/dialog_read_bg_text.xml | 12 +++++++++ 2 files changed, 31 insertions(+), 6 deletions(-) diff --git a/app/src/main/java/io/legado/app/ui/book/read/config/BgTextConfigDialog.kt b/app/src/main/java/io/legado/app/ui/book/read/config/BgTextConfigDialog.kt index 1a89cd4b1..9bd8049ff 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/config/BgTextConfigDialog.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/config/BgTextConfigDialog.kt @@ -15,8 +15,10 @@ import io.legado.app.constant.EventBus import io.legado.app.databinding.DialogEditTextBinding import io.legado.app.databinding.DialogReadBgTextBinding import io.legado.app.databinding.ItemBgImageBinding +import io.legado.app.help.DefaultData import io.legado.app.help.ReadBookConfig import io.legado.app.lib.dialogs.alert +import io.legado.app.lib.dialogs.selector import io.legado.app.lib.permission.Permissions import io.legado.app.lib.permission.PermissionsCompat import io.legado.app.lib.theme.bottomBackground @@ -107,12 +109,6 @@ class BgTextConfigDialog : BaseDialogFragment() { binding.ivExport.setColorFilter(primaryTextColor) binding.ivDelete.setColorFilter(primaryTextColor) binding.tvBgImage.setTextColor(primaryTextColor) - } - - @SuppressLint("InflateParams") - private fun initData() = with(ReadBookConfig.durConfig) { - binding.tvName.text = name.ifBlank { "文字" } - binding.swDarkStatusIcon.isChecked = curStatusIconDark() adapter = BgAdapter(requireContext(), secondaryTextColor) binding.recyclerView.adapter = adapter adapter.addHeaderView { @@ -131,6 +127,12 @@ class BgTextConfigDialog : BaseDialogFragment() { } } + @SuppressLint("InflateParams") + private fun initData() = with(ReadBookConfig.durConfig) { + binding.tvName.text = name.ifBlank { "文字" } + binding.swDarkStatusIcon.isChecked = curStatusIconDark() + } + @SuppressLint("InflateParams") private fun initEvent() = with(ReadBookConfig.durConfig) { binding.ivEdit.setOnClickListener { @@ -148,6 +150,17 @@ class BgTextConfigDialog : BaseDialogFragment() { cancelButton() }.show() } + binding.tvRestore.setOnClickListener { + val defaultConfigs = DefaultData.readConfigs + val layoutNames = defaultConfigs.map { it.name } + selector("选择预设布局", layoutNames) { _, i -> + if (i >= 0) { + ReadBookConfig.durConfig = defaultConfigs[i] + initData() + postEvent(EventBus.UP_CONFIG, true) + } + } + } binding.swDarkStatusIcon.setOnCheckedChangeListener { _, isChecked -> setCurStatusIconDark(isChecked) (activity as? ReadBookActivity)?.upSystemUiVisibility() diff --git a/app/src/main/res/layout/dialog_read_bg_text.xml b/app/src/main/res/layout/dialog_read_bg_text.xml index 553f893b4..310c62bc8 100644 --- a/app/src/main/res/layout/dialog_read_bg_text.xml +++ b/app/src/main/res/layout/dialog_read_bg_text.xml @@ -39,6 +39,18 @@ app:tint="@color/secondaryText" android:contentDescription="@string/edit" /> + + + + Date: Wed, 28 Apr 2021 10:29:57 +0800 Subject: [PATCH 08/48] =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/build.gradle | 1 - 1 file changed, 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index 6d576b873..3d73281ce 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -178,7 +178,6 @@ dependencies { implementation 'com.github.gedoor:rhino-android:1.5' //网络 - //noinspection GradleDependency implementation 'com.squareup.okhttp3:okhttp:4.9.1' implementation 'com.ljx.rxhttp:rxhttp:2.5.7' kapt 'com.ljx.rxhttp:rxhttp-compiler:2.5.7' From 0cab67420ffbdf257d8dd77b10c27b443c7616c2 Mon Sep 17 00:00:00 2001 From: gedoor Date: Wed, 28 Apr 2021 10:36:26 +0800 Subject: [PATCH 09/48] =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/assets/defaultData/readConfig.json | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/app/src/main/assets/defaultData/readConfig.json b/app/src/main/assets/defaultData/readConfig.json index 4b8c27ef4..cd62a05be 100644 --- a/app/src/main/assets/defaultData/readConfig.json +++ b/app/src/main/assets/defaultData/readConfig.json @@ -19,8 +19,8 @@ "headerPaddingLeft": 19, "headerPaddingRight": 16, "headerPaddingTop": 10, - "letterSpacing": -0.14, - "lineSpacingExtra": 7, + "letterSpacing": 0, + "lineSpacingExtra": 10, "name": "微信读书", "paddingBottom": 4, "paddingLeft": 22, @@ -50,6 +50,7 @@ "titleTopSpacing": 0 }, { + "name": "预设1", "bgStr": "#FFFFFF", "bgStrNight": "#000000", "textColor": "#000000", @@ -60,6 +61,7 @@ "darkStatusIconNight": false }, { + "name": "预设2", "bgStr": "#DDC090", "bgStrNight": "#3C3F43", "textColor": "#3E3422", @@ -70,6 +72,7 @@ "darkStatusIconNight": false }, { + "name": "预设3", "bgStr": "#C2D8AA", "bgStrNight": "#3C3F43", "textColor": "#596C44", @@ -80,6 +83,7 @@ "darkStatusIconNight": false }, { + "name": "预设4", "bgStr": "#DBB8E2", "bgStrNight": "#3C3F43", "textColor": "#68516C", @@ -90,6 +94,7 @@ "darkStatusIconNight": false }, { + "name": "预设5", "bgStr": "#ABCEE0", "bgStrNight": "#3C3F43", "textColor": "#3D4C54", From 09bd44345d7b425f054d1db36ad8314b24d78452 Mon Sep 17 00:00:00 2001 From: gedoor Date: Wed, 28 Apr 2021 10:45:20 +0800 Subject: [PATCH 10/48] =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ui/book/read/config/BgTextConfigDialog.kt | 20 +++++++++++-------- .../main/res/layout/dialog_read_bg_text.xml | 1 + 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/app/src/main/java/io/legado/app/ui/book/read/config/BgTextConfigDialog.kt b/app/src/main/java/io/legado/app/ui/book/read/config/BgTextConfigDialog.kt index 9bd8049ff..4a7b4cf96 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/config/BgTextConfigDialog.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/config/BgTextConfigDialog.kt @@ -98,19 +98,23 @@ class BgTextConfigDialog : BaseDialogFragment() { (activity as ReadBookActivity).bottomDialog-- } - private fun initView() { + private fun initView() = with(binding) { val bg = requireContext().bottomBackground val isLight = ColorUtils.isColorLight(bg) primaryTextColor = requireContext().getPrimaryTextColor(isLight) secondaryTextColor = requireContext().getSecondaryTextColor(isLight) - binding.rootView.setBackgroundColor(bg) - binding.swDarkStatusIcon.setTextColor(primaryTextColor) - binding.ivImport.setColorFilter(primaryTextColor) - binding.ivExport.setColorFilter(primaryTextColor) - binding.ivDelete.setColorFilter(primaryTextColor) - binding.tvBgImage.setTextColor(primaryTextColor) + rootView.setBackgroundColor(bg) + tvNameTitle.setTextColor(primaryTextColor) + tvName.setTextColor(secondaryTextColor) + ivEdit.setColorFilter(secondaryTextColor) + tvRestore.setTextColor(primaryTextColor) + swDarkStatusIcon.setTextColor(primaryTextColor) + ivImport.setColorFilter(primaryTextColor) + ivExport.setColorFilter(primaryTextColor) + ivDelete.setColorFilter(primaryTextColor) + tvBgImage.setTextColor(primaryTextColor) adapter = BgAdapter(requireContext(), secondaryTextColor) - binding.recyclerView.adapter = adapter + recyclerView.adapter = adapter adapter.addHeaderView { ItemBgImageBinding.inflate(layoutInflater, it, false).apply { tvName.setTextColor(secondaryTextColor) diff --git a/app/src/main/res/layout/dialog_read_bg_text.xml b/app/src/main/res/layout/dialog_read_bg_text.xml index 310c62bc8..175bb68c0 100644 --- a/app/src/main/res/layout/dialog_read_bg_text.xml +++ b/app/src/main/res/layout/dialog_read_bg_text.xml @@ -16,6 +16,7 @@ android:gravity="center_vertical"> Date: Wed, 28 Apr 2021 10:54:14 +0800 Subject: [PATCH 11/48] =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/assets/updateLog.md | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/assets/updateLog.md b/app/src/main/assets/updateLog.md index 2c01253f8..a48628283 100644 --- a/app/src/main/assets/updateLog.md +++ b/app/src/main/assets/updateLog.md @@ -10,6 +10,7 @@ **2021/04/16** * 去掉google统计,解决华为手机使用崩溃的bug * 添加规则订阅时判断重复提醒 +* 添加恢复预设布局的功能 **2021/04/13** * 修复导入布局bug From fec409c45daed67c94132092ce04bc9577838b6b Mon Sep 17 00:00:00 2001 From: gedoor Date: Wed, 28 Apr 2021 10:55:10 +0800 Subject: [PATCH 12/48] =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/assets/updateLog.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/assets/updateLog.md b/app/src/main/assets/updateLog.md index a48628283..7138cbd30 100644 --- a/app/src/main/assets/updateLog.md +++ b/app/src/main/assets/updateLog.md @@ -10,7 +10,7 @@ **2021/04/16** * 去掉google统计,解决华为手机使用崩溃的bug * 添加规则订阅时判断重复提醒 -* 添加恢复预设布局的功能 +* 添加恢复预设布局的功能, 添加一个微信读书布局作为预设布局 **2021/04/13** * 修复导入布局bug From 68239a4f7f13d5440d30393ec21f6da38e3ba6e6 Mon Sep 17 00:00:00 2001 From: gedoor Date: Wed, 28 Apr 2021 11:04:41 +0800 Subject: [PATCH 13/48] =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/java/io/legado/app/ui/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/io/legado/app/ui/README.md b/app/src/main/java/io/legado/app/ui/README.md index bc6549bec..05d4be931 100644 --- a/app/src/main/java/io/legado/app/ui/README.md +++ b/app/src/main/java/io/legado/app/ui/README.md @@ -10,7 +10,7 @@ * book\source 书源界面 * book\changeCover 封面换源界面 * book\changeSource 换源界面 -* book\chapterList 目录界面 +* book\toc 目录界面 * book\download 下载界面 * book\explore 发现界面 * book\local 书籍导入界面 From c5d0f454566a9eeb12b162fe5e46ebd40fd74e91 Mon Sep 17 00:00:00 2001 From: gedoor Date: Wed, 28 Apr 2021 15:56:05 +0800 Subject: [PATCH 14/48] =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index 3d73281ce..267c0eb8b 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -190,7 +190,7 @@ dependencies { implementation 'org.nanohttpd:nanohttpd-websocket:2.3.1' //二维码 - implementation 'com.king.zxing:zxing-lite:2.0.2' + implementation 'com.king.zxing:zxing-lite:2.0.3' //颜色选择 implementation 'com.jaredrummler:colorpicker:1.1.0' From d5348dd10c40534a53a3f94e7b859347388a0f21 Mon Sep 17 00:00:00 2001 From: gedoor Date: Wed, 28 Apr 2021 16:03:47 +0800 Subject: [PATCH 15/48] =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ui/widget/recycler/SwipeRefreshLayout.kt | 109 ++++++++++++++++++ 1 file changed, 109 insertions(+) create mode 100644 app/src/main/java/io/legado/app/ui/widget/recycler/SwipeRefreshLayout.kt diff --git a/app/src/main/java/io/legado/app/ui/widget/recycler/SwipeRefreshLayout.kt b/app/src/main/java/io/legado/app/ui/widget/recycler/SwipeRefreshLayout.kt new file mode 100644 index 000000000..9a0ba9f44 --- /dev/null +++ b/app/src/main/java/io/legado/app/ui/widget/recycler/SwipeRefreshLayout.kt @@ -0,0 +1,109 @@ +package io.legado.app.ui.widget.recycler + +import android.content.Context +import android.util.AttributeSet +import android.view.View +import android.view.ViewGroup +import androidx.core.view.* + +class SwipeRefreshLayout @JvmOverloads constructor( + context: Context, + attrs: AttributeSet? = null +) : ViewGroup(context, attrs), NestedScrollingParent3, + NestedScrollingParent2, NestedScrollingChild3, NestedScrollingChild2, NestedScrollingParent, + NestedScrollingChild { + + init { + + } + + override fun onLayout(changed: Boolean, l: Int, t: Int, r: Int, b: Int) { + TODO("Not yet implemented") + } + + override fun startNestedScroll(axes: Int, type: Int): Boolean { + TODO("Not yet implemented") + } + + override fun stopNestedScroll(type: Int) { + TODO("Not yet implemented") + } + + override fun hasNestedScrollingParent(type: Int): Boolean { + TODO("Not yet implemented") + } + + override fun dispatchNestedScroll( + dxConsumed: Int, + dyConsumed: Int, + dxUnconsumed: Int, + dyUnconsumed: Int, + offsetInWindow: IntArray?, + type: Int + ): Boolean { + TODO("Not yet implemented") + } + + override fun dispatchNestedPreScroll( + dx: Int, + dy: Int, + consumed: IntArray?, + offsetInWindow: IntArray?, + type: Int + ): Boolean { + TODO("Not yet implemented") + } + + override fun dispatchNestedScroll( + dxConsumed: Int, + dyConsumed: Int, + dxUnconsumed: Int, + dyUnconsumed: Int, + offsetInWindow: IntArray?, + type: Int, + consumed: IntArray + ) { + TODO("Not yet implemented") + } + + override fun onStartNestedScroll(child: View, target: View, axes: Int, type: Int): Boolean { + TODO("Not yet implemented") + } + + override fun onNestedScrollAccepted(child: View, target: View, axes: Int, type: Int) { + TODO("Not yet implemented") + } + + override fun onStopNestedScroll(target: View, type: Int) { + TODO("Not yet implemented") + } + + override fun onNestedScroll( + target: View, + dxConsumed: Int, + dyConsumed: Int, + dxUnconsumed: Int, + dyUnconsumed: Int, + type: Int + ) { + TODO("Not yet implemented") + } + + override fun onNestedPreScroll(target: View, dx: Int, dy: Int, consumed: IntArray, type: Int) { + TODO("Not yet implemented") + } + + override fun onNestedScroll( + target: View, + dxConsumed: Int, + dyConsumed: Int, + dxUnconsumed: Int, + dyUnconsumed: Int, + type: Int, + consumed: IntArray + ) { + TODO("Not yet implemented") + } + + +} \ No newline at end of file From d6564f30ed22b2cff1ec6a39c989901e1b175ef6 Mon Sep 17 00:00:00 2001 From: gedoor Date: Wed, 28 Apr 2021 17:44:52 +0800 Subject: [PATCH 16/48] =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/java/io/legado/app/data/AppDatabase.kt | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/app/src/main/java/io/legado/app/data/AppDatabase.kt b/app/src/main/java/io/legado/app/data/AppDatabase.kt index 70c05de42..8add07077 100644 --- a/app/src/main/java/io/legado/app/data/AppDatabase.kt +++ b/app/src/main/java/io/legado/app/data/AppDatabase.kt @@ -10,6 +10,7 @@ import io.legado.app.constant.AppConst import io.legado.app.constant.AppConst.androidId import io.legado.app.data.dao.* import io.legado.app.data.entities.* +import io.legado.app.help.AppConfig import splitties.init.appCtx import java.util.* @@ -88,6 +89,13 @@ abstract class AppDatabase : RoomDatabase() { """insert into book_groups(groupId, groupName, 'order', show) select ${AppConst.bookGroupNoneId}, '未分组', -7, 1 where not exists (select * from book_groups where groupId = ${AppConst.bookGroupNoneId})""" ) + if (AppConfig.isGooglePlay) { + db.execSQL( + """ + delete from rssSources where sourceUrl = 'https://github.com/gedoor/legado/releases' + """ + ) + } } } From cbc30f1584138e4cdb0a0f7a9629cd2ae8725440 Mon Sep 17 00:00:00 2001 From: gedoor Date: Thu, 29 Apr 2021 15:54:22 +0800 Subject: [PATCH 17/48] =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/assets/updateLog.md | 4 +- .../ui/widget/recycler/RefreshRecyclerView.kt | 92 --------------- .../ui/widget/recycler/SwipeRefreshLayout.kt | 109 ------------------ 3 files changed, 3 insertions(+), 202 deletions(-) delete mode 100644 app/src/main/java/io/legado/app/ui/widget/recycler/RefreshRecyclerView.kt delete mode 100644 app/src/main/java/io/legado/app/ui/widget/recycler/SwipeRefreshLayout.kt diff --git a/app/src/main/assets/updateLog.md b/app/src/main/assets/updateLog.md index 7138cbd30..66adaa501 100644 --- a/app/src/main/assets/updateLog.md +++ b/app/src/main/assets/updateLog.md @@ -3,9 +3,11 @@ * 关注合作公众号 **[小说拾遗]** 获取好看的小说。 * 旧版数据导入教程:先在旧版阅读(2.x)中进行备份,然后在新版阅读(3.x)【我的】->【备份与恢复】,选择【导入旧版本数据】。 -**2021/04/18** +**2021/04/29** * epub插图,epublib优化,图片解码优化,epub读取导出优化。by ag2s20150909 * 添加高刷设置 +* 其它一些优化 +* pro版本被play商店下架了,先把pro设置图片背景的功能开放到所有版本,使用pro版本的可以使用备份恢复功能切换最新版本 **2021/04/16** * 去掉google统计,解决华为手机使用崩溃的bug diff --git a/app/src/main/java/io/legado/app/ui/widget/recycler/RefreshRecyclerView.kt b/app/src/main/java/io/legado/app/ui/widget/recycler/RefreshRecyclerView.kt deleted file mode 100644 index 81f3db242..000000000 --- a/app/src/main/java/io/legado/app/ui/widget/recycler/RefreshRecyclerView.kt +++ /dev/null @@ -1,92 +0,0 @@ -package io.legado.app.ui.widget.recycler - -import android.annotation.SuppressLint -import android.content.Context -import android.util.AttributeSet -import android.view.LayoutInflater -import android.view.MotionEvent -import android.view.View -import android.widget.LinearLayout -import androidx.recyclerview.widget.LinearLayoutManager -import io.legado.app.R -import io.legado.app.databinding.ViewRefreshRecyclerBinding -import io.legado.app.lib.theme.ATH - - -@SuppressLint("ClickableViewAccessibility") -class RefreshRecyclerView(context: Context?, attrs: AttributeSet?) : LinearLayout(context, attrs) { - private var binding: ViewRefreshRecyclerBinding - private var durTouchX = -1000000f - private var durTouchY = -1000000f - - var onRefreshStart: (() -> Unit)? = null - - init { - orientation = VERTICAL - val view = LayoutInflater.from(context).inflate(R.layout.view_refresh_recycler, this, true) - binding = ViewRefreshRecyclerBinding.bind(view) - ATH.applyEdgeEffectColor(binding.recyclerView) - binding.recyclerView.setOnTouchListener(object : OnTouchListener { - @SuppressLint("ClickableViewAccessibility") - override fun onTouch(v: View?, event: MotionEvent?): Boolean { - when (event?.action) { - MotionEvent.ACTION_DOWN -> { - durTouchX = event.x - durTouchY = event.y - } - MotionEvent.ACTION_MOVE -> { - if (durTouchX == -1000000f) { - durTouchX = event.x - } - if (durTouchY == -1000000f) - durTouchY = event.y - - val dY = event.y - durTouchY //>0下拉 - durTouchY = event.y - if (!binding.refreshProgressBar.isAutoLoading && - binding.refreshProgressBar.getSecondDurProgress() == binding.refreshProgressBar.secondFinalProgress - ) { - binding.recyclerView.adapter?.let { - if (it.itemCount > 0) { - if (0 == (binding.recyclerView.layoutManager as LinearLayoutManager).findFirstCompletelyVisibleItemPosition()) { - binding.refreshProgressBar.setSecondDurProgress((binding.refreshProgressBar.getSecondDurProgress() + dY / 2).toInt()) - } - } else { - binding.refreshProgressBar.setSecondDurProgress((binding.refreshProgressBar.getSecondDurProgress() + dY / 2).toInt()) - } - } - return binding.refreshProgressBar.getSecondDurProgress() > 0 - } - } - MotionEvent.ACTION_UP -> { - if (!binding.refreshProgressBar.isAutoLoading && - binding.refreshProgressBar.secondMaxProgress > 0 && - binding.refreshProgressBar.getSecondDurProgress() > 0 - ) { - if (binding.refreshProgressBar.getSecondDurProgress() >= binding.refreshProgressBar.secondMaxProgress) { - binding.refreshProgressBar.isAutoLoading = true - onRefreshStart?.invoke() - } else { - binding.refreshProgressBar.setSecondDurProgressWithAnim(0) - } - } - durTouchX = -1000000f - durTouchY = -1000000f - } - } - return false - } - }) - } - - val recyclerView get() = binding.recyclerView - - fun startLoading() { - binding.refreshProgressBar.isAutoLoading = true - onRefreshStart?.invoke() - } - - fun stopLoading() { - binding.refreshProgressBar.isAutoLoading = false - } -} \ No newline at end of file diff --git a/app/src/main/java/io/legado/app/ui/widget/recycler/SwipeRefreshLayout.kt b/app/src/main/java/io/legado/app/ui/widget/recycler/SwipeRefreshLayout.kt deleted file mode 100644 index 9a0ba9f44..000000000 --- a/app/src/main/java/io/legado/app/ui/widget/recycler/SwipeRefreshLayout.kt +++ /dev/null @@ -1,109 +0,0 @@ -package io.legado.app.ui.widget.recycler - -import android.content.Context -import android.util.AttributeSet -import android.view.View -import android.view.ViewGroup -import androidx.core.view.* - -class SwipeRefreshLayout @JvmOverloads constructor( - context: Context, - attrs: AttributeSet? = null -) : ViewGroup(context, attrs), NestedScrollingParent3, - NestedScrollingParent2, NestedScrollingChild3, NestedScrollingChild2, NestedScrollingParent, - NestedScrollingChild { - - init { - - } - - override fun onLayout(changed: Boolean, l: Int, t: Int, r: Int, b: Int) { - TODO("Not yet implemented") - } - - override fun startNestedScroll(axes: Int, type: Int): Boolean { - TODO("Not yet implemented") - } - - override fun stopNestedScroll(type: Int) { - TODO("Not yet implemented") - } - - override fun hasNestedScrollingParent(type: Int): Boolean { - TODO("Not yet implemented") - } - - override fun dispatchNestedScroll( - dxConsumed: Int, - dyConsumed: Int, - dxUnconsumed: Int, - dyUnconsumed: Int, - offsetInWindow: IntArray?, - type: Int - ): Boolean { - TODO("Not yet implemented") - } - - override fun dispatchNestedPreScroll( - dx: Int, - dy: Int, - consumed: IntArray?, - offsetInWindow: IntArray?, - type: Int - ): Boolean { - TODO("Not yet implemented") - } - - override fun dispatchNestedScroll( - dxConsumed: Int, - dyConsumed: Int, - dxUnconsumed: Int, - dyUnconsumed: Int, - offsetInWindow: IntArray?, - type: Int, - consumed: IntArray - ) { - TODO("Not yet implemented") - } - - override fun onStartNestedScroll(child: View, target: View, axes: Int, type: Int): Boolean { - TODO("Not yet implemented") - } - - override fun onNestedScrollAccepted(child: View, target: View, axes: Int, type: Int) { - TODO("Not yet implemented") - } - - override fun onStopNestedScroll(target: View, type: Int) { - TODO("Not yet implemented") - } - - override fun onNestedScroll( - target: View, - dxConsumed: Int, - dyConsumed: Int, - dxUnconsumed: Int, - dyUnconsumed: Int, - type: Int - ) { - TODO("Not yet implemented") - } - - override fun onNestedPreScroll(target: View, dx: Int, dy: Int, consumed: IntArray, type: Int) { - TODO("Not yet implemented") - } - - override fun onNestedScroll( - target: View, - dxConsumed: Int, - dyConsumed: Int, - dxUnconsumed: Int, - dyUnconsumed: Int, - type: Int, - consumed: IntArray - ) { - TODO("Not yet implemented") - } - - -} \ No newline at end of file From e4286192a691292ad6d735371295058cdc8c3be7 Mon Sep 17 00:00:00 2001 From: gedoor Date: Thu, 29 Apr 2021 15:55:47 +0800 Subject: [PATCH 18/48] =?UTF-8?q?=E5=BC=80=E6=94=BE=E5=85=A8=E5=B1=80?= =?UTF-8?q?=E8=83=8C=E6=99=AF=E5=9B=BE=E7=89=87=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../io/legado/app/ui/config/ThemeConfigFragment.kt | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/app/src/main/java/io/legado/app/ui/config/ThemeConfigFragment.kt b/app/src/main/java/io/legado/app/ui/config/ThemeConfigFragment.kt index 2a28a1b7f..2a5e414ee 100644 --- a/app/src/main/java/io/legado/app/ui/config/ThemeConfigFragment.kt +++ b/app/src/main/java/io/legado/app/ui/config/ThemeConfigFragment.kt @@ -28,7 +28,6 @@ import io.legado.app.lib.permission.PermissionsCompat import io.legado.app.lib.theme.ATH import io.legado.app.ui.widget.number.NumberPickerDialog import io.legado.app.ui.widget.prefs.ColorPreference -import io.legado.app.ui.widget.prefs.PreferenceCategory import io.legado.app.utils.* import java.io.File @@ -55,15 +54,8 @@ class ThemeConfigFragment : BasePreferenceFragment(), if (Build.VERSION.SDK_INT < 26) { preferenceScreen.removePreferenceRecursively(PreferKey.launcherIcon) } - if (AppConfig.isGooglePlay) { - upPreferenceSummary(PreferKey.bgImage, getPrefString(PreferKey.bgImage)) - upPreferenceSummary(PreferKey.bgImageN, getPrefString(PreferKey.bgImageN)) - } else { - findPreference("dayThemeCategory") - ?.removePreferenceRecursively(PreferKey.bgImage) - findPreference("nightThemeCategory") - ?.removePreferenceRecursively(PreferKey.bgImageN) - } + upPreferenceSummary(PreferKey.bgImage, getPrefString(PreferKey.bgImage)) + upPreferenceSummary(PreferKey.bgImageN, getPrefString(PreferKey.bgImageN)) upPreferenceSummary(PreferKey.barElevation, AppConfig.elevation.toString()) findPreference(PreferKey.cBackground)?.let { it.onSaveColor = { color -> From 39fedaf1f8a7a3909b513aaaaa28c82586e7ef20 Mon Sep 17 00:00:00 2001 From: gedoor Date: Fri, 30 Apr 2021 22:04:00 +0800 Subject: [PATCH 19/48] =?UTF-8?q?=E5=BC=80=E6=94=BE=E5=85=A8=E5=B1=80?= =?UTF-8?q?=E8=83=8C=E6=99=AF=E5=9B=BE=E7=89=87=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/assets/updateLog.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/assets/updateLog.md b/app/src/main/assets/updateLog.md index 66adaa501..8832f1657 100644 --- a/app/src/main/assets/updateLog.md +++ b/app/src/main/assets/updateLog.md @@ -3,7 +3,7 @@ * 关注合作公众号 **[小说拾遗]** 获取好看的小说。 * 旧版数据导入教程:先在旧版阅读(2.x)中进行备份,然后在新版阅读(3.x)【我的】->【备份与恢复】,选择【导入旧版本数据】。 -**2021/04/29** +**2021/04/30** * epub插图,epublib优化,图片解码优化,epub读取导出优化。by ag2s20150909 * 添加高刷设置 * 其它一些优化 From d7a952d018833288e6ac3b43144a8644a6ce1ecf Mon Sep 17 00:00:00 2001 From: gedoor Date: Sat, 1 May 2021 19:06:52 +0800 Subject: [PATCH 20/48] =?UTF-8?q?=E5=BC=80=E6=94=BE=E5=85=A8=E5=B1=80?= =?UTF-8?q?=E8=83=8C=E6=99=AF=E5=9B=BE=E7=89=87=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/java/io/legado/app/base/BaseActivity.kt | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/io/legado/app/base/BaseActivity.kt b/app/src/main/java/io/legado/app/base/BaseActivity.kt index 7ae907b99..e89e47642 100644 --- a/app/src/main/java/io/legado/app/base/BaseActivity.kt +++ b/app/src/main/java/io/legado/app/base/BaseActivity.kt @@ -172,11 +172,9 @@ abstract class BaseActivity( ATH.applyBackgroundTint(window.decorView) } } - if (AppConfig.isGooglePlay) { - ThemeConfig.getBgImage(this)?.let { - kotlin.runCatching { - window.decorView.background = it - } + ThemeConfig.getBgImage(this)?.let { + kotlin.runCatching { + window.decorView.background = it } } } From 50f35c2a912ec2113810f9091e4523c060af7dc6 Mon Sep 17 00:00:00 2001 From: david082321 Date: Sat, 1 May 2021 19:42:08 +0800 Subject: [PATCH 21/48] Update translation Update zh-TW translation --- app/src/main/res/values-zh-rTW/strings.xml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index a29b45531..99f5030d0 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -812,6 +812,8 @@ 匯出到WebDav 反轉內容 除錯 + 當機日誌 + 使用自訂中文分行 圖片樣式 系統TTS 匯出格式 @@ -823,6 +825,6 @@ 列表原始碼 此url已訂閱 高刷 - 使用屏幕最高刷新率 + 使用螢幕最高刷新率 From 2ee438a8153a98ed9af20de7a608eb2fc1951eb7 Mon Sep 17 00:00:00 2001 From: david082321 Date: Sat, 1 May 2021 19:44:16 +0800 Subject: [PATCH 22/48] Update strings.xml MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 使用 https://github.com/gedoor/legado/blob/master/app/src/main/res/values-zh/strings.xml 同步內容順序 --- app/src/main/res/values/strings.xml | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 501d88d96..d0b515fed 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -397,7 +397,6 @@ 分类Url 登录URL(loginUrl) 源注释(sourceComment) - 请求头(header) 搜索地址(url) 发现地址规则(url) 书籍列表规则(bookList) @@ -455,9 +454,10 @@ Data parsing failed - + 请求头(header) Debug source Import from QR code + Share selected sources Scan QR code Tap to display Menu when selected Theme @@ -721,7 +721,6 @@ Select a legacy backup folder Enabled Disabled - Starting download This book is already in Download list click to open @@ -744,7 +743,6 @@ Enable replace rule by default For new added books Select restore file - Switch default theme Day background can not be too dark! Day bottom can not be too dark! Night background can not be too bright! @@ -771,7 +769,7 @@ Save night theme config Theme list Save, Import, Share theme - Share selected sources + Switch default theme Sort by update time Search content 关注公众号[开源阅读]获取订阅源! From 936423ec9fd28a2d1a569051cc80c1796591c6d5 Mon Sep 17 00:00:00 2001 From: david082321 Date: Sat, 1 May 2021 19:48:11 +0800 Subject: [PATCH 23/48] Update strings.xml --- app/src/main/res/values/strings.xml | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index d0b515fed..d98e3483a 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -454,7 +454,7 @@ Data parsing failed - 请求头(header) + H Debug source Import from QR code Share selected sources @@ -772,10 +772,10 @@ Switch default theme Sort by update time Search content - 关注公众号[开源阅读]获取订阅源! + Follow [开源阅读] at WeChat for more RSS source! 当前没有发现源,关注公众号[开源阅读]添加带发现的书源! 将焦点放到输入框按下物理按键会自动录入键值,多个按键会自动用英文逗号隔开. - 主题名称 + Theme name 自动清除过期搜索数据 超过一天的搜索数据 重新分段 @@ -784,13 +784,13 @@ 智能扫描 拷贝书籍URL 拷贝目录URL - 没有书籍 - 保留原名 + NO BOOK + Keep original name 点击区域设置 - 关闭 - 下一页 - 上一页 - 无操作 + Close + Next Page + Prev Page + No Action 正文标题 显示/隐藏 footer header From d34166f519e80df4f675c086ccaa56b721bd66fa Mon Sep 17 00:00:00 2001 From: david082321 Date: Sat, 1 May 2021 19:49:23 +0800 Subject: [PATCH 24/48] Update strings.xml --- app/src/main/res/values/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index d98e3483a..bd230bc1f 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -454,7 +454,7 @@ Data parsing failed - H + HTTP Header Debug source Import from QR code Share selected sources From b86339364d6f2e0a487e3f93fea5c27b5377ef91 Mon Sep 17 00:00:00 2001 From: gedoor Date: Sun, 2 May 2021 22:31:14 +0800 Subject: [PATCH 25/48] =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/io/legado/app/help/http/HttpHelper.kt | 4 ++-- .../app/{utils => help/http}/OkHttpExtensions.kt | 2 +- .../java/io/legado/app/help/http/RetryInterceptor.kt | 12 ++++++++++++ app/src/main/java/io/legado/app/lib/webdav/WebDav.kt | 10 +++++----- 4 files changed, 20 insertions(+), 8 deletions(-) rename app/src/main/java/io/legado/app/{utils => help/http}/OkHttpExtensions.kt (94%) create mode 100644 app/src/main/java/io/legado/app/help/http/RetryInterceptor.kt diff --git a/app/src/main/java/io/legado/app/help/http/HttpHelper.kt b/app/src/main/java/io/legado/app/help/http/HttpHelper.kt index 6a9f7f8b9..a6331d8a6 100644 --- a/app/src/main/java/io/legado/app/help/http/HttpHelper.kt +++ b/app/src/main/java/io/legado/app/help/http/HttpHelper.kt @@ -36,7 +36,7 @@ object HttpHelper { .connectionSpecs(specs) .followRedirects(true) .followSslRedirects(true) - .addInterceptor(getHeaderInterceptor()) + .addInterceptor(headerInterceptor()) builder.build() } @@ -85,7 +85,7 @@ object HttpHelper { return client } - private fun getHeaderInterceptor(): Interceptor { + private fun headerInterceptor(): Interceptor { return Interceptor { chain -> val request = chain.request() .newBuilder() diff --git a/app/src/main/java/io/legado/app/utils/OkHttpExtensions.kt b/app/src/main/java/io/legado/app/help/http/OkHttpExtensions.kt similarity index 94% rename from app/src/main/java/io/legado/app/utils/OkHttpExtensions.kt rename to app/src/main/java/io/legado/app/help/http/OkHttpExtensions.kt index b21bcc8e4..e17fa35c4 100644 --- a/app/src/main/java/io/legado/app/utils/OkHttpExtensions.kt +++ b/app/src/main/java/io/legado/app/help/http/OkHttpExtensions.kt @@ -1,4 +1,4 @@ -package io.legado.app.utils +package io.legado.app.help.http import kotlinx.coroutines.suspendCancellableCoroutine import okhttp3.Call diff --git a/app/src/main/java/io/legado/app/help/http/RetryInterceptor.kt b/app/src/main/java/io/legado/app/help/http/RetryInterceptor.kt new file mode 100644 index 000000000..00c4a0881 --- /dev/null +++ b/app/src/main/java/io/legado/app/help/http/RetryInterceptor.kt @@ -0,0 +1,12 @@ +package io.legado.app.help.http + +import okhttp3.Interceptor +import okhttp3.Response + +class RetryInterceptor : Interceptor { + + override fun intercept(chain: Interceptor.Chain): Response { + TODO("Not yet implemented") + } + +} \ No newline at end of file diff --git a/app/src/main/java/io/legado/app/lib/webdav/WebDav.kt b/app/src/main/java/io/legado/app/lib/webdav/WebDav.kt index 1570bc793..51c8e93ae 100644 --- a/app/src/main/java/io/legado/app/lib/webdav/WebDav.kt +++ b/app/src/main/java/io/legado/app/lib/webdav/WebDav.kt @@ -1,14 +1,12 @@ package io.legado.app.lib.webdav import io.legado.app.help.http.HttpHelper -import io.legado.app.utils.await +import io.legado.app.help.http.await import okhttp3.* import okhttp3.MediaType.Companion.toMediaType import okhttp3.RequestBody.Companion.asRequestBody import okhttp3.RequestBody.Companion.toRequestBody import org.jsoup.Jsoup -import rxhttp.wrapper.param.RxHttp -import rxhttp.wrapper.param.toInputStream import java.io.File import java.io.IOException import java.io.InputStream @@ -238,9 +236,11 @@ class WebDav(urlStr: String) { val url = httpUrl val auth = HttpAuth.auth if (url != null && auth != null) { - return RxHttp.get(url) + val requestBuilder = Request.Builder() + .url(url) .addHeader("Authorization", Credentials.basic(auth.user, auth.pass)) - .toInputStream().await() + return HttpHelper.client.newCall(request = requestBuilder.build()).await() + .body?.byteStream() } return null } From da0d070bfe0b4dad1c7054886a7d6daa7c375566 Mon Sep 17 00:00:00 2001 From: gedoor Date: Sun, 2 May 2021 23:02:37 +0800 Subject: [PATCH 26/48] =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../legado/app/help/http/OkHttpExtensions.kt | 22 +++++++++++++++ .../app/help/http/parser/StrResponseParser.kt | 27 +++---------------- .../legado/app/help/http/parser/TextParser.kt | 20 ++------------ 3 files changed, 27 insertions(+), 42 deletions(-) diff --git a/app/src/main/java/io/legado/app/help/http/OkHttpExtensions.kt b/app/src/main/java/io/legado/app/help/http/OkHttpExtensions.kt index e17fa35c4..d32d9f3d4 100644 --- a/app/src/main/java/io/legado/app/help/http/OkHttpExtensions.kt +++ b/app/src/main/java/io/legado/app/help/http/OkHttpExtensions.kt @@ -1,10 +1,14 @@ package io.legado.app.help.http +import io.legado.app.utils.EncodingDetect +import io.legado.app.utils.UTF8BOMFighter import kotlinx.coroutines.suspendCancellableCoroutine import okhttp3.Call import okhttp3.Callback import okhttp3.Response +import okhttp3.ResponseBody import java.io.IOException +import java.nio.charset.Charset import kotlin.coroutines.resume import kotlin.coroutines.resumeWithException @@ -24,4 +28,22 @@ suspend fun Call.await(): Response = suspendCancellableCoroutine { block -> } }) +} + +fun ResponseBody.text(encode: String? = null): String { + val responseBytes = UTF8BOMFighter.removeUTF8BOM(bytes()) + var charsetName: String? = encode + + charsetName?.let { + return String(responseBytes, Charset.forName(charsetName)) + } + + //根据http头判断 + contentType()?.charset()?.let { + return String(responseBytes, it) + } + + //根据内容判断 + charsetName = EncodingDetect.getHtmlEncode(responseBytes) + return String(responseBytes, Charset.forName(charsetName)) } \ No newline at end of file diff --git a/app/src/main/java/io/legado/app/help/http/parser/StrResponseParser.kt b/app/src/main/java/io/legado/app/help/http/parser/StrResponseParser.kt index 9868b9dc8..a5c8cdbe5 100644 --- a/app/src/main/java/io/legado/app/help/http/parser/StrResponseParser.kt +++ b/app/src/main/java/io/legado/app/help/http/parser/StrResponseParser.kt @@ -1,40 +1,19 @@ package io.legado.app.help.http.parser import io.legado.app.help.http.StrResponse -import io.legado.app.utils.EncodingDetect -import io.legado.app.utils.UTF8BOMFighter +import io.legado.app.help.http.text import okhttp3.Response import rxhttp.wrapper.annotation.Parser import rxhttp.wrapper.exception.HttpStatusCodeException -import java.nio.charset.Charset @Parser(name = "StrResponse") class StrResponseParser(private val encode: String? = null) : rxhttp.wrapper.parse.Parser { override fun onParse(response: Response): StrResponse { - val body = getString(response) + val body = response.body?.text(encode) + ?: throw HttpStatusCodeException(response, "内容为空") return StrResponse(response, body) } - private fun getString(response: Response): String { - - val responseBody = response.body ?: throw HttpStatusCodeException(response, "内容为空") - val responseBytes = UTF8BOMFighter.removeUTF8BOM(responseBody.bytes()) - var charsetName: String? = encode - - charsetName?.let { - return String(responseBytes, Charset.forName(charsetName)) - } - - //根据http头判断 - responseBody.contentType()?.charset()?.let { - return String(responseBytes, it) - } - - //根据内容判断 - charsetName = EncodingDetect.getHtmlEncode(responseBytes) - return String(responseBytes, Charset.forName(charsetName)) - } - } \ No newline at end of file diff --git a/app/src/main/java/io/legado/app/help/http/parser/TextParser.kt b/app/src/main/java/io/legado/app/help/http/parser/TextParser.kt index 031ad9d33..1d4c4ec93 100644 --- a/app/src/main/java/io/legado/app/help/http/parser/TextParser.kt +++ b/app/src/main/java/io/legado/app/help/http/parser/TextParser.kt @@ -1,11 +1,9 @@ package io.legado.app.help.http.parser -import io.legado.app.utils.EncodingDetect -import io.legado.app.utils.UTF8BOMFighter +import io.legado.app.help.http.text import okhttp3.Response import rxhttp.wrapper.annotation.Parser import rxhttp.wrapper.exception.HttpStatusCodeException -import java.nio.charset.Charset @Parser(name = "Text") class TextParser(private val encode: String? = null) : rxhttp.wrapper.parse.Parser { @@ -13,21 +11,7 @@ class TextParser(private val encode: String? = null) : rxhttp.wrapper.parse.Pars override fun onParse(response: Response): String { val responseBody = response.body ?: throw HttpStatusCodeException(response, "内容为空") - val responseBytes = UTF8BOMFighter.removeUTF8BOM(responseBody.bytes()) - var charsetName: String? = encode - - charsetName?.let { - return String(responseBytes, Charset.forName(charsetName)) - } - - //根据http头判断 - responseBody.contentType()?.charset()?.let { - return String(responseBytes, it) - } - - //根据内容判断 - charsetName = EncodingDetect.getHtmlEncode(responseBytes) - return String(responseBytes, Charset.forName(charsetName)) + return responseBody.text(encode) } } \ No newline at end of file From d9bcb7506aca5c48ccc3b5c7d5b7e4f409051a89 Mon Sep 17 00:00:00 2001 From: gedoor Date: Mon, 3 May 2021 00:16:33 +0800 Subject: [PATCH 27/48] =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/java/io/legado/app/App.kt | 4 +- .../io/legado/app/help/http/HttpHelper.kt | 92 +----------- .../legado/app/help/http/OkHttpExtensions.kt | 49 ------- .../io/legado/app/help/http/OkHttpHelper.kt | 131 ++++++++++++++++++ .../java/io/legado/app/lib/webdav/WebDav.kt | 8 +- .../app/model/analyzeRule/AnalyzeUrl.kt | 12 +- 6 files changed, 144 insertions(+), 152 deletions(-) delete mode 100644 app/src/main/java/io/legado/app/help/http/OkHttpExtensions.kt create mode 100644 app/src/main/java/io/legado/app/help/http/OkHttpHelper.kt diff --git a/app/src/main/java/io/legado/app/App.kt b/app/src/main/java/io/legado/app/App.kt index 6345cf1b1..b5edcd40f 100644 --- a/app/src/main/java/io/legado/app/App.kt +++ b/app/src/main/java/io/legado/app/App.kt @@ -15,7 +15,7 @@ import io.legado.app.help.ActivityHelp import io.legado.app.help.AppConfig import io.legado.app.help.CrashHandler import io.legado.app.help.ThemeConfig.applyDayNight -import io.legado.app.help.http.HttpHelper +import io.legado.app.help.http.okHttpClient import io.legado.app.utils.LanguageUtils import io.legado.app.utils.defaultSharedPreferences import rxhttp.wrapper.param.RxHttp @@ -26,7 +26,7 @@ class App : MultiDexApplication() { super.onCreate() CrashHandler(this) LanguageUtils.setConfiguration(this) - RxHttp.init(HttpHelper.client, BuildConfig.DEBUG) + RxHttp.init(okHttpClient, BuildConfig.DEBUG) RxHttp.setOnParamAssembly { it.addHeader(AppConst.UA_NAME, AppConfig.userAgent) } diff --git a/app/src/main/java/io/legado/app/help/http/HttpHelper.kt b/app/src/main/java/io/legado/app/help/http/HttpHelper.kt index a6331d8a6..99037a3cd 100644 --- a/app/src/main/java/io/legado/app/help/http/HttpHelper.kt +++ b/app/src/main/java/io/legado/app/help/http/HttpHelper.kt @@ -1,102 +1,12 @@ package io.legado.app.help.http import kotlinx.coroutines.suspendCancellableCoroutine -import okhttp3.ConnectionSpec -import okhttp3.Credentials -import okhttp3.Interceptor -import okhttp3.OkHttpClient -import java.net.InetSocketAddress -import java.net.Proxy -import java.util.concurrent.ConcurrentHashMap -import java.util.concurrent.TimeUnit import kotlin.coroutines.resume @Suppress("unused") object HttpHelper { - private val proxyClientCache: ConcurrentHashMap by lazy { - ConcurrentHashMap() - } - - val client: OkHttpClient by lazy { - - val specs = arrayListOf( - ConnectionSpec.MODERN_TLS, - ConnectionSpec.COMPATIBLE_TLS, - ConnectionSpec.CLEARTEXT - ) - - val builder = OkHttpClient.Builder() - .connectTimeout(15, TimeUnit.SECONDS) - .writeTimeout(15, TimeUnit.SECONDS) - .readTimeout(15, TimeUnit.SECONDS) - .sslSocketFactory(SSLHelper.unsafeSSLSocketFactory, SSLHelper.unsafeTrustManager) - .retryOnConnectionFailure(true) - .hostnameVerifier(SSLHelper.unsafeHostnameVerifier) - .connectionSpecs(specs) - .followRedirects(true) - .followSslRedirects(true) - .addInterceptor(headerInterceptor()) - - builder.build() - } - - /** - * 缓存代理okHttp - */ - fun getProxyClient(proxy: String? = null): OkHttpClient { - if (proxy.isNullOrBlank()) { - return client - } - proxyClientCache[proxy]?.let { - return it - } - val r = Regex("(http|socks4|socks5)://(.*):(\\d{2,5})(@.*@.*)?") - val ms = r.findAll(proxy) - val group = ms.first() - var username = "" //代理服务器验证用户名 - var password = "" //代理服务器验证密码 - val type = if (group.groupValues[1] == "http") "http" else "socks" - val host = group.groupValues[2] - val port = group.groupValues[3].toInt() - if (group.groupValues[4] != "") { - username = group.groupValues[4].split("@")[1] - password = group.groupValues[4].split("@")[2] - } - if (type != "direct" && host != "") { - val builder = client.newBuilder() - if (type == "http") { - builder.proxy(Proxy(Proxy.Type.HTTP, InetSocketAddress(host, port))) - } else { - builder.proxy(Proxy(Proxy.Type.SOCKS, InetSocketAddress(host, port))) - } - if (username != "" && password != "") { - builder.proxyAuthenticator { _, response -> //设置代理服务器账号密码 - val credential: String = Credentials.basic(username, password) - response.request.newBuilder() - .header("Proxy-Authorization", credential) - .build() - } - } - val proxyClient = builder.build() - proxyClientCache[proxy] = proxyClient - return proxyClient - } - return client - } - - private fun headerInterceptor(): Interceptor { - return Interceptor { chain -> - val request = chain.request() - .newBuilder() - .addHeader("Keep-Alive", "300") - .addHeader("Connection", "Keep-Alive") - .addHeader("Cache-Control", "no-cache") - .build() - chain.proceed(request) - } - } - + suspend fun ajax(params: AjaxWebView.AjaxParams): StrResponse = suspendCancellableCoroutine { block -> val webView = AjaxWebView() diff --git a/app/src/main/java/io/legado/app/help/http/OkHttpExtensions.kt b/app/src/main/java/io/legado/app/help/http/OkHttpExtensions.kt deleted file mode 100644 index d32d9f3d4..000000000 --- a/app/src/main/java/io/legado/app/help/http/OkHttpExtensions.kt +++ /dev/null @@ -1,49 +0,0 @@ -package io.legado.app.help.http - -import io.legado.app.utils.EncodingDetect -import io.legado.app.utils.UTF8BOMFighter -import kotlinx.coroutines.suspendCancellableCoroutine -import okhttp3.Call -import okhttp3.Callback -import okhttp3.Response -import okhttp3.ResponseBody -import java.io.IOException -import java.nio.charset.Charset -import kotlin.coroutines.resume -import kotlin.coroutines.resumeWithException - -suspend fun Call.await(): Response = suspendCancellableCoroutine { block -> - - block.invokeOnCancellation { - cancel() - } - - enqueue(object : Callback { - override fun onFailure(call: Call, e: IOException) { - block.resumeWithException(e) - } - - override fun onResponse(call: Call, response: Response) { - block.resume(response) - } - }) - -} - -fun ResponseBody.text(encode: String? = null): String { - val responseBytes = UTF8BOMFighter.removeUTF8BOM(bytes()) - var charsetName: String? = encode - - charsetName?.let { - return String(responseBytes, Charset.forName(charsetName)) - } - - //根据http头判断 - contentType()?.charset()?.let { - return String(responseBytes, it) - } - - //根据内容判断 - charsetName = EncodingDetect.getHtmlEncode(responseBytes) - return String(responseBytes, Charset.forName(charsetName)) -} \ No newline at end of file diff --git a/app/src/main/java/io/legado/app/help/http/OkHttpHelper.kt b/app/src/main/java/io/legado/app/help/http/OkHttpHelper.kt new file mode 100644 index 000000000..a97e784c8 --- /dev/null +++ b/app/src/main/java/io/legado/app/help/http/OkHttpHelper.kt @@ -0,0 +1,131 @@ +package io.legado.app.help.http + +import io.legado.app.utils.EncodingDetect +import io.legado.app.utils.UTF8BOMFighter +import kotlinx.coroutines.suspendCancellableCoroutine +import okhttp3.* +import java.io.IOException +import java.net.InetSocketAddress +import java.net.Proxy +import java.nio.charset.Charset +import java.util.concurrent.ConcurrentHashMap +import java.util.concurrent.TimeUnit +import kotlin.coroutines.resume +import kotlin.coroutines.resumeWithException + +val okHttpClient: OkHttpClient by lazy { + + val specs = arrayListOf( + ConnectionSpec.MODERN_TLS, + ConnectionSpec.COMPATIBLE_TLS, + ConnectionSpec.CLEARTEXT + ) + + val builder = OkHttpClient.Builder() + .connectTimeout(15, TimeUnit.SECONDS) + .writeTimeout(15, TimeUnit.SECONDS) + .readTimeout(15, TimeUnit.SECONDS) + .sslSocketFactory(SSLHelper.unsafeSSLSocketFactory, SSLHelper.unsafeTrustManager) + .retryOnConnectionFailure(true) + .hostnameVerifier(SSLHelper.unsafeHostnameVerifier) + .connectionSpecs(specs) + .followRedirects(true) + .followSslRedirects(true) + .addInterceptor(Interceptor { chain -> + val request = chain.request() + .newBuilder() + .addHeader("Keep-Alive", "300") + .addHeader("Connection", "Keep-Alive") + .addHeader("Cache-Control", "no-cache") + .build() + chain.proceed(request) + }) + + builder.build() +} + +object OkHttpHelper { + private val proxyClientCache: ConcurrentHashMap by lazy { + ConcurrentHashMap() + } + + /** + * 缓存代理okHttp + */ + fun getProxyClient(proxy: String? = null): OkHttpClient { + if (proxy.isNullOrBlank()) { + return okHttpClient + } + proxyClientCache[proxy]?.let { + return it + } + val r = Regex("(http|socks4|socks5)://(.*):(\\d{2,5})(@.*@.*)?") + val ms = r.findAll(proxy) + val group = ms.first() + var username = "" //代理服务器验证用户名 + var password = "" //代理服务器验证密码 + val type = if (group.groupValues[1] == "http") "http" else "socks" + val host = group.groupValues[2] + val port = group.groupValues[3].toInt() + if (group.groupValues[4] != "") { + username = group.groupValues[4].split("@")[1] + password = group.groupValues[4].split("@")[2] + } + if (type != "direct" && host != "") { + val builder = okHttpClient.newBuilder() + if (type == "http") { + builder.proxy(Proxy(Proxy.Type.HTTP, InetSocketAddress(host, port))) + } else { + builder.proxy(Proxy(Proxy.Type.SOCKS, InetSocketAddress(host, port))) + } + if (username != "" && password != "") { + builder.proxyAuthenticator { _, response -> //设置代理服务器账号密码 + val credential: String = Credentials.basic(username, password) + response.request.newBuilder() + .header("Proxy-Authorization", credential) + .build() + } + } + val proxyClient = builder.build() + proxyClientCache[proxy] = proxyClient + return proxyClient + } + return okHttpClient + } +} + +suspend fun Call.await(): Response = suspendCancellableCoroutine { block -> + + block.invokeOnCancellation { + cancel() + } + + enqueue(object : Callback { + override fun onFailure(call: Call, e: IOException) { + block.resumeWithException(e) + } + + override fun onResponse(call: Call, response: Response) { + block.resume(response) + } + }) + +} + +fun ResponseBody.text(encode: String? = null): String { + val responseBytes = UTF8BOMFighter.removeUTF8BOM(bytes()) + var charsetName: String? = encode + + charsetName?.let { + return String(responseBytes, Charset.forName(charsetName)) + } + + //根据http头判断 + contentType()?.charset()?.let { + return String(responseBytes, it) + } + + //根据内容判断 + charsetName = EncodingDetect.getHtmlEncode(responseBytes) + return String(responseBytes, Charset.forName(charsetName)) +} \ No newline at end of file diff --git a/app/src/main/java/io/legado/app/lib/webdav/WebDav.kt b/app/src/main/java/io/legado/app/lib/webdav/WebDav.kt index 51c8e93ae..612781028 100644 --- a/app/src/main/java/io/legado/app/lib/webdav/WebDav.kt +++ b/app/src/main/java/io/legado/app/lib/webdav/WebDav.kt @@ -1,7 +1,7 @@ package io.legado.app.lib.webdav -import io.legado.app.help.http.HttpHelper import io.legado.app.help.http.await +import io.legado.app.help.http.okHttpClient import okhttp3.* import okhttp3.MediaType.Companion.toMediaType import okhttp3.RequestBody.Companion.asRequestBody @@ -113,7 +113,7 @@ class WebDav(urlStr: String) { request.header("Authorization", Credentials.basic(it.user, it.pass)) } request.header("Depth", if (depth < 0) "infinity" else depth.toString()) - return HttpHelper.client.newCall(request.build()).await() + return okHttpClient.newCall(request.build()).await() } return null } @@ -227,7 +227,7 @@ class WebDav(urlStr: String) { HttpAuth.auth?.let { requestBuilder.header("Authorization", Credentials.basic(it.user, it.pass)) } - val response = HttpHelper.client.newCall(requestBuilder.build()).await() + val response = okHttpClient.newCall(requestBuilder.build()).await() return response.isSuccessful } @@ -239,7 +239,7 @@ class WebDav(urlStr: String) { val requestBuilder = Request.Builder() .url(url) .addHeader("Authorization", Credentials.basic(auth.user, auth.pass)) - return HttpHelper.client.newCall(request = requestBuilder.build()).await() + return okHttpClient.newCall(request = requestBuilder.build()).await() .body?.byteStream() } return null diff --git a/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeUrl.kt b/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeUrl.kt index 318c1dcd3..0dc588990 100644 --- a/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeUrl.kt +++ b/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeUrl.kt @@ -312,14 +312,14 @@ class AnalyzeUrl( if (fieldMap.isNotEmpty() || body.isNullOrBlank()) { RxHttp.postForm(url) .setAssemblyEnabled(false) - .setOkClient(HttpHelper.getProxyClient(proxy)) + .setOkClient(OkHttpHelper.getProxyClient(proxy)) .addAllEncoded(fieldMap) .addAllHeader(headerMap) .toStrResponse().await() } else { RxHttp.postJson(url) .setAssemblyEnabled(false) - .setOkClient(HttpHelper.getProxyClient(proxy)) + .setOkClient(OkHttpHelper.getProxyClient(proxy)) .addAll(body) .addAllHeader(headerMap) .toStrResponse().await() @@ -327,7 +327,7 @@ class AnalyzeUrl( } else -> RxHttp.get(url) .setAssemblyEnabled(false) - .setOkClient(HttpHelper.getProxyClient(proxy)) + .setOkClient(OkHttpHelper.getProxyClient(proxy)) .addAllEncoded(fieldMap) .addAllHeader(headerMap) .toStrResponse().await() @@ -341,14 +341,14 @@ class AnalyzeUrl( if (fieldMap.isNotEmpty() || body.isNullOrBlank()) { RxHttp.postForm(url) .setAssemblyEnabled(false) - .setOkClient(HttpHelper.getProxyClient(proxy)) + .setOkClient(OkHttpHelper.getProxyClient(proxy)) .addAllEncoded(fieldMap) .addAllHeader(headerMap) .toByteArray().await() } else { RxHttp.postJson(url) .setAssemblyEnabled(false) - .setOkClient(HttpHelper.getProxyClient(proxy)) + .setOkClient(OkHttpHelper.getProxyClient(proxy)) .addAll(body) .addAllHeader(headerMap) .toByteArray().await() @@ -356,7 +356,7 @@ class AnalyzeUrl( } else -> RxHttp.get(url) .setAssemblyEnabled(false) - .setOkClient(HttpHelper.getProxyClient(proxy)) + .setOkClient(OkHttpHelper.getProxyClient(proxy)) .addAllEncoded(fieldMap) .addAllHeader(headerMap) .toByteArray().await() From 9e029a6823a720f9611c21a04c16b7414205cf46 Mon Sep 17 00:00:00 2001 From: gedoor Date: Mon, 3 May 2021 00:56:59 +0800 Subject: [PATCH 28/48] =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/io/legado/app/help/http/HttpHelper.kt | 9 ++++++++- app/src/main/java/io/legado/app/lib/webdav/WebDav.kt | 10 +++++----- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/app/src/main/java/io/legado/app/help/http/HttpHelper.kt b/app/src/main/java/io/legado/app/help/http/HttpHelper.kt index 99037a3cd..324673c3a 100644 --- a/app/src/main/java/io/legado/app/help/http/HttpHelper.kt +++ b/app/src/main/java/io/legado/app/help/http/HttpHelper.kt @@ -1,12 +1,19 @@ package io.legado.app.help.http import kotlinx.coroutines.suspendCancellableCoroutine +import okhttp3.Request +import okhttp3.Response import kotlin.coroutines.resume @Suppress("unused") object HttpHelper { - + suspend fun newCall(builder: Request.Builder.() -> Unit, proxy: String? = null): Response { + val client = OkHttpHelper.getProxyClient(proxy) + val requestBuilder = Request.Builder().apply(builder) + return client.newCall(requestBuilder.build()).await() + } + suspend fun ajax(params: AjaxWebView.AjaxParams): StrResponse = suspendCancellableCoroutine { block -> val webView = AjaxWebView() diff --git a/app/src/main/java/io/legado/app/lib/webdav/WebDav.kt b/app/src/main/java/io/legado/app/lib/webdav/WebDav.kt index 612781028..c98ee33d4 100644 --- a/app/src/main/java/io/legado/app/lib/webdav/WebDav.kt +++ b/app/src/main/java/io/legado/app/lib/webdav/WebDav.kt @@ -1,5 +1,6 @@ package io.legado.app.lib.webdav +import io.legado.app.help.http.HttpHelper import io.legado.app.help.http.await import io.legado.app.help.http.okHttpClient import okhttp3.* @@ -236,11 +237,10 @@ class WebDav(urlStr: String) { val url = httpUrl val auth = HttpAuth.auth if (url != null && auth != null) { - val requestBuilder = Request.Builder() - .url(url) - .addHeader("Authorization", Credentials.basic(auth.user, auth.pass)) - return okHttpClient.newCall(request = requestBuilder.build()).await() - .body?.byteStream() + return HttpHelper.newCall({ + url(url) + addHeader("Authorization", Credentials.basic(auth.user, auth.pass)) + }).body?.byteStream() } return null } From ccb4a0092f1947dcdc7cfb6306239751af9e59c3 Mon Sep 17 00:00:00 2001 From: gedoor Date: Mon, 3 May 2021 16:13:57 +0800 Subject: [PATCH 29/48] =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../io/legado/app/help/http/HttpHelper.kt | 8 -- .../io/legado/app/help/http/OkHttpHelper.kt | 89 +++++++------- .../java/io/legado/app/lib/webdav/WebDav.kt | 109 +++++++++--------- .../app/model/analyzeRule/AnalyzeUrl.kt | 12 +- 4 files changed, 104 insertions(+), 114 deletions(-) diff --git a/app/src/main/java/io/legado/app/help/http/HttpHelper.kt b/app/src/main/java/io/legado/app/help/http/HttpHelper.kt index 324673c3a..f87085a9c 100644 --- a/app/src/main/java/io/legado/app/help/http/HttpHelper.kt +++ b/app/src/main/java/io/legado/app/help/http/HttpHelper.kt @@ -1,19 +1,11 @@ package io.legado.app.help.http import kotlinx.coroutines.suspendCancellableCoroutine -import okhttp3.Request -import okhttp3.Response import kotlin.coroutines.resume @Suppress("unused") object HttpHelper { - suspend fun newCall(builder: Request.Builder.() -> Unit, proxy: String? = null): Response { - val client = OkHttpHelper.getProxyClient(proxy) - val requestBuilder = Request.Builder().apply(builder) - return client.newCall(requestBuilder.build()).await() - } - suspend fun ajax(params: AjaxWebView.AjaxParams): StrResponse = suspendCancellableCoroutine { block -> val webView = AjaxWebView() diff --git a/app/src/main/java/io/legado/app/help/http/OkHttpHelper.kt b/app/src/main/java/io/legado/app/help/http/OkHttpHelper.kt index a97e784c8..dccf75d6b 100644 --- a/app/src/main/java/io/legado/app/help/http/OkHttpHelper.kt +++ b/app/src/main/java/io/legado/app/help/http/OkHttpHelper.kt @@ -13,6 +13,10 @@ import java.util.concurrent.TimeUnit import kotlin.coroutines.resume import kotlin.coroutines.resumeWithException +private val proxyClientCache: ConcurrentHashMap by lazy { + ConcurrentHashMap() +} + val okHttpClient: OkHttpClient by lazy { val specs = arrayListOf( @@ -44,54 +48,53 @@ val okHttpClient: OkHttpClient by lazy { builder.build() } -object OkHttpHelper { - private val proxyClientCache: ConcurrentHashMap by lazy { - ConcurrentHashMap() +/** + * 缓存代理okHttp + */ +fun getProxyClient(proxy: String? = null): OkHttpClient { + if (proxy.isNullOrBlank()) { + return okHttpClient } - - /** - * 缓存代理okHttp - */ - fun getProxyClient(proxy: String? = null): OkHttpClient { - if (proxy.isNullOrBlank()) { - return okHttpClient - } - proxyClientCache[proxy]?.let { - return it - } - val r = Regex("(http|socks4|socks5)://(.*):(\\d{2,5})(@.*@.*)?") - val ms = r.findAll(proxy) - val group = ms.first() - var username = "" //代理服务器验证用户名 - var password = "" //代理服务器验证密码 - val type = if (group.groupValues[1] == "http") "http" else "socks" - val host = group.groupValues[2] - val port = group.groupValues[3].toInt() - if (group.groupValues[4] != "") { - username = group.groupValues[4].split("@")[1] - password = group.groupValues[4].split("@")[2] + proxyClientCache[proxy]?.let { + return it + } + val r = Regex("(http|socks4|socks5)://(.*):(\\d{2,5})(@.*@.*)?") + val ms = r.findAll(proxy) + val group = ms.first() + var username = "" //代理服务器验证用户名 + var password = "" //代理服务器验证密码 + val type = if (group.groupValues[1] == "http") "http" else "socks" + val host = group.groupValues[2] + val port = group.groupValues[3].toInt() + if (group.groupValues[4] != "") { + username = group.groupValues[4].split("@")[1] + password = group.groupValues[4].split("@")[2] + } + if (type != "direct" && host != "") { + val builder = okHttpClient.newBuilder() + if (type == "http") { + builder.proxy(Proxy(Proxy.Type.HTTP, InetSocketAddress(host, port))) + } else { + builder.proxy(Proxy(Proxy.Type.SOCKS, InetSocketAddress(host, port))) } - if (type != "direct" && host != "") { - val builder = okHttpClient.newBuilder() - if (type == "http") { - builder.proxy(Proxy(Proxy.Type.HTTP, InetSocketAddress(host, port))) - } else { - builder.proxy(Proxy(Proxy.Type.SOCKS, InetSocketAddress(host, port))) - } - if (username != "" && password != "") { - builder.proxyAuthenticator { _, response -> //设置代理服务器账号密码 - val credential: String = Credentials.basic(username, password) - response.request.newBuilder() - .header("Proxy-Authorization", credential) - .build() - } + if (username != "" && password != "") { + builder.proxyAuthenticator { _, response -> //设置代理服务器账号密码 + val credential: String = Credentials.basic(username, password) + response.request.newBuilder() + .header("Proxy-Authorization", credential) + .build() } - val proxyClient = builder.build() - proxyClientCache[proxy] = proxyClient - return proxyClient } - return okHttpClient + val proxyClient = builder.build() + proxyClientCache[proxy] = proxyClient + return proxyClient } + return okHttpClient +} + +fun OkHttpClient.newCall(builder: Request.Builder.() -> Unit): Call { + val requestBuilder = Request.Builder().apply(builder) + return this.newCall(requestBuilder.build()) } suspend fun Call.await(): Response = suspendCancellableCoroutine { block -> diff --git a/app/src/main/java/io/legado/app/lib/webdav/WebDav.kt b/app/src/main/java/io/legado/app/lib/webdav/WebDav.kt index c98ee33d4..1cc1220bc 100644 --- a/app/src/main/java/io/legado/app/lib/webdav/WebDav.kt +++ b/app/src/main/java/io/legado/app/lib/webdav/WebDav.kt @@ -1,7 +1,7 @@ package io.legado.app.lib.webdav -import io.legado.app.help.http.HttpHelper import io.legado.app.help.http.await +import io.legado.app.help.http.newCall import io.legado.app.help.http.okHttpClient import okhttp3.* import okhttp3.MediaType.Companion.toMediaType @@ -21,17 +21,19 @@ class WebDav(urlStr: String) { companion object { // 指定返回哪些属性 private const val DIR = - """ - - - - - - - - %s - - """ + """ + + + + + + + + + %s + + + """ } private val url: URL = URL(urlStr) @@ -92,7 +94,7 @@ class WebDav(urlStr: String) { } @Throws(IOException::class) - private suspend fun propFindResponse(propsList: ArrayList, depth: Int = 1): Response? { + private suspend fun propFindResponse(propsList: ArrayList): Response? { val requestProps = StringBuilder() for (p in propsList) { requestProps.append("\n") @@ -102,19 +104,17 @@ class WebDav(urlStr: String) { } else { String.format(DIR, requestProps.toString() + "\n") } - httpUrl?.let { url -> - // 添加RequestBody对象,可以只返回的属性。如果设为null,则会返回全部属性 - // 注意:尽量手动指定需要返回的属性。若返回全部属性,可能后由于Prop.java里没有该属性名,而崩溃。 - val requestBody = requestPropsStr.toRequestBody("text/plain".toMediaType()) - val request = Request.Builder() - .url(url) - .method("PROPFIND", requestBody) - - HttpAuth.auth?.let { - request.header("Authorization", Credentials.basic(it.user, it.pass)) - } - request.header("Depth", if (depth < 0) "infinity" else depth.toString()) - return okHttpClient.newCall(request.build()).await() + val url = httpUrl + val auth = HttpAuth.auth + if (url != null && auth != null) { + return okHttpClient.newCall { + url(url) + addHeader("Authorization", Credentials.basic(auth.user, auth.pass)) + // 添加RequestBody对象,可以只返回的属性。如果设为null,则会返回全部属性 + // 注意:尽量手动指定需要返回的属性。若返回全部属性,可能后由于Prop.java里没有该属性名,而崩溃。 + val requestBody = requestPropsStr.toRequestBody("text/plain".toMediaType()) + method("PROPFIND", requestBody) + }.await() } return null } @@ -159,11 +159,14 @@ class WebDav(urlStr: String) { * @return 是否创建成功 */ suspend fun makeAsDir(): Boolean { - httpUrl?.let { url -> - val request = Request.Builder() - .url(url) - .method("MKCOL", null) - return execRequest(request) + val url = httpUrl + val auth = HttpAuth.auth + if (url != null && auth != null) { + return okHttpClient.newCall { + url(url) + method("MKCOL", null) + addHeader("Authorization", Credentials.basic(auth.user, auth.pass)) + }.await().isSuccessful } return false } @@ -197,11 +200,14 @@ class WebDav(urlStr: String) { if (!file.exists()) return false // 务必注意RequestBody不要嵌套,不然上传时内容可能会被追加多余的文件信息 val fileBody = file.asRequestBody(contentType?.toMediaType()) - httpUrl?.let { - val request = Request.Builder() - .url(it) - .put(fileBody) - return execRequest(request) + val url = httpUrl + val auth = HttpAuth.auth + if (url != null && auth != null) { + return okHttpClient.newCall { + url(url) + put(fileBody) + addHeader("Authorization", Credentials.basic(auth.user, auth.pass)) + }.await().isSuccessful } return false } @@ -209,38 +215,27 @@ class WebDav(urlStr: String) { suspend fun upload(byteArray: ByteArray, contentType: String? = null): Boolean { // 务必注意RequestBody不要嵌套,不然上传时内容可能会被追加多余的文件信息 val fileBody = byteArray.toRequestBody(contentType?.toMediaType()) - httpUrl?.let { - val request = Request.Builder() - .url(it) - .put(fileBody) - return execRequest(request) + val url = httpUrl + val auth = HttpAuth.auth + if (url != null && auth != null) { + return okHttpClient.newCall { + url(url) + put(fileBody) + addHeader("Authorization", Credentials.basic(auth.user, auth.pass)) + }.await().isSuccessful } return false } - /** - * 执行请求,获取响应结果 - * @param requestBuilder 因为还需要追加验证信息,所以此处传递Request.Builder的对象,而不是Request的对象 - * @return 请求执行的结果 - */ - @Throws(IOException::class) - private suspend fun execRequest(requestBuilder: Request.Builder): Boolean { - HttpAuth.auth?.let { - requestBuilder.header("Authorization", Credentials.basic(it.user, it.pass)) - } - val response = okHttpClient.newCall(requestBuilder.build()).await() - return response.isSuccessful - } - @Throws(IOException::class) private suspend fun getInputStream(): InputStream? { val url = httpUrl val auth = HttpAuth.auth if (url != null && auth != null) { - return HttpHelper.newCall({ + return okHttpClient.newCall { url(url) addHeader("Authorization", Credentials.basic(auth.user, auth.pass)) - }).body?.byteStream() + }.await().body?.byteStream() } return null } diff --git a/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeUrl.kt b/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeUrl.kt index 0dc588990..d61ca7633 100644 --- a/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeUrl.kt +++ b/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeUrl.kt @@ -312,14 +312,14 @@ class AnalyzeUrl( if (fieldMap.isNotEmpty() || body.isNullOrBlank()) { RxHttp.postForm(url) .setAssemblyEnabled(false) - .setOkClient(OkHttpHelper.getProxyClient(proxy)) + .setOkClient(getProxyClient(proxy)) .addAllEncoded(fieldMap) .addAllHeader(headerMap) .toStrResponse().await() } else { RxHttp.postJson(url) .setAssemblyEnabled(false) - .setOkClient(OkHttpHelper.getProxyClient(proxy)) + .setOkClient(getProxyClient(proxy)) .addAll(body) .addAllHeader(headerMap) .toStrResponse().await() @@ -327,7 +327,7 @@ class AnalyzeUrl( } else -> RxHttp.get(url) .setAssemblyEnabled(false) - .setOkClient(OkHttpHelper.getProxyClient(proxy)) + .setOkClient(getProxyClient(proxy)) .addAllEncoded(fieldMap) .addAllHeader(headerMap) .toStrResponse().await() @@ -341,14 +341,14 @@ class AnalyzeUrl( if (fieldMap.isNotEmpty() || body.isNullOrBlank()) { RxHttp.postForm(url) .setAssemblyEnabled(false) - .setOkClient(OkHttpHelper.getProxyClient(proxy)) + .setOkClient(getProxyClient(proxy)) .addAllEncoded(fieldMap) .addAllHeader(headerMap) .toByteArray().await() } else { RxHttp.postJson(url) .setAssemblyEnabled(false) - .setOkClient(OkHttpHelper.getProxyClient(proxy)) + .setOkClient(getProxyClient(proxy)) .addAll(body) .addAllHeader(headerMap) .toByteArray().await() @@ -356,7 +356,7 @@ class AnalyzeUrl( } else -> RxHttp.get(url) .setAssemblyEnabled(false) - .setOkClient(OkHttpHelper.getProxyClient(proxy)) + .setOkClient(getProxyClient(proxy)) .addAllEncoded(fieldMap) .addAllHeader(headerMap) .toByteArray().await() From 251974976775dc0270b1284a9a800a298a45a83d Mon Sep 17 00:00:00 2001 From: gedoor Date: Mon, 3 May 2021 16:16:34 +0800 Subject: [PATCH 30/48] =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/java/io/legado/app/base/BaseActivity.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/java/io/legado/app/base/BaseActivity.kt b/app/src/main/java/io/legado/app/base/BaseActivity.kt index e89e47642..4d2707444 100644 --- a/app/src/main/java/io/legado/app/base/BaseActivity.kt +++ b/app/src/main/java/io/legado/app/base/BaseActivity.kt @@ -74,6 +74,7 @@ abstract class BaseActivity( * 添加高刷新率支持 */ // 获取系统window支持的模式 + @Suppress("DEPRECATION") val modes = window.windowManager.defaultDisplay.supportedModes // 对获取的模式,基于刷新率的大小进行排序,从小到大排序 modes.sortBy { From 32d1c079fb0f8b118eb96729b1beeb3ac81d5e75 Mon Sep 17 00:00:00 2001 From: gedoor Date: Mon, 3 May 2021 16:39:12 +0800 Subject: [PATCH 31/48] =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/java/io/legado/app/lib/webdav/WebDav.kt | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/io/legado/app/lib/webdav/WebDav.kt b/app/src/main/java/io/legado/app/lib/webdav/WebDav.kt index 1cc1220bc..030179674 100644 --- a/app/src/main/java/io/legado/app/lib/webdav/WebDav.kt +++ b/app/src/main/java/io/legado/app/lib/webdav/WebDav.kt @@ -21,8 +21,7 @@ class WebDav(urlStr: String) { companion object { // 指定返回哪些属性 private const val DIR = - """ - + """ @@ -32,8 +31,7 @@ class WebDav(urlStr: String) { %s - - """ + """ } private val url: URL = URL(urlStr) From 9069cbd35764106c0589a6b3be37bd192ff5906c Mon Sep 17 00:00:00 2001 From: gedoor Date: Mon, 3 May 2021 20:53:15 +0800 Subject: [PATCH 32/48] =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../io/legado/app/help/http/OkHttpHelper.kt | 14 +++- .../java/io/legado/app/lib/webdav/WebDav.kt | 64 +++++++++---------- .../association/ImportBookSourceViewModel.kt | 9 ++- .../association/ImportReplaceRuleViewModel.kt | 9 ++- .../association/ImportRssSourceViewModel.kt | 9 ++- .../ui/book/read/config/BgTextConfigDialog.kt | 8 ++- .../book/read/config/SpeakEngineViewModel.kt | 9 ++- .../ui/book/read/config/TocRegexViewModel.kt | 9 ++- .../ui/main/bookshelf/BookshelfViewModel.kt | 9 ++- .../app/ui/rss/read/ReadRssViewModel.kt | 8 ++- 10 files changed, 86 insertions(+), 62 deletions(-) diff --git a/app/src/main/java/io/legado/app/help/http/OkHttpHelper.kt b/app/src/main/java/io/legado/app/help/http/OkHttpHelper.kt index dccf75d6b..a45eb1914 100644 --- a/app/src/main/java/io/legado/app/help/http/OkHttpHelper.kt +++ b/app/src/main/java/io/legado/app/help/http/OkHttpHelper.kt @@ -1,5 +1,7 @@ package io.legado.app.help.http +import io.legado.app.constant.AppConst +import io.legado.app.help.AppConfig import io.legado.app.utils.EncodingDetect import io.legado.app.utils.UTF8BOMFighter import kotlinx.coroutines.suspendCancellableCoroutine @@ -92,9 +94,15 @@ fun getProxyClient(proxy: String? = null): OkHttpClient { return okHttpClient } -fun OkHttpClient.newCall(builder: Request.Builder.() -> Unit): Call { - val requestBuilder = Request.Builder().apply(builder) - return this.newCall(requestBuilder.build()) +suspend fun OkHttpClient.newCall(builder: Request.Builder.() -> Unit): ResponseBody { + val requestBuilder = Request.Builder() + requestBuilder.header(AppConst.UA_NAME, AppConfig.userAgent) + requestBuilder.apply(builder) + val response = this.newCall(requestBuilder.build()).await() + if (!response.isSuccessful) { + throw IOException("服务器没有响应。") + } + return response.body!! } suspend fun Call.await(): Response = suspendCancellableCoroutine { block -> diff --git a/app/src/main/java/io/legado/app/lib/webdav/WebDav.kt b/app/src/main/java/io/legado/app/lib/webdav/WebDav.kt index 030179674..36713320f 100644 --- a/app/src/main/java/io/legado/app/lib/webdav/WebDav.kt +++ b/app/src/main/java/io/legado/app/lib/webdav/WebDav.kt @@ -1,8 +1,8 @@ package io.legado.app.lib.webdav -import io.legado.app.help.http.await import io.legado.app.help.http.newCall import io.legado.app.help.http.okHttpClient +import io.legado.app.help.http.text import okhttp3.* import okhttp3.MediaType.Companion.toMediaType import okhttp3.RequestBody.Companion.asRequestBody @@ -58,16 +58,9 @@ class WebDav(urlStr: String) { * @return 远程文件是否存在 */ suspend fun indexFileInfo(): Boolean { - propFindResponse(ArrayList())?.let { response -> - if (!response.isSuccessful) { - this.exists = false - return false - } - response.body?.let { - @Suppress("BlockingMethodInNonBlockingContext") - if (it.string().isNotEmpty()) { - return true - } + propFindResponse(ArrayList())?.let { + if (it.text().isNotEmpty()) { + return true } } return false @@ -80,19 +73,13 @@ class WebDav(urlStr: String) { * @return 文件列表 */ suspend fun listFiles(propsList: ArrayList = ArrayList()): List { - propFindResponse(propsList)?.let { response -> - if (response.isSuccessful) { - response.body?.let { body -> - @Suppress("BlockingMethodInNonBlockingContext") - return parseDir(body.string()) - } - } + propFindResponse(propsList)?.text()?.let { body -> + return parseDir(body) } return ArrayList() } - @Throws(IOException::class) - private suspend fun propFindResponse(propsList: ArrayList): Response? { + private suspend fun propFindResponse(propsList: ArrayList): ResponseBody? { val requestProps = StringBuilder() for (p in propsList) { requestProps.append("\n") @@ -105,14 +92,18 @@ class WebDav(urlStr: String) { val url = httpUrl val auth = HttpAuth.auth if (url != null && auth != null) { - return okHttpClient.newCall { - url(url) - addHeader("Authorization", Credentials.basic(auth.user, auth.pass)) - // 添加RequestBody对象,可以只返回的属性。如果设为null,则会返回全部属性 - // 注意:尽量手动指定需要返回的属性。若返回全部属性,可能后由于Prop.java里没有该属性名,而崩溃。 - val requestBody = requestPropsStr.toRequestBody("text/plain".toMediaType()) - method("PROPFIND", requestBody) - }.await() + return kotlin.runCatching { + okHttpClient.newCall { + url(url) + addHeader("Authorization", Credentials.basic(auth.user, auth.pass)) + // 添加RequestBody对象,可以只返回的属性。如果设为null,则会返回全部属性 + // 注意:尽量手动指定需要返回的属性。若返回全部属性,可能后由于Prop.java里没有该属性名,而崩溃。 + val requestBody = requestPropsStr.toRequestBody("text/plain".toMediaType()) + method("PROPFIND", requestBody) + } + }.onFailure { + it.printStackTrace() + }.getOrNull() } return null } @@ -160,11 +151,12 @@ class WebDav(urlStr: String) { val url = httpUrl val auth = HttpAuth.auth if (url != null && auth != null) { - return okHttpClient.newCall { + okHttpClient.newCall { url(url) method("MKCOL", null) addHeader("Authorization", Credentials.basic(auth.user, auth.pass)) - }.await().isSuccessful + } + return true } return false } @@ -201,11 +193,12 @@ class WebDav(urlStr: String) { val url = httpUrl val auth = HttpAuth.auth if (url != null && auth != null) { - return okHttpClient.newCall { + okHttpClient.newCall { url(url) put(fileBody) addHeader("Authorization", Credentials.basic(auth.user, auth.pass)) - }.await().isSuccessful + } + return true } return false } @@ -216,11 +209,12 @@ class WebDav(urlStr: String) { val url = httpUrl val auth = HttpAuth.auth if (url != null && auth != null) { - return okHttpClient.newCall { + okHttpClient.newCall { url(url) put(fileBody) addHeader("Authorization", Credentials.basic(auth.user, auth.pass)) - }.await().isSuccessful + } + return true } return false } @@ -233,7 +227,7 @@ class WebDav(urlStr: String) { return okHttpClient.newCall { url(url) addHeader("Authorization", Credentials.basic(auth.user, auth.pass)) - }.await().body?.byteStream() + }.byteStream() } return null } diff --git a/app/src/main/java/io/legado/app/ui/association/ImportBookSourceViewModel.kt b/app/src/main/java/io/legado/app/ui/association/ImportBookSourceViewModel.kt index 7a08cacb1..a67c7e7f8 100644 --- a/app/src/main/java/io/legado/app/ui/association/ImportBookSourceViewModel.kt +++ b/app/src/main/java/io/legado/app/ui/association/ImportBookSourceViewModel.kt @@ -9,13 +9,14 @@ import io.legado.app.data.appDb import io.legado.app.data.entities.BookSource import io.legado.app.help.AppConfig import io.legado.app.help.SourceHelp +import io.legado.app.help.http.newCall +import io.legado.app.help.http.okHttpClient +import io.legado.app.help.http.text import io.legado.app.help.storage.OldRule import io.legado.app.help.storage.Restore import io.legado.app.utils.isAbsUrl import io.legado.app.utils.isJsonArray import io.legado.app.utils.isJsonObject -import rxhttp.wrapper.param.RxHttp -import rxhttp.wrapper.param.toText class ImportBookSourceViewModel(app: Application) : BaseViewModel(app) { var groupName: String? = null @@ -111,7 +112,9 @@ class ImportBookSourceViewModel(app: Application) : BaseViewModel(app) { } private suspend fun importSourceUrl(url: String) { - RxHttp.get(url).toText("utf-8").await().let { body -> + okHttpClient.newCall { + url(url) + }.text("utf-8").let { body -> val items: List> = Restore.jsonPath.parse(body).read("$") for (item in items) { val jsonItem = Restore.jsonPath.parse(item) diff --git a/app/src/main/java/io/legado/app/ui/association/ImportReplaceRuleViewModel.kt b/app/src/main/java/io/legado/app/ui/association/ImportReplaceRuleViewModel.kt index a9a937114..8d6da537e 100644 --- a/app/src/main/java/io/legado/app/ui/association/ImportReplaceRuleViewModel.kt +++ b/app/src/main/java/io/legado/app/ui/association/ImportReplaceRuleViewModel.kt @@ -4,10 +4,11 @@ import android.app.Application import androidx.lifecycle.MutableLiveData import io.legado.app.base.BaseViewModel import io.legado.app.data.entities.ReplaceRule +import io.legado.app.help.http.newCall +import io.legado.app.help.http.okHttpClient +import io.legado.app.help.http.text import io.legado.app.help.storage.OldReplace import io.legado.app.utils.isAbsUrl -import rxhttp.wrapper.param.RxHttp -import rxhttp.wrapper.param.toText class ImportReplaceRuleViewModel(app: Application) : BaseViewModel(app) { val errorLiveData = MutableLiveData() @@ -18,7 +19,9 @@ class ImportReplaceRuleViewModel(app: Application) : BaseViewModel(app) { fun import(text: String) { execute { if (text.isAbsUrl()) { - RxHttp.get(text).toText("utf-8").await().let { + okHttpClient.newCall { + url(text) + }.text("utf-8").let { val rules = OldReplace.jsonToReplaceRules(it) allRules.addAll(rules) } diff --git a/app/src/main/java/io/legado/app/ui/association/ImportRssSourceViewModel.kt b/app/src/main/java/io/legado/app/ui/association/ImportRssSourceViewModel.kt index 0db5f7af0..0658d5b5a 100644 --- a/app/src/main/java/io/legado/app/ui/association/ImportRssSourceViewModel.kt +++ b/app/src/main/java/io/legado/app/ui/association/ImportRssSourceViewModel.kt @@ -9,10 +9,11 @@ import io.legado.app.data.appDb import io.legado.app.data.entities.RssSource import io.legado.app.help.AppConfig import io.legado.app.help.SourceHelp +import io.legado.app.help.http.newCall +import io.legado.app.help.http.okHttpClient +import io.legado.app.help.http.text import io.legado.app.help.storage.Restore import io.legado.app.utils.* -import rxhttp.wrapper.param.RxHttp -import rxhttp.wrapper.param.toText class ImportRssSourceViewModel(app: Application) : BaseViewModel(app) { var groupName: String? = null @@ -106,7 +107,9 @@ class ImportRssSourceViewModel(app: Application) : BaseViewModel(app) { } private suspend fun importSourceUrl(url: String) { - RxHttp.get(url).toText("utf-8").await().let { body -> + okHttpClient.newCall { + url(url) + }.text("utf-8").let { body -> val items: List> = Restore.jsonPath.parse(body).read("$") for (item in items) { val jsonItem = Restore.jsonPath.parse(item) diff --git a/app/src/main/java/io/legado/app/ui/book/read/config/BgTextConfigDialog.kt b/app/src/main/java/io/legado/app/ui/book/read/config/BgTextConfigDialog.kt index 4a7b4cf96..170c51ab4 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/config/BgTextConfigDialog.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/config/BgTextConfigDialog.kt @@ -17,6 +17,8 @@ import io.legado.app.databinding.DialogReadBgTextBinding import io.legado.app.databinding.ItemBgImageBinding import io.legado.app.help.DefaultData import io.legado.app.help.ReadBookConfig +import io.legado.app.help.http.newCall +import io.legado.app.help.http.okHttpClient import io.legado.app.lib.dialogs.alert import io.legado.app.lib.dialogs.selector import io.legado.app.lib.permission.Permissions @@ -29,8 +31,6 @@ import io.legado.app.ui.document.FilePicker import io.legado.app.ui.document.FilePickerParam import io.legado.app.utils.* import io.legado.app.utils.viewbindingdelegate.viewBinding -import rxhttp.wrapper.param.RxHttp -import rxhttp.wrapper.param.toByteArray import java.io.File class BgTextConfigDialog : BaseDialogFragment() { @@ -308,7 +308,9 @@ class BgTextConfigDialog : BaseDialogFragment() { private fun importNetConfig(url: String) { execute { - RxHttp.get(url).toByteArray().await().let { + okHttpClient.newCall { + url(url) + }.bytes().let { importConfig(it) } }.onError { diff --git a/app/src/main/java/io/legado/app/ui/book/read/config/SpeakEngineViewModel.kt b/app/src/main/java/io/legado/app/ui/book/read/config/SpeakEngineViewModel.kt index c7eed9534..89246859e 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/config/SpeakEngineViewModel.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/config/SpeakEngineViewModel.kt @@ -6,9 +6,10 @@ import io.legado.app.base.BaseViewModel import io.legado.app.data.appDb import io.legado.app.data.entities.HttpTTS import io.legado.app.help.DefaultData +import io.legado.app.help.http.newCall +import io.legado.app.help.http.okHttpClient +import io.legado.app.help.http.text import io.legado.app.utils.* -import rxhttp.wrapper.param.RxHttp -import rxhttp.wrapper.param.toText class SpeakEngineViewModel(application: Application) : BaseViewModel(application) { @@ -20,7 +21,9 @@ class SpeakEngineViewModel(application: Application) : BaseViewModel(application fun importOnLine(url: String) { execute { - RxHttp.get(url).toText("utf-8").await().let { json -> + okHttpClient.newCall { + url(url) + }.text("utf-8").let { json -> import(json) } }.onSuccess { diff --git a/app/src/main/java/io/legado/app/ui/book/read/config/TocRegexViewModel.kt b/app/src/main/java/io/legado/app/ui/book/read/config/TocRegexViewModel.kt index 6494cf762..d1ce1ae26 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/config/TocRegexViewModel.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/config/TocRegexViewModel.kt @@ -5,10 +5,11 @@ import io.legado.app.base.BaseViewModel import io.legado.app.data.appDb import io.legado.app.data.entities.TxtTocRule import io.legado.app.help.DefaultData +import io.legado.app.help.http.newCall +import io.legado.app.help.http.okHttpClient +import io.legado.app.help.http.text import io.legado.app.utils.GSON import io.legado.app.utils.fromJsonArray -import rxhttp.wrapper.param.RxHttp -import rxhttp.wrapper.param.toText class TocRegexViewModel(application: Application) : BaseViewModel(application) { @@ -29,7 +30,9 @@ class TocRegexViewModel(application: Application) : BaseViewModel(application) { fun importOnLine(url: String, finally: (msg: String) -> Unit) { execute { - RxHttp.get(url).toText("utf-8").await().let { json -> + okHttpClient.newCall { + url(url) + }.text("utf-8").let { json -> GSON.fromJsonArray(json)?.let { appDb.txtTocRuleDao.insert(*it.toTypedArray()) } diff --git a/app/src/main/java/io/legado/app/ui/main/bookshelf/BookshelfViewModel.kt b/app/src/main/java/io/legado/app/ui/main/bookshelf/BookshelfViewModel.kt index 87f048fda..ac9f91190 100644 --- a/app/src/main/java/io/legado/app/ui/main/bookshelf/BookshelfViewModel.kt +++ b/app/src/main/java/io/legado/app/ui/main/bookshelf/BookshelfViewModel.kt @@ -7,13 +7,14 @@ import io.legado.app.data.appDb import io.legado.app.data.entities.Book import io.legado.app.data.entities.BookGroup import io.legado.app.data.entities.BookSource +import io.legado.app.help.http.newCall +import io.legado.app.help.http.okHttpClient +import io.legado.app.help.http.text import io.legado.app.model.webBook.PreciseSearch import io.legado.app.model.webBook.WebBook import io.legado.app.utils.* import kotlinx.coroutines.Dispatchers.IO import kotlinx.coroutines.isActive -import rxhttp.wrapper.param.RxHttp -import rxhttp.wrapper.param.toText class BookshelfViewModel(application: Application) : BaseViewModel(application) { @@ -87,7 +88,9 @@ class BookshelfViewModel(application: Application) : BaseViewModel(application) val text = str.trim() when { text.isAbsUrl() -> { - RxHttp.get(text).toText().await().let { + okHttpClient.newCall { + url(text) + }.text().let { importBookshelf(it, groupId) } } diff --git a/app/src/main/java/io/legado/app/ui/rss/read/ReadRssViewModel.kt b/app/src/main/java/io/legado/app/ui/rss/read/ReadRssViewModel.kt index a2faacfad..594a4a543 100644 --- a/app/src/main/java/io/legado/app/ui/rss/read/ReadRssViewModel.kt +++ b/app/src/main/java/io/legado/app/ui/rss/read/ReadRssViewModel.kt @@ -16,6 +16,8 @@ import io.legado.app.data.appDb import io.legado.app.data.entities.RssArticle import io.legado.app.data.entities.RssSource import io.legado.app.data.entities.RssStar +import io.legado.app.help.http.newCall +import io.legado.app.help.http.okHttpClient import io.legado.app.model.analyzeRule.AnalyzeUrl import io.legado.app.model.rss.Rss import io.legado.app.utils.DocumentUtils @@ -24,8 +26,6 @@ import io.legado.app.utils.isContentScheme import io.legado.app.utils.writeBytes import kotlinx.coroutines.Dispatchers.IO import kotlinx.coroutines.launch -import rxhttp.wrapper.param.RxHttp -import rxhttp.wrapper.param.toByteArray import java.io.File import java.util.* @@ -147,7 +147,9 @@ class ReadRssViewModel(application: Application) : BaseViewModel(application), private suspend fun webData2bitmap(data: String): ByteArray? { return if (URLUtil.isValidUrl(data)) { - RxHttp.get(data).toByteArray().await() + okHttpClient.newCall { + url(data) + }.bytes() } else { Base64.decode(data.split(",").toTypedArray()[1], Base64.DEFAULT) } From 272163ea7095dc3ceacbc3421542774a75dccfe3 Mon Sep 17 00:00:00 2001 From: gedoor Date: Mon, 3 May 2021 23:14:44 +0800 Subject: [PATCH 33/48] =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/io/legado/app/help/JsExtensions.kt | 8 +- .../io/legado/app/help/http/OkHttpHelper.kt | 45 +++++++++++ .../app/model/analyzeRule/AnalyzeUrl.kt | 78 +++++++------------ 3 files changed, 77 insertions(+), 54 deletions(-) diff --git a/app/src/main/java/io/legado/app/help/JsExtensions.kt b/app/src/main/java/io/legado/app/help/JsExtensions.kt index 64d8d0893..851660fdf 100644 --- a/app/src/main/java/io/legado/app/help/JsExtensions.kt +++ b/app/src/main/java/io/legado/app/help/JsExtensions.kt @@ -4,9 +4,7 @@ import android.net.Uri import android.util.Base64 import androidx.annotation.Keep import io.legado.app.constant.AppConst.dateFormat -import io.legado.app.help.http.CookieStore -import io.legado.app.help.http.SSLHelper -import io.legado.app.help.http.StrResponse +import io.legado.app.help.http.* import io.legado.app.model.Debug import io.legado.app.model.analyzeRule.AnalyzeUrl import io.legado.app.model.analyzeRule.QueryTTF @@ -16,8 +14,6 @@ import kotlinx.coroutines.async import kotlinx.coroutines.runBlocking import org.jsoup.Connection import org.jsoup.Jsoup -import rxhttp.wrapper.param.RxHttp -import rxhttp.wrapper.param.toByteArray import splitties.init.appCtx import java.io.File import java.net.URLEncoder @@ -292,7 +288,7 @@ interface JsExtensions { str.isAbsUrl() -> runBlocking { var x = CacheManager.getByteArray(key) if (x == null) { - x = RxHttp.get(str).toByteArray().await() + x = okHttpClient.newCall { url(str) }.bytes() x.let { CacheManager.put(key, it) } diff --git a/app/src/main/java/io/legado/app/help/http/OkHttpHelper.kt b/app/src/main/java/io/legado/app/help/http/OkHttpHelper.kt index a45eb1914..f1f015a15 100644 --- a/app/src/main/java/io/legado/app/help/http/OkHttpHelper.kt +++ b/app/src/main/java/io/legado/app/help/http/OkHttpHelper.kt @@ -6,6 +6,9 @@ import io.legado.app.utils.EncodingDetect import io.legado.app.utils.UTF8BOMFighter import kotlinx.coroutines.suspendCancellableCoroutine import okhttp3.* +import okhttp3.HttpUrl.Companion.toHttpUrl +import okhttp3.MediaType.Companion.toMediaType +import okhttp3.RequestBody.Companion.toRequestBody import java.io.IOException import java.net.InetSocketAddress import java.net.Proxy @@ -105,6 +108,17 @@ suspend fun OkHttpClient.newCall(builder: Request.Builder.() -> Unit): ResponseB return response.body!! } +suspend fun OkHttpClient.newCallStrResponse(builder: Request.Builder.() -> Unit): StrResponse { + val requestBuilder = Request.Builder() + requestBuilder.header(AppConst.UA_NAME, AppConfig.userAgent) + requestBuilder.apply(builder) + val response = this.newCall(requestBuilder.build()).await() + if (!response.isSuccessful) { + throw IOException("服务器没有响应。") + } + return StrResponse(response, response.body!!.text()) +} + suspend fun Call.await(): Response = suspendCancellableCoroutine { block -> block.invokeOnCancellation { @@ -139,4 +153,35 @@ fun ResponseBody.text(encode: String? = null): String { //根据内容判断 charsetName = EncodingDetect.getHtmlEncode(responseBytes) return String(responseBytes, Charset.forName(charsetName)) +} + +fun Request.Builder.get(url: String, queryMap: Map, encoded: Boolean = false) { + val httpBuilder = url.toHttpUrl().newBuilder() + queryMap.forEach { + if (encoded) { + httpBuilder.addEncodedQueryParameter(it.key, it.value) + } else { + httpBuilder.addQueryParameter(it.key, it.value) + } + } + url(httpBuilder.build()) +} + +fun Request.Builder.postForm(form: Map, encoded: Boolean = false) { + val formBody = FormBody.Builder() + form.forEach { + if (encoded) { + formBody.addEncoded(it.key, it.value) + } else { + formBody.add(it.key, it.value) + } + } + post(formBody.build()) +} + +fun Request.Builder.postJson(json: String?) { + json?.let { + val requestBody = json.toRequestBody("application/json; charset=UTF-8".toMediaType()) + post(requestBody) + } } \ No newline at end of file diff --git a/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeUrl.kt b/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeUrl.kt index d61ca7633..c341fb544 100644 --- a/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeUrl.kt +++ b/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeUrl.kt @@ -16,9 +16,6 @@ import io.legado.app.help.CacheManager import io.legado.app.help.JsExtensions import io.legado.app.help.http.* import io.legado.app.utils.* -import rxhttp.wrapper.param.RxHttp -import rxhttp.wrapper.param.toByteArray -import rxhttp.wrapper.param.toStrResponse import java.net.URLEncoder import java.util.* import java.util.regex.Pattern @@ -307,60 +304,45 @@ class AnalyzeUrl( params.tag = tag return HttpHelper.ajax(params) } - return when (method) { - RequestMethod.POST -> { - if (fieldMap.isNotEmpty() || body.isNullOrBlank()) { - RxHttp.postForm(url) - .setAssemblyEnabled(false) - .setOkClient(getProxyClient(proxy)) - .addAllEncoded(fieldMap) - .addAllHeader(headerMap) - .toStrResponse().await() - } else { - RxHttp.postJson(url) - .setAssemblyEnabled(false) - .setOkClient(getProxyClient(proxy)) - .addAll(body) - .addAllHeader(headerMap) - .toStrResponse().await() + return getProxyClient(proxy).newCallStrResponse { + removeHeader(UA_NAME) + headerMap.forEach { + addHeader(it.key, it.value) + } + when (method) { + RequestMethod.POST -> { + url(url) + if (fieldMap.isNotEmpty() || body.isNullOrBlank()) { + postForm(fieldMap, true) + } else { + postJson(body) + } } + else -> get(url, fieldMap, true) } - else -> RxHttp.get(url) - .setAssemblyEnabled(false) - .setOkClient(getProxyClient(proxy)) - .addAllEncoded(fieldMap) - .addAllHeader(headerMap) - .toStrResponse().await() } } suspend fun getByteArray(tag: String? = null): ByteArray { setCookie(tag) - return when (method) { - RequestMethod.POST -> { - if (fieldMap.isNotEmpty() || body.isNullOrBlank()) { - RxHttp.postForm(url) - .setAssemblyEnabled(false) - .setOkClient(getProxyClient(proxy)) - .addAllEncoded(fieldMap) - .addAllHeader(headerMap) - .toByteArray().await() - } else { - RxHttp.postJson(url) - .setAssemblyEnabled(false) - .setOkClient(getProxyClient(proxy)) - .addAll(body) - .addAllHeader(headerMap) - .toByteArray().await() + @Suppress("BlockingMethodInNonBlockingContext") + return getProxyClient(proxy).newCall { + removeHeader(UA_NAME) + headerMap.forEach { + addHeader(it.key, it.value) + } + when (method) { + RequestMethod.POST -> { + url(url) + if (fieldMap.isNotEmpty() || body.isNullOrBlank()) { + postForm(fieldMap, true) + } else { + postJson(body) + } } + else -> get(url, fieldMap, true) } - else -> RxHttp.get(url) - .setAssemblyEnabled(false) - .setOkClient(getProxyClient(proxy)) - .addAllEncoded(fieldMap) - .addAllHeader(headerMap) - .toByteArray().await() - } + }.bytes() } private fun setCookie(tag: String?) { From f91bc8722a690337bec5f04c745378c641494fa1 Mon Sep 17 00:00:00 2001 From: gedoor Date: Mon, 3 May 2021 23:32:03 +0800 Subject: [PATCH 34/48] =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/build.gradle | 2 -- app/src/main/java/io/legado/app/App.kt | 7 ------- .../legado/app/help/http/parser/ByteParser.kt | 13 ------------- .../app/help/http/parser/InputStreamParser.kt | 14 -------------- .../app/help/http/parser/StrResponseParser.kt | 19 ------------------- .../legado/app/help/http/parser/TextParser.kt | 17 ----------------- .../app/lib/permission/PermissionsCompat.kt | 5 ----- .../io/legado/app/lib/permission/Request.kt | 19 ++++++------------- .../legado/app/model/webBook/BookContent.kt | 5 ++++- 9 files changed, 10 insertions(+), 91 deletions(-) delete mode 100644 app/src/main/java/io/legado/app/help/http/parser/ByteParser.kt delete mode 100644 app/src/main/java/io/legado/app/help/http/parser/InputStreamParser.kt delete mode 100644 app/src/main/java/io/legado/app/help/http/parser/StrResponseParser.kt delete mode 100644 app/src/main/java/io/legado/app/help/http/parser/TextParser.kt diff --git a/app/build.gradle b/app/build.gradle index 267c0eb8b..0044c4aa3 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -179,8 +179,6 @@ dependencies { //网络 implementation 'com.squareup.okhttp3:okhttp:4.9.1' - implementation 'com.ljx.rxhttp:rxhttp:2.5.7' - kapt 'com.ljx.rxhttp:rxhttp-compiler:2.5.7' //Glide implementation 'com.github.bumptech.glide:glide:4.11.0' diff --git a/app/src/main/java/io/legado/app/App.kt b/app/src/main/java/io/legado/app/App.kt index b5edcd40f..5791d7007 100644 --- a/app/src/main/java/io/legado/app/App.kt +++ b/app/src/main/java/io/legado/app/App.kt @@ -7,7 +7,6 @@ import android.content.res.Configuration import android.os.Build import androidx.multidex.MultiDexApplication import com.jeremyliao.liveeventbus.LiveEventBus -import io.legado.app.constant.AppConst import io.legado.app.constant.AppConst.channelIdDownload import io.legado.app.constant.AppConst.channelIdReadAloud import io.legado.app.constant.AppConst.channelIdWeb @@ -15,10 +14,8 @@ import io.legado.app.help.ActivityHelp import io.legado.app.help.AppConfig import io.legado.app.help.CrashHandler import io.legado.app.help.ThemeConfig.applyDayNight -import io.legado.app.help.http.okHttpClient import io.legado.app.utils.LanguageUtils import io.legado.app.utils.defaultSharedPreferences -import rxhttp.wrapper.param.RxHttp class App : MultiDexApplication() { @@ -26,10 +23,6 @@ class App : MultiDexApplication() { super.onCreate() CrashHandler(this) LanguageUtils.setConfiguration(this) - RxHttp.init(okHttpClient, BuildConfig.DEBUG) - RxHttp.setOnParamAssembly { - it.addHeader(AppConst.UA_NAME, AppConfig.userAgent) - } createNotificationChannels() applyDayNight(this) LiveEventBus.config() diff --git a/app/src/main/java/io/legado/app/help/http/parser/ByteParser.kt b/app/src/main/java/io/legado/app/help/http/parser/ByteParser.kt deleted file mode 100644 index b2812d41e..000000000 --- a/app/src/main/java/io/legado/app/help/http/parser/ByteParser.kt +++ /dev/null @@ -1,13 +0,0 @@ -package io.legado.app.help.http.parser - -import okhttp3.Response -import rxhttp.wrapper.annotation.Parser - -@Parser(name = "ByteArray") -class ByteParser : rxhttp.wrapper.parse.Parser { - - override fun onParse(response: Response): ByteArray { - return response.body!!.bytes() - } - -} \ No newline at end of file diff --git a/app/src/main/java/io/legado/app/help/http/parser/InputStreamParser.kt b/app/src/main/java/io/legado/app/help/http/parser/InputStreamParser.kt deleted file mode 100644 index 9ca0ffe4d..000000000 --- a/app/src/main/java/io/legado/app/help/http/parser/InputStreamParser.kt +++ /dev/null @@ -1,14 +0,0 @@ -package io.legado.app.help.http.parser - -import okhttp3.Response -import rxhttp.wrapper.annotation.Parser -import java.io.InputStream - -@Parser(name = "InputStream") -class InputStreamParser : rxhttp.wrapper.parse.Parser { - - override fun onParse(response: Response): InputStream { - return response.body!!.byteStream() - } - -} \ No newline at end of file diff --git a/app/src/main/java/io/legado/app/help/http/parser/StrResponseParser.kt b/app/src/main/java/io/legado/app/help/http/parser/StrResponseParser.kt deleted file mode 100644 index a5c8cdbe5..000000000 --- a/app/src/main/java/io/legado/app/help/http/parser/StrResponseParser.kt +++ /dev/null @@ -1,19 +0,0 @@ -package io.legado.app.help.http.parser - -import io.legado.app.help.http.StrResponse -import io.legado.app.help.http.text -import okhttp3.Response -import rxhttp.wrapper.annotation.Parser -import rxhttp.wrapper.exception.HttpStatusCodeException - -@Parser(name = "StrResponse") -class StrResponseParser(private val encode: String? = null) : - rxhttp.wrapper.parse.Parser { - - override fun onParse(response: Response): StrResponse { - val body = response.body?.text(encode) - ?: throw HttpStatusCodeException(response, "内容为空") - return StrResponse(response, body) - } - -} \ No newline at end of file diff --git a/app/src/main/java/io/legado/app/help/http/parser/TextParser.kt b/app/src/main/java/io/legado/app/help/http/parser/TextParser.kt deleted file mode 100644 index 1d4c4ec93..000000000 --- a/app/src/main/java/io/legado/app/help/http/parser/TextParser.kt +++ /dev/null @@ -1,17 +0,0 @@ -package io.legado.app.help.http.parser - -import io.legado.app.help.http.text -import okhttp3.Response -import rxhttp.wrapper.annotation.Parser -import rxhttp.wrapper.exception.HttpStatusCodeException - -@Parser(name = "Text") -class TextParser(private val encode: String? = null) : rxhttp.wrapper.parse.Parser { - - override fun onParse(response: Response): String { - - val responseBody = response.body ?: throw HttpStatusCodeException(response, "内容为空") - return responseBody.text(encode) - } - -} \ No newline at end of file diff --git a/app/src/main/java/io/legado/app/lib/permission/PermissionsCompat.kt b/app/src/main/java/io/legado/app/lib/permission/PermissionsCompat.kt index a2d604c99..f127c77d6 100644 --- a/app/src/main/java/io/legado/app/lib/permission/PermissionsCompat.kt +++ b/app/src/main/java/io/legado/app/lib/permission/PermissionsCompat.kt @@ -29,11 +29,6 @@ class PermissionsCompat private constructor() { return this } - fun requestCode(requestCode: Int): Builder { - request.setRequestCode(requestCode) - return this - } - fun onGranted(callback: () -> Unit): Builder { request.setOnGrantedCallback(object : OnPermissionsGrantedCallback { override fun onPermissionsGranted() { diff --git a/app/src/main/java/io/legado/app/lib/permission/Request.kt b/app/src/main/java/io/legado/app/lib/permission/Request.kt index 2de60d059..a5f3acacd 100644 --- a/app/src/main/java/io/legado/app/lib/permission/Request.kt +++ b/app/src/main/java/io/legado/app/lib/permission/Request.kt @@ -46,10 +46,6 @@ internal class Request : OnRequestPermissionsResultCallback { this.permissions?.addAll(listOf(*permissions)) } - fun setRequestCode(requestCode: Int) { - this.requestCode = requestCode - } - fun setOnGrantedCallback(callback: OnPermissionsGrantedCallback) { grantedCallback = callback } @@ -81,13 +77,10 @@ internal class Request : OnRequestPermissionsResultCallback { if (rationaleResId != 0) source?.context?.getText(rationaleResId) else rationale if (rationale != null) { showSettingDialog(rationale) { - onPermissionsDenied( - requestCode, - deniedPermissions - ) + onPermissionsDenied(deniedPermissions) } } else { - onPermissionsDenied(requestCode, deniedPermissions) + onPermissionsDenied(deniedPermissions) } } } else { @@ -160,7 +153,7 @@ internal class Request : OnRequestPermissionsResultCallback { RequestPlugins.sResultCallback?.onPermissionsGranted() } - private fun onPermissionsDenied(requestCode: Int, deniedPermissions: Array) { + private fun onPermissionsDenied(deniedPermissions: Array) { try { deniedCallback?.onPermissionsDenied(deniedPermissions) } catch (ignore: Exception) { @@ -178,9 +171,9 @@ internal class Request : OnRequestPermissionsResultCallback { val rationale = if (rationaleResId != 0) source?.context?.getText(rationaleResId) else rationale if (rationale != null) { - showSettingDialog(rationale) { onPermissionsDenied(requestCode, deniedPermissions) } + showSettingDialog(rationale) { onPermissionsDenied(deniedPermissions) } } else { - onPermissionsDenied(requestCode, deniedPermissions) + onPermissionsDenied(deniedPermissions) } } else { onPermissionsGranted() @@ -192,7 +185,7 @@ internal class Request : OnRequestPermissionsResultCallback { if (deniedPermissions == null) { onPermissionsGranted() } else { - onPermissionsDenied(this.requestCode, deniedPermissions) + onPermissionsDenied(deniedPermissions) } } diff --git a/app/src/main/java/io/legado/app/model/webBook/BookContent.kt b/app/src/main/java/io/legado/app/model/webBook/BookContent.kt index 1e55b9e8a..e6984a548 100644 --- a/app/src/main/java/io/legado/app/model/webBook/BookContent.kt +++ b/app/src/main/java/io/legado/app/model/webBook/BookContent.kt @@ -15,6 +15,7 @@ import io.legado.app.utils.NetworkUtils import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers.IO import kotlinx.coroutines.async +import kotlinx.coroutines.ensureActive import kotlinx.coroutines.withContext import splitties.init.appCtx @@ -47,11 +48,11 @@ object BookContent { val analyzeRule = AnalyzeRule(book).setContent(body, baseUrl) analyzeRule.setRedirectUrl(baseUrl) analyzeRule.nextChapterUrl = mNextChapterUrl + scope.ensureActive() var contentData = analyzeContent( book, baseUrl, redirectUrl, body, contentRule, bookChapter, bookSource, mNextChapterUrl ) content.append(contentData.content).append("\n") - if (contentData.nextUrl.size == 1) { var nextUrl = contentData.nextUrl[0] while (nextUrl.isNotEmpty() && !nextUrlList.contains(nextUrl)) { @@ -60,6 +61,7 @@ object BookContent { == NetworkUtils.getAbsoluteURL(baseUrl, mNextChapterUrl) ) break nextUrlList.add(nextUrl) + scope.ensureActive() val res = AnalyzeUrl( ruleUrl = nextUrl, book = book, @@ -95,6 +97,7 @@ object BookContent { } } asyncArray.forEach { coroutine -> + scope.ensureActive() content.append(coroutine.await()).append("\n") } } From a45b5844abf8d12596a7ecfb84dd567c5f43313c Mon Sep 17 00:00:00 2001 From: gedoor Date: Tue, 4 May 2021 09:27:17 +0800 Subject: [PATCH 35/48] =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../io/legado/app/help/http/HttpHelper.kt | 119 +++++++++-- .../io/legado/app/help/http/OkHttpHelper.kt | 187 ------------------ .../io/legado/app/help/http/OkHttpUtils.kt | 114 +++++++++++ .../app/model/analyzeRule/AnalyzeUrl.kt | 2 +- 4 files changed, 215 insertions(+), 207 deletions(-) delete mode 100644 app/src/main/java/io/legado/app/help/http/OkHttpHelper.kt create mode 100644 app/src/main/java/io/legado/app/help/http/OkHttpUtils.kt diff --git a/app/src/main/java/io/legado/app/help/http/HttpHelper.kt b/app/src/main/java/io/legado/app/help/http/HttpHelper.kt index f87085a9c..cdf6a03bc 100644 --- a/app/src/main/java/io/legado/app/help/http/HttpHelper.kt +++ b/app/src/main/java/io/legado/app/help/http/HttpHelper.kt @@ -1,30 +1,111 @@ package io.legado.app.help.http import kotlinx.coroutines.suspendCancellableCoroutine +import okhttp3.ConnectionSpec +import okhttp3.Credentials +import okhttp3.Interceptor +import okhttp3.OkHttpClient +import java.net.InetSocketAddress +import java.net.Proxy +import java.util.concurrent.ConcurrentHashMap +import java.util.concurrent.TimeUnit import kotlin.coroutines.resume -@Suppress("unused") -object HttpHelper { +private val proxyClientCache: ConcurrentHashMap by lazy { + ConcurrentHashMap() +} - suspend fun ajax(params: AjaxWebView.AjaxParams): StrResponse = - suspendCancellableCoroutine { block -> - val webView = AjaxWebView() - block.invokeOnCancellation { - webView.destroyWebView() - } - webView.callback = object : AjaxWebView.Callback() { - override fun onResult(response: StrResponse) { +val okHttpClient: OkHttpClient by lazy { + val specs = arrayListOf( + ConnectionSpec.MODERN_TLS, + ConnectionSpec.COMPATIBLE_TLS, + ConnectionSpec.CLEARTEXT + ) - if (!block.isCompleted) - block.resume(response) - } + val builder = OkHttpClient.Builder() + .connectTimeout(15, TimeUnit.SECONDS) + .writeTimeout(15, TimeUnit.SECONDS) + .readTimeout(15, TimeUnit.SECONDS) + .sslSocketFactory(SSLHelper.unsafeSSLSocketFactory, SSLHelper.unsafeTrustManager) + .retryOnConnectionFailure(true) + .hostnameVerifier(SSLHelper.unsafeHostnameVerifier) + .connectionSpecs(specs) + .followRedirects(true) + .followSslRedirects(true) + .addInterceptor(Interceptor { chain -> + val request = chain.request() + .newBuilder() + .addHeader("Keep-Alive", "300") + .addHeader("Connection", "Keep-Alive") + .addHeader("Cache-Control", "no-cache") + .build() + chain.proceed(request) + }) + + builder.build() +} - override fun onError(error: Throwable) { - if (!block.isCompleted) - block.cancel(error) - } +/** + * 缓存代理okHttp + */ +fun getProxyClient(proxy: String? = null): OkHttpClient { + if (proxy.isNullOrBlank()) { + return okHttpClient + } + proxyClientCache[proxy]?.let { + return it + } + val r = Regex("(http|socks4|socks5)://(.*):(\\d{2,5})(@.*@.*)?") + val ms = r.findAll(proxy) + val group = ms.first() + var username = "" //代理服务器验证用户名 + var password = "" //代理服务器验证密码 + val type = if (group.groupValues[1] == "http") "http" else "socks" + val host = group.groupValues[2] + val port = group.groupValues[3].toInt() + if (group.groupValues[4] != "") { + username = group.groupValues[4].split("@")[1] + password = group.groupValues[4].split("@")[2] + } + if (type != "direct" && host != "") { + val builder = okHttpClient.newBuilder() + if (type == "http") { + builder.proxy(Proxy(Proxy.Type.HTTP, InetSocketAddress(host, port))) + } else { + builder.proxy(Proxy(Proxy.Type.SOCKS, InetSocketAddress(host, port))) + } + if (username != "" && password != "") { + builder.proxyAuthenticator { _, response -> //设置代理服务器账号密码 + val credential: String = Credentials.basic(username, password) + response.request.newBuilder() + .header("Proxy-Authorization", credential) + .build() } - webView.load(params) } - + val proxyClient = builder.build() + proxyClientCache[proxy] = proxyClient + return proxyClient + } + return okHttpClient } + +suspend fun getWebViewSrc(params: AjaxWebView.AjaxParams): StrResponse = + suspendCancellableCoroutine { block -> + val webView = AjaxWebView() + block.invokeOnCancellation { + webView.destroyWebView() + } + webView.callback = object : AjaxWebView.Callback() { + override fun onResult(response: StrResponse) { + + if (!block.isCompleted) + block.resume(response) + } + + override fun onError(error: Throwable) { + if (!block.isCompleted) + block.cancel(error) + } + } + webView.load(params) + } \ No newline at end of file diff --git a/app/src/main/java/io/legado/app/help/http/OkHttpHelper.kt b/app/src/main/java/io/legado/app/help/http/OkHttpHelper.kt deleted file mode 100644 index f1f015a15..000000000 --- a/app/src/main/java/io/legado/app/help/http/OkHttpHelper.kt +++ /dev/null @@ -1,187 +0,0 @@ -package io.legado.app.help.http - -import io.legado.app.constant.AppConst -import io.legado.app.help.AppConfig -import io.legado.app.utils.EncodingDetect -import io.legado.app.utils.UTF8BOMFighter -import kotlinx.coroutines.suspendCancellableCoroutine -import okhttp3.* -import okhttp3.HttpUrl.Companion.toHttpUrl -import okhttp3.MediaType.Companion.toMediaType -import okhttp3.RequestBody.Companion.toRequestBody -import java.io.IOException -import java.net.InetSocketAddress -import java.net.Proxy -import java.nio.charset.Charset -import java.util.concurrent.ConcurrentHashMap -import java.util.concurrent.TimeUnit -import kotlin.coroutines.resume -import kotlin.coroutines.resumeWithException - -private val proxyClientCache: ConcurrentHashMap by lazy { - ConcurrentHashMap() -} - -val okHttpClient: OkHttpClient by lazy { - - val specs = arrayListOf( - ConnectionSpec.MODERN_TLS, - ConnectionSpec.COMPATIBLE_TLS, - ConnectionSpec.CLEARTEXT - ) - - val builder = OkHttpClient.Builder() - .connectTimeout(15, TimeUnit.SECONDS) - .writeTimeout(15, TimeUnit.SECONDS) - .readTimeout(15, TimeUnit.SECONDS) - .sslSocketFactory(SSLHelper.unsafeSSLSocketFactory, SSLHelper.unsafeTrustManager) - .retryOnConnectionFailure(true) - .hostnameVerifier(SSLHelper.unsafeHostnameVerifier) - .connectionSpecs(specs) - .followRedirects(true) - .followSslRedirects(true) - .addInterceptor(Interceptor { chain -> - val request = chain.request() - .newBuilder() - .addHeader("Keep-Alive", "300") - .addHeader("Connection", "Keep-Alive") - .addHeader("Cache-Control", "no-cache") - .build() - chain.proceed(request) - }) - - builder.build() -} - -/** - * 缓存代理okHttp - */ -fun getProxyClient(proxy: String? = null): OkHttpClient { - if (proxy.isNullOrBlank()) { - return okHttpClient - } - proxyClientCache[proxy]?.let { - return it - } - val r = Regex("(http|socks4|socks5)://(.*):(\\d{2,5})(@.*@.*)?") - val ms = r.findAll(proxy) - val group = ms.first() - var username = "" //代理服务器验证用户名 - var password = "" //代理服务器验证密码 - val type = if (group.groupValues[1] == "http") "http" else "socks" - val host = group.groupValues[2] - val port = group.groupValues[3].toInt() - if (group.groupValues[4] != "") { - username = group.groupValues[4].split("@")[1] - password = group.groupValues[4].split("@")[2] - } - if (type != "direct" && host != "") { - val builder = okHttpClient.newBuilder() - if (type == "http") { - builder.proxy(Proxy(Proxy.Type.HTTP, InetSocketAddress(host, port))) - } else { - builder.proxy(Proxy(Proxy.Type.SOCKS, InetSocketAddress(host, port))) - } - if (username != "" && password != "") { - builder.proxyAuthenticator { _, response -> //设置代理服务器账号密码 - val credential: String = Credentials.basic(username, password) - response.request.newBuilder() - .header("Proxy-Authorization", credential) - .build() - } - } - val proxyClient = builder.build() - proxyClientCache[proxy] = proxyClient - return proxyClient - } - return okHttpClient -} - -suspend fun OkHttpClient.newCall(builder: Request.Builder.() -> Unit): ResponseBody { - val requestBuilder = Request.Builder() - requestBuilder.header(AppConst.UA_NAME, AppConfig.userAgent) - requestBuilder.apply(builder) - val response = this.newCall(requestBuilder.build()).await() - if (!response.isSuccessful) { - throw IOException("服务器没有响应。") - } - return response.body!! -} - -suspend fun OkHttpClient.newCallStrResponse(builder: Request.Builder.() -> Unit): StrResponse { - val requestBuilder = Request.Builder() - requestBuilder.header(AppConst.UA_NAME, AppConfig.userAgent) - requestBuilder.apply(builder) - val response = this.newCall(requestBuilder.build()).await() - if (!response.isSuccessful) { - throw IOException("服务器没有响应。") - } - return StrResponse(response, response.body!!.text()) -} - -suspend fun Call.await(): Response = suspendCancellableCoroutine { block -> - - block.invokeOnCancellation { - cancel() - } - - enqueue(object : Callback { - override fun onFailure(call: Call, e: IOException) { - block.resumeWithException(e) - } - - override fun onResponse(call: Call, response: Response) { - block.resume(response) - } - }) - -} - -fun ResponseBody.text(encode: String? = null): String { - val responseBytes = UTF8BOMFighter.removeUTF8BOM(bytes()) - var charsetName: String? = encode - - charsetName?.let { - return String(responseBytes, Charset.forName(charsetName)) - } - - //根据http头判断 - contentType()?.charset()?.let { - return String(responseBytes, it) - } - - //根据内容判断 - charsetName = EncodingDetect.getHtmlEncode(responseBytes) - return String(responseBytes, Charset.forName(charsetName)) -} - -fun Request.Builder.get(url: String, queryMap: Map, encoded: Boolean = false) { - val httpBuilder = url.toHttpUrl().newBuilder() - queryMap.forEach { - if (encoded) { - httpBuilder.addEncodedQueryParameter(it.key, it.value) - } else { - httpBuilder.addQueryParameter(it.key, it.value) - } - } - url(httpBuilder.build()) -} - -fun Request.Builder.postForm(form: Map, encoded: Boolean = false) { - val formBody = FormBody.Builder() - form.forEach { - if (encoded) { - formBody.addEncoded(it.key, it.value) - } else { - formBody.add(it.key, it.value) - } - } - post(formBody.build()) -} - -fun Request.Builder.postJson(json: String?) { - json?.let { - val requestBody = json.toRequestBody("application/json; charset=UTF-8".toMediaType()) - post(requestBody) - } -} \ No newline at end of file diff --git a/app/src/main/java/io/legado/app/help/http/OkHttpUtils.kt b/app/src/main/java/io/legado/app/help/http/OkHttpUtils.kt new file mode 100644 index 000000000..d958fc5a2 --- /dev/null +++ b/app/src/main/java/io/legado/app/help/http/OkHttpUtils.kt @@ -0,0 +1,114 @@ +package io.legado.app.help.http + +import io.legado.app.constant.AppConst +import io.legado.app.help.AppConfig +import io.legado.app.utils.EncodingDetect +import io.legado.app.utils.UTF8BOMFighter +import kotlinx.coroutines.suspendCancellableCoroutine +import okhttp3.* +import okhttp3.HttpUrl.Companion.toHttpUrl +import okhttp3.MediaType.Companion.toMediaType +import okhttp3.RequestBody.Companion.toRequestBody +import java.io.IOException +import java.nio.charset.Charset +import kotlin.coroutines.resume +import kotlin.coroutines.resumeWithException + +suspend fun OkHttpClient.newCall( + retry: Int = 0, + builder: Request.Builder.() -> Unit +): ResponseBody { + val requestBuilder = Request.Builder() + requestBuilder.header(AppConst.UA_NAME, AppConfig.userAgent) + requestBuilder.apply(builder) + for (i in 0..retry) { + val response = this.newCall(requestBuilder.build()).await() + if (response.isSuccessful) { + return response.body!! + } + } + throw IOException("服务器没有响应。") +} + +suspend fun OkHttpClient.newCallStrResponse( + retry: Int = 0, + builder: Request.Builder.() -> Unit +): StrResponse { + val requestBuilder = Request.Builder() + requestBuilder.header(AppConst.UA_NAME, AppConfig.userAgent) + requestBuilder.apply(builder) + for (i in 0..retry) { + val response = this.newCall(requestBuilder.build()).await() + if (response.isSuccessful) { + return StrResponse(response, response.body!!.text()) + } + } + throw IOException("服务器没有响应。") +} + +suspend fun Call.await(): Response = suspendCancellableCoroutine { block -> + + block.invokeOnCancellation { + cancel() + } + + enqueue(object : Callback { + override fun onFailure(call: Call, e: IOException) { + block.resumeWithException(e) + } + + override fun onResponse(call: Call, response: Response) { + block.resume(response) + } + }) + +} + +fun ResponseBody.text(encode: String? = null): String { + val responseBytes = UTF8BOMFighter.removeUTF8BOM(bytes()) + var charsetName: String? = encode + + charsetName?.let { + return String(responseBytes, Charset.forName(charsetName)) + } + + //根据http头判断 + contentType()?.charset()?.let { + return String(responseBytes, it) + } + + //根据内容判断 + charsetName = EncodingDetect.getHtmlEncode(responseBytes) + return String(responseBytes, Charset.forName(charsetName)) +} + +fun Request.Builder.get(url: String, queryMap: Map, encoded: Boolean = false) { + val httpBuilder = url.toHttpUrl().newBuilder() + queryMap.forEach { + if (encoded) { + httpBuilder.addEncodedQueryParameter(it.key, it.value) + } else { + httpBuilder.addQueryParameter(it.key, it.value) + } + } + url(httpBuilder.build()) +} + +fun Request.Builder.postForm(form: Map, encoded: Boolean = false) { + val formBody = FormBody.Builder() + form.forEach { + if (encoded) { + formBody.addEncoded(it.key, it.value) + } else { + formBody.add(it.key, it.value) + } + } + post(formBody.build()) +} + +fun Request.Builder.postJson(json: String?) { + json?.let { + val requestBody = json.toRequestBody("application/json; charset=UTF-8".toMediaType()) + post(requestBody) + } +} \ No newline at end of file diff --git a/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeUrl.kt b/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeUrl.kt index c341fb544..eb4230e1a 100644 --- a/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeUrl.kt +++ b/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeUrl.kt @@ -302,7 +302,7 @@ class AnalyzeUrl( params.sourceRegex = sourceRegex params.postData = body?.toByteArray() params.tag = tag - return HttpHelper.ajax(params) + return getWebViewSrc(params) } return getProxyClient(proxy).newCallStrResponse { removeHeader(UA_NAME) From f96c0a217c876f439e3e7e63228988160d481898 Mon Sep 17 00:00:00 2001 From: gedoor Date: Tue, 4 May 2021 10:02:23 +0800 Subject: [PATCH 36/48] =?UTF-8?q?url=E5=8F=82=E6=95=B0=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E9=87=8D=E8=AF=95=E6=AC=A1=E6=95=B0retry?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/io/legado/app/model/analyzeRule/AnalyzeUrl.kt | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeUrl.kt b/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeUrl.kt index eb4230e1a..088090555 100644 --- a/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeUrl.kt +++ b/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeUrl.kt @@ -55,6 +55,7 @@ class AnalyzeUrl( private var charset: String? = null private var method = RequestMethod.GET private var proxy: String? = null + private var retry: Int = 0 init { baseUrl = baseUrl.split(splitUrlRegex, 1)[0] @@ -197,6 +198,7 @@ class AnalyzeUrl( option.js?.let { evalJS(it) } + retry = option.retry } } headerMap[UA_NAME] ?: let { @@ -304,7 +306,7 @@ class AnalyzeUrl( params.tag = tag return getWebViewSrc(params) } - return getProxyClient(proxy).newCallStrResponse { + return getProxyClient(proxy).newCallStrResponse(retry) { removeHeader(UA_NAME) headerMap.forEach { addHeader(it.key, it.value) @@ -326,7 +328,7 @@ class AnalyzeUrl( suspend fun getByteArray(tag: String? = null): ByteArray { setCookie(tag) @Suppress("BlockingMethodInNonBlockingContext") - return getProxyClient(proxy).newCall { + return getProxyClient(proxy).newCall(retry) { removeHeader(UA_NAME) headerMap.forEach { addHeader(it.key, it.value) @@ -375,7 +377,8 @@ class AnalyzeUrl( val headers: Any?, val body: Any?, val type: String?, - val js: String? + val js: String?, + val retry: Int = 0 ) } From dd4192b3d677ce324fc08cef48d634afc0a79233 Mon Sep 17 00:00:00 2001 From: gedoor Date: Tue, 4 May 2021 10:03:56 +0800 Subject: [PATCH 37/48] =?UTF-8?q?url=E5=8F=82=E6=95=B0=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E9=87=8D=E8=AF=95=E6=AC=A1=E6=95=B0retry?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/assets/updateLog.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/src/main/assets/updateLog.md b/app/src/main/assets/updateLog.md index 8832f1657..8130b998b 100644 --- a/app/src/main/assets/updateLog.md +++ b/app/src/main/assets/updateLog.md @@ -3,6 +3,10 @@ * 关注合作公众号 **[小说拾遗]** 获取好看的小说。 * 旧版数据导入教程:先在旧版阅读(2.x)中进行备份,然后在新版阅读(3.x)【我的】->【备份与恢复】,选择【导入旧版本数据】。 +**2021/05/04** +* 修复bug +* url参数添加重置次数,retry + **2021/04/30** * epub插图,epublib优化,图片解码优化,epub读取导出优化。by ag2s20150909 * 添加高刷设置 From af769120da9e56933ee81b3af330c7e174deef5c Mon Sep 17 00:00:00 2001 From: gedoor Date: Tue, 4 May 2021 10:57:15 +0800 Subject: [PATCH 38/48] =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/java/io/legado/app/help/http/OkHttpUtils.kt | 6 ++++++ .../java/io/legado/app/model/analyzeRule/AnalyzeUrl.kt | 8 ++------ 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/app/src/main/java/io/legado/app/help/http/OkHttpUtils.kt b/app/src/main/java/io/legado/app/help/http/OkHttpUtils.kt index d958fc5a2..3b15acf5d 100644 --- a/app/src/main/java/io/legado/app/help/http/OkHttpUtils.kt +++ b/app/src/main/java/io/legado/app/help/http/OkHttpUtils.kt @@ -82,6 +82,12 @@ fun ResponseBody.text(encode: String? = null): String { return String(responseBytes, Charset.forName(charsetName)) } +fun Request.Builder.addHeaders(headers: Map) { + headers.forEach { + addHeader(it.key, it.value) + } +} + fun Request.Builder.get(url: String, queryMap: Map, encoded: Boolean = false) { val httpBuilder = url.toHttpUrl().newBuilder() queryMap.forEach { diff --git a/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeUrl.kt b/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeUrl.kt index 088090555..73e90e782 100644 --- a/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeUrl.kt +++ b/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeUrl.kt @@ -308,9 +308,7 @@ class AnalyzeUrl( } return getProxyClient(proxy).newCallStrResponse(retry) { removeHeader(UA_NAME) - headerMap.forEach { - addHeader(it.key, it.value) - } + addHeaders(headerMap) when (method) { RequestMethod.POST -> { url(url) @@ -330,9 +328,7 @@ class AnalyzeUrl( @Suppress("BlockingMethodInNonBlockingContext") return getProxyClient(proxy).newCall(retry) { removeHeader(UA_NAME) - headerMap.forEach { - addHeader(it.key, it.value) - } + addHeaders(headerMap) when (method) { RequestMethod.POST -> { url(url) From 0fb04f1547331e74d9a6646f9b601286d57a926c Mon Sep 17 00:00:00 2001 From: gedoor Date: Tue, 4 May 2021 13:11:44 +0800 Subject: [PATCH 39/48] =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/io/legado/app/ui/document/FilePickerActivity.kt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/src/main/java/io/legado/app/ui/document/FilePickerActivity.kt b/app/src/main/java/io/legado/app/ui/document/FilePickerActivity.kt index c3f601271..17a11d799 100644 --- a/app/src/main/java/io/legado/app/ui/document/FilePickerActivity.kt +++ b/app/src/main/java/io/legado/app/ui/document/FilePickerActivity.kt @@ -23,6 +23,7 @@ class FilePickerActivity : private val selectDocTree = registerForActivityResult(ActivityResultContracts.OpenDocumentTree()) { + it ?: return@registerForActivityResult if (it.isContentScheme()) { contentResolver.takePersistableUriPermission( it, @@ -33,6 +34,7 @@ class FilePickerActivity : } private val selectDoc = registerForActivityResult(ActivityResultContracts.OpenDocument()) { + it ?: return@registerForActivityResult onResult(Intent().setData(it)) } From 178e3712d379fe6e451a3ab047797c6b66af4a55 Mon Sep 17 00:00:00 2001 From: gedoor Date: Tue, 4 May 2021 13:18:14 +0800 Subject: [PATCH 40/48] =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/io/legado/app/help/http/OkHttpUtils.kt | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/io/legado/app/help/http/OkHttpUtils.kt b/app/src/main/java/io/legado/app/help/http/OkHttpUtils.kt index 3b15acf5d..b0bcfef18 100644 --- a/app/src/main/java/io/legado/app/help/http/OkHttpUtils.kt +++ b/app/src/main/java/io/legado/app/help/http/OkHttpUtils.kt @@ -21,13 +21,14 @@ suspend fun OkHttpClient.newCall( val requestBuilder = Request.Builder() requestBuilder.header(AppConst.UA_NAME, AppConfig.userAgent) requestBuilder.apply(builder) + var response: Response? = null for (i in 0..retry) { - val response = this.newCall(requestBuilder.build()).await() + response = this.newCall(requestBuilder.build()).await() if (response.isSuccessful) { return response.body!! } } - throw IOException("服务器没有响应。") + throw IOException(response?.message ?: "服务器没有响应。") } suspend fun OkHttpClient.newCallStrResponse( @@ -37,13 +38,14 @@ suspend fun OkHttpClient.newCallStrResponse( val requestBuilder = Request.Builder() requestBuilder.header(AppConst.UA_NAME, AppConfig.userAgent) requestBuilder.apply(builder) + var response: Response? = null for (i in 0..retry) { - val response = this.newCall(requestBuilder.build()).await() + response = this.newCall(requestBuilder.build()).await() if (response.isSuccessful) { return StrResponse(response, response.body!!.text()) } } - throw IOException("服务器没有响应。") + throw IOException(response?.message ?: "服务器没有响应。") } suspend fun Call.await(): Response = suspendCancellableCoroutine { block -> From c5b47dd555f26fea5f7242b81d9de2c2a065fa76 Mon Sep 17 00:00:00 2001 From: gedoor Date: Tue, 4 May 2021 14:15:25 +0800 Subject: [PATCH 41/48] =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/java/io/legado/app/help/http/OkHttpUtils.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/io/legado/app/help/http/OkHttpUtils.kt b/app/src/main/java/io/legado/app/help/http/OkHttpUtils.kt index b0bcfef18..4dec4bf3e 100644 --- a/app/src/main/java/io/legado/app/help/http/OkHttpUtils.kt +++ b/app/src/main/java/io/legado/app/help/http/OkHttpUtils.kt @@ -28,7 +28,7 @@ suspend fun OkHttpClient.newCall( return response.body!! } } - throw IOException(response?.message ?: "服务器没有响应。") + throw IOException(response!!.message) } suspend fun OkHttpClient.newCallStrResponse( @@ -45,7 +45,7 @@ suspend fun OkHttpClient.newCallStrResponse( return StrResponse(response, response.body!!.text()) } } - throw IOException(response?.message ?: "服务器没有响应。") + throw IOException(response!!.message) } suspend fun Call.await(): Response = suspendCancellableCoroutine { block -> From 89e89762177e1a393c224fce615f106462544351 Mon Sep 17 00:00:00 2001 From: gedoor Date: Tue, 4 May 2021 19:11:19 +0800 Subject: [PATCH 42/48] =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../app/ui/association/FileAssociationActivity.kt | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/app/src/main/java/io/legado/app/ui/association/FileAssociationActivity.kt b/app/src/main/java/io/legado/app/ui/association/FileAssociationActivity.kt index 67aec440f..8401830c6 100644 --- a/app/src/main/java/io/legado/app/ui/association/FileAssociationActivity.kt +++ b/app/src/main/java/io/legado/app/ui/association/FileAssociationActivity.kt @@ -1,14 +1,10 @@ package io.legado.app.ui.association -import android.content.Intent import android.os.Bundle import androidx.activity.viewModels import io.legado.app.base.VMBaseActivity import io.legado.app.constant.Theme import io.legado.app.databinding.ActivityTranslucenceBinding -import io.legado.app.ui.main.MainActivity -import io.legado.app.utils.startActivity - import io.legado.app.utils.toastOnUi class FileAssociationActivity : @@ -39,14 +35,4 @@ class FileAssociationActivity : } } - override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { - super.onActivityResult(requestCode, resultCode, data) - finish() - //返回后直接跳转到主页面 - gotoMainActivity() - } - - private fun gotoMainActivity() { - startActivity() - } } From cd3f352c9295c75cce44c80500634f8da7fa80fd Mon Sep 17 00:00:00 2001 From: gedoor Date: Tue, 4 May 2021 19:29:44 +0800 Subject: [PATCH 43/48] =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/java/io/legado/app/ui/book/read/ReadBookActivity.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/java/io/legado/app/ui/book/read/ReadBookActivity.kt b/app/src/main/java/io/legado/app/ui/book/read/ReadBookActivity.kt index 159cced9d..d8d98c9ed 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/ReadBookActivity.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/ReadBookActivity.kt @@ -80,6 +80,7 @@ class ReadBookActivity : ReadBookBaseActivity(), } private val sourceEditActivity = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { + it ?: return@registerForActivityResult if (it.resultCode == RESULT_OK) { viewModel.upBookSource { upView() From 53d51c8123144ef3f65331652906229973c1e985 Mon Sep 17 00:00:00 2001 From: gedoor Date: Tue, 4 May 2021 19:31:01 +0800 Subject: [PATCH 44/48] =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/io/legado/app/ui/book/read/ReadBookActivity.kt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/src/main/java/io/legado/app/ui/book/read/ReadBookActivity.kt b/app/src/main/java/io/legado/app/ui/book/read/ReadBookActivity.kt index d8d98c9ed..2e616ab44 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/ReadBookActivity.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/ReadBookActivity.kt @@ -89,12 +89,14 @@ class ReadBookActivity : ReadBookBaseActivity(), } private val replaceActivity = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { + it ?: return@registerForActivityResult if (it.resultCode == RESULT_OK) { viewModel.replaceRuleChanged() } } private val searchContentActivity = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { + it ?: return@registerForActivityResult it.data?.let { data -> data.getIntExtra("index", ReadBook.durChapterIndex).let { index -> viewModel.searchContentQuery = data.getStringExtra("query") ?: "" From 73e1f22d8820557a83298e882bc423f8045da896 Mon Sep 17 00:00:00 2001 From: gedoor Date: Thu, 6 May 2021 08:40:39 +0800 Subject: [PATCH 45/48] =?UTF-8?q?=E5=8D=87=E7=BA=A7android=20studio?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle | 6 +++--- gradle/wrapper/gradle-wrapper.properties | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build.gradle b/build.gradle index e421da86b..dbf616d77 100644 --- a/build.gradle +++ b/build.gradle @@ -1,7 +1,7 @@ // Top-level build file where you can add configuration options common to all sub-projects/modules. buildscript { - ext.kotlin_version = '1.4.32' + ext.kotlin_version = '1.5.0' repositories { google() maven { url "https://maven.aliyun.com/nexus/content/groups/public/" } @@ -10,8 +10,8 @@ buildscript { maven { url "https://plugins.gradle.org/m2/" } } dependencies { - classpath 'com.android.tools.build:gradle:4.1.3' - classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" + classpath 'com.android.tools.build:gradle:4.2.0' + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.5.0" classpath "de.timfreiheit.resourceplaceholders:placeholders:0.3" } } diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 806be7b26..ef1aa2fdc 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-6.7.1-all.zip From d2dd02776658b4210fad2dcf7a56f4d4b028aa38 Mon Sep 17 00:00:00 2001 From: gedoor Date: Thu, 6 May 2021 09:30:13 +0800 Subject: [PATCH 46/48] =?UTF-8?q?=E5=8D=87=E7=BA=A7android=20studio?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index 0044c4aa3..f19373953 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -152,7 +152,7 @@ dependencies { implementation "androidx.lifecycle:lifecycle-common-java8:$lifecycle_version" //room - def room_version = '2.2.6' + def room_version = '2.3.0' implementation "androidx.room:room-runtime:$room_version" kapt "androidx.room:room-compiler:$room_version" testImplementation "androidx.room:room-testing:$room_version" From 42cadc68ffb55dd1bbe6a172fbb7cc7d37e4211f Mon Sep 17 00:00:00 2001 From: gedoor Date: Thu, 6 May 2021 09:53:31 +0800 Subject: [PATCH 47/48] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E9=BB=98=E8=AE=A4tts,?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/assets/defaultData/httpTTS.json | 160 +++++++++++++++---- 1 file changed, 125 insertions(+), 35 deletions(-) diff --git a/app/src/main/assets/defaultData/httpTTS.json b/app/src/main/assets/defaultData/httpTTS.json index de70e5196..08d3386cd 100644 --- a/app/src/main/assets/defaultData/httpTTS.json +++ b/app/src/main/assets/defaultData/httpTTS.json @@ -1,147 +1,237 @@ [ + { + "id": -100, + "name": "0", + "url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=4127&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=11&vol=5&aue=6&pit=3&_res_tag_=audio\"\n}" + }, + { + "id": -99, + "name": "zaixianai.cn", + "url": "\nlet url='https://www.zaixianai.cn/voiceCompose';\n\nlet ua=\"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36\";\n\nlet doc=java.get(url,{\"User-Agent\":ua});\nlet cookie=String(doc.header(\"set-cookie\")).match(/laravel_session=[^\\n]+/)[0];\nlet token=String(doc.body()).match(/token=\"([^\"]+)/)[1];\n\nurl='https://www.zaixianai.cn/Api_getVoice,'+JSON.stringify({\n\"method\": \"POST\",\n\"body\": \"content=\" + java.encodeURI(speakText) + \"&volume=50&speech_rate=0&voice=Aixia&_token=\"+token,\n\"headers\": {\n\"User-Agent\": ua,\n\"cookie\": cookie\n}\n});\n\nlet res=java.ajax(url);\n\n'https://www.zaixianai.cn/voice/'+JSON.parse(res).data.file_name+','+JSON.stringify({\n\"headers\": {\n\"User-Agent\": ua,\n\"accept\": \"*/*\",\n\"referer\": \"https://www.zaixianai.cn/voiceCompose\",\n\"cookie\": cookie,\n\"accept-encoding\": \"identity;q=1, *;q=0\"\n}\n})\n" + }, + { + "id": -98, + "name": "台湾女声", + "url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=4007&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=160&vol=5&aue=6&pit=5&_res_tag_=audio\"\n}" + }, { "id": -1, "name": "度丫丫", - "url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=4&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=301&vol=5&pit=5&_res_tag_=audio\"\n}" + "url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=4&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=301&vol=5&aue=6&pit=5&_res_tag_=audio\"\n}" }, { "id": -2, "name": "度博文①", - "url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=106&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=301&vol=5&pit=5&_res_tag_=audio\"\n}" + "url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=106&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=301&vol=5&aue=6&pit=5&_res_tag_=audio\"\n}" }, { "id": -3, "name": "度博文②", - "url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=4106&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=301&vol=5&pit=5&_res_tag_=audio\"\n}" + "url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=4106&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=301&vol=5&aue=6&pit=5&_res_tag_=audio\"\n}" }, { "id": -4, "name": "度博文③", - "url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=5106&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=301&vol=5&pit=5&_res_tag_=audio\"\n}" + "url": "http://tsn.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=5106&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=160&vol=5&aue=6&pit=5&_res_tag_=audio\"\n}" + }, + { + "id": -97, + "name": "度小乔", + "url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=1117&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=160=&vol=5&aue=6&pit=3&_res_tag_=audio\"\n}" }, { "id": -5, "name": "度小娇", - "url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=5&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=301&vol=5&pit=5&_res_tag_=audio\"\n}" + "url": "http://tsn.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=5&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=160&vol=5&aue=6&pit=5&_res_tag_=audio\"\n}" }, { "id": -6, "name": "度小宇", - "url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=1&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=301&vol=5&pit=5&_res_tag_=audio\"\n}" + "url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=2&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=301&vol=5&aue=6&pit=5&_res_tag_=audio\"\n}" }, { "id": -7, "name": "度小童", "url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=110&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=301&vol=5&pit=5&_res_tag_=audio\"\n}" }, + { + "id": -96, + "name": "度小童", + "url": "http://tsn.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=110&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=160&vol=5&aue=6&pit=5&_res_tag_=audio\"\n}" + }, + { + "id": -95, + "name": "度小粤", + "url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=0&cuid=baidu_speech_demo&idx=1&cod=2&lan=cte&ctp=1&pdt=160&vol=5&aue=6&pit=5&_res_tag_=audio\"\n}" + }, { "id": -8, "name": "度小美", - "url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=0&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=301&vol=5&pit=5&_res_tag_=audio\"\n}" + "url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=0&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=160&vol=5&aue=6&pit=5&_res_tag_=audio\"\n}" + }, + { + "id": -94, + "name": "度小芳", + "url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=4125&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=160&vol=5&aue=6&pit=5&_res_tag_=audio\"\n}" }, { "id": -9, "name": "度小萌", - "url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=111&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=301&vol=5&pit=5&_res_tag_=audio\"\n}" + "url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=111&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=301&vol=5&aue=6&pit=5&_res_tag_=audio\"\n}" + }, + { + "id": -93, + "name": "度小贤", + "url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=4115&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=160=&vol=5&aue=6&pit=5&_res_tag_=audio\"}" + }, + { + "id": -92, + "name": "度小雯", + "url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=5100&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=160=&vol=5&aue=6&pit=5&_res_tag_=audio\"\n}" }, { "id": -10, "name": "度小鹿①", - "url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=4118&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=301&vol=5&pit=5&_res_tag_=audio\"\n}" + "url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=4118&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=160&vol=5&aue=6&pit=5&_res_tag_=audio\"\n}" }, { - "id": -11, + "id": -12, "name": "度小鹿②", - "url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=5118&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=301&vol=5&pit=5&_res_tag_=audio\"\n}" + "url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=4119&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=160&vol=5&aue=6&pit=5&_res_tag_=audio\"\n}" }, { - "id": -12, + "id": -11, "name": "度小鹿③", - "url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=4119&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=301&vol=5&pit=5&_res_tag_=audio\"\n}" + "url": "http://tsn.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=5118&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=160=&vol=5&aue=6&pit=5&_res_tag_=audio\"\n}" + }, + { + "id": -91, + "name": "度灵儿", + "url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=5105&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=160=&vol=5&aue=6&pit=5&_res_tag_=audio\"\n}" }, { "id": -13, "name": "度米朵①", - "url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=103&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=301&vol=5&pit=5&_res_tag_=audio\"\n}" + "url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=103&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=301&vol=5&aue=6&pit=5&_res_tag_=audio\"\n}" }, { "id": -14, "name": "度米朵②", - "url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=4103&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=301&vol=5&pit=5&_res_tag_=audio\"\n}" + "url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=4103&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=160&vol=5&aue=6&pit=5&_res_tag_=audio\"\n}" }, { "id": -15, "name": "度逍遥-基础", - "url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=3&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=301&vol=5&pit=5&_res_tag_=audio\"\n}" + "url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=3&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=160&vol=5&aue=6&pit=5&_res_tag_=audio\"\n}" }, { "id": -16, "name": "度逍遥-精品①", - "url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=4003&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=301&vol=5&pit=5&_res_tag_=audio\"\n}" + "url": "http://tsn.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=4003&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=160&vol=5&aue=6&pit=5&_res_tag_=audio\"\n}" }, { "id": -17, "name": "度逍遥-精品②", - "url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=5003&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=301&vol=5&pit=5&_res_tag_=audio\"\n}" + "url": "http://tsn.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=5003&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=160&vol=5&aue=6&pit=5&_res_tag_=audio\"\n}" }, { "id": -18, "name": "情感女声", - "url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=4105&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=301&vol=5&pit=5&_res_tag_=audio\"\n}" + "url": "http://tsn.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=4105&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=160=&vol=5&aue=6&pit=5&_res_tag_=audio\"\n}" }, { "id": -19, "name": "情感男声", - "url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=4115&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=301&vol=5&pit=5&_res_tag_=audio\"\n}" + "url": "http://tsn.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=4115&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=160&vol=5&aue=6&pit=5&_res_tag_=audio\"\n}" }, { "id": -20, "name": "标准女声", - "url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=4100&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=301&vol=5&pit=5&_res_tag_=audio\"\n}" + "url": "http://tsn.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=4100&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=160=&vol=5&aue=6&pit=5&_res_tag_=audio\"\n}" + }, + { + "id": -90, + "name": "标准女声-基础", + "url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=100&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=160&vol=5&aue=6&pit=5&_res_tag_=audio\"\n}" }, { "id": -21, "name": "标准男声", - "url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=4121&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=301&vol=5&pit=5&_res_tag_=audio\"\n}" + "url": "http://tsn.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=4121&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=160=&vol=5&aue=6&pit=5&_res_tag_=audio\"\n}" }, { - "id": -22, - "name": "治愈女声", - "url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=5120&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=301&vol=5&pit=5&_res_tag_=audio\"\n}" + "id": -89, + "name": "温柔女声", + "url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=4126&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=160&vol=5&aue=6&pit=5&_res_tag_=audio\"\n}" }, { - "id": -23, - "name": "治愈男声", - "url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=5121&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=301&vol=5&pit=5&_res_tag_=audio\"\n}" + "id": -88, + "name": "甜美女声①", + "url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=1200&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=160&vol=&rate=32=5&pit=5&_res_tag_=audio\"\n}" }, { "id": -24, - "name": "甜美女声①", - "url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=4117&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=301&vol=5&pit=5&_res_tag_=audio\"\n}" + "name": "甜美女声②", + "url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=4117&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=160&vol=5&aue=6&pit=5&_res_tag_=audio\"\n}" }, { "id": -25, - "name": "甜美女声②", - "url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=5117&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=301&vol=5&pit=5&_res_tag_=audio\"\n}" + "name": "甜美女声③", + "url": "http://tsn.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=5117&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=160&vol=5&aue=6&pit=5&_res_tag_=audio\"\n}" + }, + { + "id": -22, + "name": "电台女声", + "url": "http://tsn.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=5120&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=160&vol=&rate=32=5&pit=5&_res_tag_=audio\"\n}" + }, + { + "id": -23, + "name": "电台男声", + "url": "http://tsn.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=5121&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=160&vol=5&aue=6&pit=5&_res_tag_=audio\"\n}" }, { "id": -26, "name": "百度主持", "url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=9&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=301&vol=5&pit=5&_res_tag_=audio\"\n}" }, + { + "id": -87, + "name": "百度主持", + "url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=4127&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=11&vol=5&aue=6&pit=5&_res_tag_=audio\"\n}" + }, + { + "id": -86, + "name": "百度解说①", + "url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=4123&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=12&vol=5&aue=6&pit=5&_res_tag_=audio\"\n}" + }, + { + "id": -85, + "name": "百度解说②", + "url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=4128&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=12&vol=5&aue=6&pit=5&_res_tag_=audio\"\n}" + }, + { + "id": -84, + "name": "百度解说③", + "url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=4129&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=12&vol=5&aue=6&pit=5&_res_tag_=audio\"\n}" + }, { "id": -27, "name": "百度评书①", - "url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=6&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=301&vol=5&pit=5&_res_tag_=audio\"\n}" + "url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=6&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=301&vol=5&aue=6&pit=5&_res_tag_=audio\"\n}" }, { "id": -28, "name": "百度评书②", - "url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=4114&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=301&vol=5&pit=5&_res_tag_=audio\"\n}" + "url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=4114&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=160&vol=5&aue=6&pit=5&_res_tag_=audio\"\n}" + }, + { + "id": -83, + "name": "萝莉少女音", + "url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=5201&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=160&vol=5&aue=6&pit=5&_res_tag_=audio\"\n}" }, { "id": -29, "name": "阿里云语音", "url": "/*播音人Aiting可改其他https://cdn.jsdelivr.net/gh/Celeter/build/.github/scripts/speaker.json,详见https://ai.aliyun.com/nls/tts*/;eval(''+java.ajax('https://cdn.jsdelivr.net/gh/Celeter/build/.github/scripts/ttsDemo.js'));ttsDemo(speakText,speakSpeed,'Aiting')" } -] +] \ No newline at end of file From cc94d3bc70811490f03d25cff96ead8198446c91 Mon Sep 17 00:00:00 2001 From: gedoor Date: Thu, 6 May 2021 09:56:49 +0800 Subject: [PATCH 48/48] edit updateLog.md --- app/src/main/assets/updateLog.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/src/main/assets/updateLog.md b/app/src/main/assets/updateLog.md index 8130b998b..11a6dcfcd 100644 --- a/app/src/main/assets/updateLog.md +++ b/app/src/main/assets/updateLog.md @@ -6,6 +6,8 @@ **2021/05/04** * 修复bug * url参数添加重置次数,retry +* 修改默认tts, 手动导入 +* 升级android studio **2021/04/30** * epub插图,epublib优化,图片解码优化,epub读取导出优化。by ag2s20150909