diff --git a/README.md b/README.md
index e63456b42..843400d98 100644
--- a/README.md
+++ b/README.md
@@ -21,7 +21,10 @@
or
or [Releases](https://github.com/gedoor/legado/releases/latest)
## 阅读API
-阅读3.0 提供了2种方式的API:`Web方式`和`Content Provider方式`。您可以在[这里](api.md)根据需要自行调用。
+* 阅读3.0 提供了2种方式的API:`Web方式`和`Content Provider方式`。您可以在[这里](api.md)根据需要自行调用。
+* 可通过url唤起阅读进行一键导入,url格式: legado://import/{path}?src={url}
+* path类型: bookSource,rssSource,replaceRule,textTocRule,httpTTS,theme,readConfig
+* path类型解释: 书源,订阅源,替换规则,本地txt小说目录规则,在线朗读引擎,主题,阅读排版
## 感谢
```
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index fea75c6a4..522dd2c43 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -319,16 +319,6 @@
-
-
-
-
-
-
-
-
-
+
+
-
-
-
-
-
-
-
-
-
+ android:theme="@style/AppTheme.Transparent" />
-
-
-
-
-
-
-
-
-
+ android:theme="@style/AppTheme.Transparent" />
-
-
-
-
-
-
-
-
-
+ android:theme="@style/AppTheme.Transparent" />
if (newConfig.themeName == config.themeName) {
configList[index] = newConfig
diff --git a/app/src/main/java/io/legado/app/ui/association/ImportBookSourceActivity.kt b/app/src/main/java/io/legado/app/ui/association/ImportBookSourceActivity.kt
index a1e1badca..f2c09bd88 100644
--- a/app/src/main/java/io/legado/app/ui/association/ImportBookSourceActivity.kt
+++ b/app/src/main/java/io/legado/app/ui/association/ImportBookSourceActivity.kt
@@ -8,8 +8,6 @@ import io.legado.app.constant.Theme
import io.legado.app.databinding.ActivityTranslucenceBinding
import io.legado.app.help.IntentDataHelp
import io.legado.app.lib.dialogs.alert
-
-import io.legado.app.utils.toastOnUi
import io.legado.app.utils.viewbindingdelegate.viewBinding
@@ -49,18 +47,7 @@ class ImportBookSourceActivity :
viewModel.importSource(it)
return
}
- intent.data?.let {
- when (it.path) {
- "/importonline" -> it.getQueryParameter("src")?.let { url ->
- viewModel.importSource(url)
- }
- else -> {
- binding.rotateLoading.hide()
- toastOnUi(R.string.wrong_format)
- finish()
- }
- }
- } ?: finish()
+ finish()
}
private fun errorDialog(msg: String) {
diff --git a/app/src/main/java/io/legado/app/ui/association/ImportReplaceRuleActivity.kt b/app/src/main/java/io/legado/app/ui/association/ImportReplaceRuleActivity.kt
index d01b49f26..a202a03e9 100644
--- a/app/src/main/java/io/legado/app/ui/association/ImportReplaceRuleActivity.kt
+++ b/app/src/main/java/io/legado/app/ui/association/ImportReplaceRuleActivity.kt
@@ -7,7 +7,6 @@ import io.legado.app.constant.Theme
import io.legado.app.databinding.ActivityTranslucenceBinding
import io.legado.app.help.IntentDataHelp
import io.legado.app.lib.dialogs.alert
-import io.legado.app.utils.toastOnUi
import io.legado.app.utils.viewbindingdelegate.viewBinding
class ImportReplaceRuleActivity :
@@ -46,18 +45,7 @@ class ImportReplaceRuleActivity :
viewModel.import(it)
return
}
- intent.data?.let {
- when (it.path) {
- "/importonline" -> it.getQueryParameter("src")?.let { url ->
- viewModel.import(url)
- }
- else -> {
- binding.rotateLoading.hide()
- toastOnUi("格式不对")
- finish()
- }
- }
- } ?: finish()
+ finish()
}
private fun errorDialog(msg: String) {
diff --git a/app/src/main/java/io/legado/app/ui/association/ImportRssSourceActivity.kt b/app/src/main/java/io/legado/app/ui/association/ImportRssSourceActivity.kt
index 7a2cfe9d9..a7a82a2cb 100644
--- a/app/src/main/java/io/legado/app/ui/association/ImportRssSourceActivity.kt
+++ b/app/src/main/java/io/legado/app/ui/association/ImportRssSourceActivity.kt
@@ -8,8 +8,6 @@ import io.legado.app.constant.Theme
import io.legado.app.databinding.ActivityTranslucenceBinding
import io.legado.app.help.IntentDataHelp
import io.legado.app.lib.dialogs.alert
-
-import io.legado.app.utils.toastOnUi
import io.legado.app.utils.viewbindingdelegate.viewBinding
class ImportRssSourceActivity :
@@ -48,18 +46,7 @@ class ImportRssSourceActivity :
viewModel.importSource(it)
return
}
- intent.data?.let {
- when (it.path) {
- "/importonline" -> it.getQueryParameter("src")?.let { url ->
- viewModel.importSource(url)
- }
- else -> {
- binding.rotateLoading.hide()
- toastOnUi(R.string.wrong_format)
- finish()
- }
- }
- } ?: finish()
+ finish()
}
private fun errorDialog(msg: String) {
diff --git a/app/src/main/java/io/legado/app/ui/association/OnLineImportActivity.kt b/app/src/main/java/io/legado/app/ui/association/OnLineImportActivity.kt
index 45cc57de7..d24a1d635 100644
--- a/app/src/main/java/io/legado/app/ui/association/OnLineImportActivity.kt
+++ b/app/src/main/java/io/legado/app/ui/association/OnLineImportActivity.kt
@@ -3,15 +3,22 @@ package io.legado.app.ui.association
import android.os.Bundle
import androidx.activity.viewModels
import io.legado.app.R
-import io.legado.app.base.BaseActivity
+import io.legado.app.base.VMBaseActivity
import io.legado.app.constant.Theme
import io.legado.app.databinding.ActivityTranslucenceBinding
import io.legado.app.lib.dialogs.alert
+import io.legado.app.utils.toastOnUi
import io.legado.app.utils.viewbindingdelegate.viewBinding
-class OnLineImportActivity : BaseActivity(theme = Theme.Transparent) {
+/**
+ * 网络一键导入
+ * 格式: legado://import/{path}?src={url}
+ */
+class OnLineImportActivity :
+ VMBaseActivity(theme = Theme.Transparent) {
override val binding by viewBinding(ActivityTranslucenceBinding::inflate)
+ override val viewModel by viewModels()
override fun onActivityCreated(savedInstanceState: Bundle?) {
intent.data?.let {
@@ -21,10 +28,21 @@ class OnLineImportActivity : BaseActivity(theme = T
return
}
when (it.path) {
- "bookSource" -> importBookSource(url)
- "rssSource" -> importRssSource(url)
- "replaceRule" -> importReplaceRule(url)
- else -> {
+ "/bookSource" -> importBookSource(url)
+ "/rssSource" -> importRssSource(url)
+ "/replaceRule" -> importReplaceRule(url)
+ "/textTocRule" -> viewModel.importTextTocRule(url, this::finallyDialog)
+ "/httpTTS" -> viewModel.importHttpTTS(url, this::finallyDialog)
+ "/theme" -> viewModel.importTheme(url, this::finallyDialog)
+ "/readConfig" -> viewModel.importReadConfig(url, this::finallyDialog)
+ "/importonline" -> when (it.host) {
+ "booksource" -> importBookSource(url)
+ "rsssource" -> importRssSource(url)
+ "replace" -> importReplaceRule(url)
+ else -> {
+ toastOnUi("url error")
+ finish()
+ }
}
}
}
@@ -35,14 +53,14 @@ class OnLineImportActivity : BaseActivity(theme = T
binding.rotateLoading.show()
viewModel.errorLiveData.observe(this, {
binding.rotateLoading.hide()
- errorDialog(it)
+ finallyDialog(getString(R.string.error), it)
})
viewModel.successLiveData.observe(this, {
binding.rotateLoading.hide()
if (it > 0) {
ImportBookSourceDialog().show(supportFragmentManager, "bookSource")
} else {
- errorDialog(getString(R.string.wrong_format))
+ finallyDialog(getString(R.string.error), getString(R.string.wrong_format))
}
})
viewModel.importSource(url)
@@ -53,14 +71,14 @@ class OnLineImportActivity : BaseActivity(theme = T
binding.rotateLoading.show()
viewModel.errorLiveData.observe(this, {
binding.rotateLoading.hide()
- errorDialog(it)
+ finallyDialog(getString(R.string.error), it)
})
viewModel.successLiveData.observe(this, {
binding.rotateLoading.hide()
if (it > 0) {
ImportRssSourceDialog().show(supportFragmentManager, "rssSource")
} else {
- errorDialog(getString(R.string.wrong_format))
+ finallyDialog(getString(R.string.error), getString(R.string.wrong_format))
}
})
viewModel.importSource(url)
@@ -71,22 +89,22 @@ class OnLineImportActivity : BaseActivity(theme = T
binding.rotateLoading.show()
viewModel.errorLiveData.observe(this, {
binding.rotateLoading.hide()
- errorDialog(it)
+ finallyDialog(getString(R.string.error), it)
})
viewModel.successLiveData.observe(this, {
binding.rotateLoading.hide()
if (it > 0) {
ImportReplaceRuleDialog().show(supportFragmentManager, "replaceRule")
} else {
- errorDialog(getString(R.string.wrong_format))
+ finallyDialog(getString(R.string.error), getString(R.string.wrong_format))
}
})
viewModel.import(url)
}
- private fun errorDialog(msg: String) {
- alert(getString(R.string.error), msg) {
- okButton { }
+ private fun finallyDialog(title: String, msg: String) {
+ alert(title, msg) {
+ okButton()
onDismiss {
finish()
}
diff --git a/app/src/main/java/io/legado/app/ui/association/OnLineImportViewModel.kt b/app/src/main/java/io/legado/app/ui/association/OnLineImportViewModel.kt
index 8dfba367e..2526d32b9 100644
--- a/app/src/main/java/io/legado/app/ui/association/OnLineImportViewModel.kt
+++ b/app/src/main/java/io/legado/app/ui/association/OnLineImportViewModel.kt
@@ -1,6 +1,111 @@
package io.legado.app.ui.association
import io.legado.app.App
+import io.legado.app.R
import io.legado.app.base.BaseViewModel
+import io.legado.app.data.appDb
+import io.legado.app.data.entities.HttpTTS
+import io.legado.app.data.entities.TxtTocRule
+import io.legado.app.help.ReadBookConfig
+import io.legado.app.help.ThemeConfig
+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 io.legado.app.utils.fromJsonObject
+import io.legado.app.utils.isJsonArray
-class OnLineImportViewModel(app: App) : BaseViewModel(app)
\ No newline at end of file
+class OnLineImportViewModel(app: App) : BaseViewModel(app) {
+
+ fun importTextTocRule(url: String, finally: (title: String, msg: String) -> Unit) {
+ execute {
+ okHttpClient.newCall {
+ url(url)
+ }.text("utf-8").let { json ->
+ if (json.isJsonArray()) {
+ GSON.fromJsonArray(json)?.let {
+ appDb.txtTocRuleDao.insert(*it.toTypedArray())
+ } ?: throw Exception("格式不对")
+ } else {
+ GSON.fromJsonObject(json)?.let {
+ appDb.txtTocRuleDao.insert(it)
+ } ?: throw Exception("格式不对")
+ }
+ }
+ }.onSuccess {
+ finally.invoke(context.getString(R.string.success), "导入Txt规则成功")
+ }.onError {
+ finally.invoke(context.getString(R.string.error), it.localizedMessage ?: "未知错误")
+ }
+ }
+
+ fun importHttpTTS(url: String, finally: (title: String, msg: String) -> Unit) {
+ execute {
+ okHttpClient.newCall {
+ url(url)
+ }.text("utf-8").let { json ->
+ if (json.isJsonArray()) {
+ GSON.fromJsonArray(json)?.let {
+ appDb.httpTTSDao.insert(*it.toTypedArray())
+ return@execute it.size
+ } ?: throw Exception("格式不对")
+ } else {
+ GSON.fromJsonObject(json)?.let {
+ appDb.httpTTSDao.insert(it)
+ return@execute 1
+ } ?: throw Exception("格式不对")
+ }
+ }
+ }.onSuccess {
+ finally.invoke(context.getString(R.string.success), "导入${it}朗读引擎")
+ }.onError {
+ finally.invoke(context.getString(R.string.error), it.localizedMessage ?: "未知错误")
+ }
+ }
+
+ fun importTheme(url: String, finally: (title: String, msg: String) -> Unit) {
+ execute {
+ okHttpClient.newCall {
+ url(url)
+ }.text("utf-8").let { json ->
+ if (json.isJsonArray()) {
+ GSON.fromJsonArray(json)?.forEach {
+ ThemeConfig.addConfig(it)
+ } ?: throw Exception("格式不对")
+ } else {
+ GSON.fromJsonObject(json)?.let {
+ ThemeConfig.addConfig(it)
+ } ?: throw Exception("格式不对")
+ }
+ }
+ }.onSuccess {
+ finally.invoke(context.getString(R.string.success), "导入主题成功")
+ }.onError {
+ finally.invoke(context.getString(R.string.error), it.localizedMessage ?: "未知错误")
+ }
+ }
+
+ fun importReadConfig(url: String, finally: (title: String, msg: String) -> Unit) {
+ execute {
+ @Suppress("BlockingMethodInNonBlockingContext")
+ val bytes = okHttpClient.newCall {
+ url(url)
+ }.bytes()
+ val config = ReadBookConfig.import(bytes)
+ ReadBookConfig.configList.forEachIndexed { index, c ->
+ if (c.name == config.name) {
+ ReadBookConfig.configList[index] = config
+ return@execute config.name
+ }
+ ReadBookConfig.configList.add(config)
+ return@execute config.name
+ }
+ }.onSuccess {
+ finally.invoke(context.getString(R.string.success), "导入排版成功")
+ }.onError {
+ finally.invoke(context.getString(R.string.error), it.localizedMessage ?: "未知错误")
+ }
+ }
+
+}
\ No newline at end of file
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 3837b6c22..5175f6610 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
@@ -308,6 +308,7 @@ class BgTextConfigDialog : BaseDialogFragment() {
private fun importNetConfig(url: String) {
execute {
+ @Suppress("BlockingMethodInNonBlockingContext")
okHttpClient.newCall {
url(url)
}.bytes().let {
@@ -318,9 +319,9 @@ class BgTextConfigDialog : BaseDialogFragment() {
}
}
- @Suppress("BlockingMethodInNonBlockingContext")
private fun importConfig(uri: Uri) {
execute {
+ @Suppress("BlockingMethodInNonBlockingContext")
importConfig(uri.readBytes(requireContext())!!)
}.onError {
it.printStackTrace()
@@ -328,61 +329,13 @@ class BgTextConfigDialog : BaseDialogFragment() {
}
}
- @Suppress("BlockingMethodInNonBlockingContext")
+ @Suppress("BlockingMethodInNonBlockingContext", "BlockingMethodInNonBlockingContext")
private fun importConfig(byteArray: ByteArray) {
execute {
- val configZipPath = FileUtils.getPath(requireContext().externalCache, configFileName)
- FileUtils.deleteFile(configZipPath)
- val zipFile = FileUtils.createFileIfNotExist(configZipPath)
- zipFile.writeBytes(byteArray)
- val configDirPath = FileUtils.getPath(requireContext().externalCache, "readConfig")
- FileUtils.deleteFile(configDirPath)
- ZipUtils.unzipFile(zipFile, FileUtils.createFolderIfNotExist(configDirPath))
- val configDir = FileUtils.createFolderIfNotExist(configDirPath)
- val configFile = FileUtils.getFile(configDir, "readConfig.json")
- val config: ReadBookConfig.Config = GSON.fromJsonObject(configFile.readText())!!
- if (config.textFont.isNotEmpty()) {
- val fontName = FileUtils.getName(config.textFont)
- val fontPath =
- FileUtils.getPath(requireContext().externalFiles, "font", fontName)
- if (!FileUtils.exist(fontPath)) {
- FileUtils.getFile(configDir, fontName).copyTo(File(fontPath))
- }
- config.textFont = fontPath
- }
- if (config.bgType == 2) {
- val bgName = FileUtils.getName(config.bgStr)
- val bgPath = FileUtils.getPath(requireContext().externalFiles, "bg", bgName)
- if (!FileUtils.exist(bgPath)) {
- val bgFile = FileUtils.getFile(configDir, bgName)
- if (bgFile.exists()) {
- bgFile.copyTo(File(bgPath))
- }
- }
- }
- if (config.bgTypeNight == 2) {
- val bgName = FileUtils.getName(config.bgStrNight)
- val bgPath = FileUtils.getPath(requireContext().externalFiles, "bg", bgName)
- if (!FileUtils.exist(bgPath)) {
- val bgFile = FileUtils.getFile(configDir, bgName)
- if (bgFile.exists()) {
- bgFile.copyTo(File(bgPath))
- }
- }
- }
- if (config.bgTypeEInk == 2) {
- val bgName = FileUtils.getName(config.bgStrEInk)
- val bgPath = FileUtils.getPath(requireContext().externalFiles, "bg", bgName)
- if (!FileUtils.exist(bgPath)) {
- val bgFile = FileUtils.getFile(configDir, bgName)
- if (bgFile.exists()) {
- bgFile.copyTo(File(bgPath))
- }
- }
- }
- ReadBookConfig.durConfig = config
- postEvent(EventBus.UP_CONFIG, true)
+ ReadBookConfig.import(byteArray)
}.onSuccess {
+ ReadBookConfig.durConfig = it
+ postEvent(EventBus.UP_CONFIG, true)
toastOnUi("导入成功")
}.onError {
it.printStackTrace()
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 73bfd6e24..ecadd4519 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
@@ -2,7 +2,6 @@ package io.legado.app.ui.rss.read
import android.annotation.SuppressLint
import android.app.DownloadManager
-import android.content.Intent
import android.content.pm.ActivityInfo
import android.content.res.Configuration
import android.net.Uri
@@ -23,9 +22,7 @@ import io.legado.app.help.AppConfig
import io.legado.app.lib.theme.DrawableUtils
import io.legado.app.lib.theme.primaryTextColor
import io.legado.app.service.help.Download
-import io.legado.app.ui.association.ImportBookSourceActivity
-import io.legado.app.ui.association.ImportReplaceRuleActivity
-import io.legado.app.ui.association.ImportRssSourceActivity
+import io.legado.app.ui.association.OnLineImportActivity
import io.legado.app.ui.document.FilePicker
import io.legado.app.ui.document.FilePickerParam
import io.legado.app.utils.*
@@ -332,41 +329,23 @@ class ReadRssActivity : VMBaseActivity
}
private fun shouldOverrideUrlLoading(url: Uri): Boolean {
- if (url.scheme == "http" || url.scheme == "https") {
- return false
- } else if (url.scheme == "yuedu") {
- when (url.host) {
- "booksource" -> {
- val intent = Intent(
- this@ReadRssActivity,
- ImportBookSourceActivity::class.java
- )
- intent.data = url
- startActivity(intent)
- }
- "rsssource" -> {
- val intent = Intent(
- this@ReadRssActivity,
- ImportRssSourceActivity::class.java
- )
- intent.data = url
- startActivity(intent)
+ when (url.scheme) {
+ "http", "https" -> {
+ return false
+ }
+ "legado", "yuedu" -> {
+ startActivity {
+ data = url
}
- "replace" -> {
- val intent = Intent(
- this@ReadRssActivity,
- ImportReplaceRuleActivity::class.java
- )
- intent.data = url
- startActivity(intent)
+ return true
+ }
+ else -> {
+ binding.root.longSnackbar("跳转其它应用", "确认") {
+ openUrl(url)
}
+ return true
}
- return true
- }
- binding.root.longSnackbar("跳转其它应用", "确认") {
- openUrl(url)
}
- return true
}
}