优化
This commit is contained in:
@@ -1,19 +1,29 @@
|
||||
package io.legado.app.ui.association
|
||||
|
||||
import android.app.Application
|
||||
import android.net.Uri
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import io.legado.app.base.BaseViewModel
|
||||
import io.legado.app.utils.contains
|
||||
import io.legado.app.utils.inputStream
|
||||
import io.legado.app.utils.readText
|
||||
|
||||
abstract class BaseAssociationViewModel(application: Application) : BaseViewModel(application) {
|
||||
|
||||
val successLive = MutableLiveData<Pair<String, String>>()
|
||||
val errorLive = MutableLiveData<String>()
|
||||
|
||||
fun importJson(uri: Uri) {
|
||||
when {
|
||||
uri.inputStream(context).contains("bookSourceUrl") ->
|
||||
successLive.postValue(Pair("bookSource", uri.toString()))
|
||||
else -> importJson(uri.readText(context))
|
||||
}
|
||||
}
|
||||
|
||||
fun importJson(json: String) {
|
||||
//暂时根据文件内容判断属于什么
|
||||
when {
|
||||
json.contains("bookSourceUrl") ->
|
||||
successLive.postValue(Pair("bookSource", json))
|
||||
json.contains("sourceUrl") ->
|
||||
successLive.postValue(Pair("rssSource", json))
|
||||
json.contains("pattern") ->
|
||||
|
||||
@@ -7,7 +7,9 @@ import androidx.lifecycle.MutableLiveData
|
||||
import io.legado.app.constant.AppLog
|
||||
import io.legado.app.constant.AppPattern.bookFileRegex
|
||||
import io.legado.app.exception.NoStackTraceException
|
||||
import io.legado.app.help.IntentData
|
||||
import io.legado.app.model.localBook.LocalBook
|
||||
import io.legado.app.utils.inputStream
|
||||
import io.legado.app.utils.isJson
|
||||
import io.legado.app.utils.printOnDebug
|
||||
import java.io.File
|
||||
@@ -23,24 +25,19 @@ class FileAssociationViewModel(application: Application) : BaseAssociationViewMo
|
||||
fun dispatchIndent(uri: Uri) {
|
||||
execute {
|
||||
lateinit var fileName: String
|
||||
lateinit var content: String
|
||||
lateinit var fileStream: InputStream
|
||||
//如果是普通的url,需要根据返回的内容判断是什么
|
||||
if (uri.scheme == "file" || uri.scheme == "content") {
|
||||
if (uri.scheme == "file") {
|
||||
fileName = if (uri.scheme == "file") {
|
||||
val file = File(uri.path.toString())
|
||||
fileStream = file.inputStream()
|
||||
fileName = file.name
|
||||
file.name
|
||||
} else {
|
||||
val file = DocumentFile.fromSingleUri(context, uri)
|
||||
if (file?.exists() != true) throw NoStackTraceException("文件不存在")
|
||||
fileStream = context.contentResolver.openInputStream(uri)!!
|
||||
fileName = file.name ?: ""
|
||||
file.name ?: ""
|
||||
}
|
||||
kotlin.runCatching {
|
||||
content = fileStream.reader(Charsets.UTF_8).use { it.readText() }
|
||||
if (content.isJson()) {
|
||||
importJson(content)
|
||||
if (uri.inputStream(context).isJson()) {
|
||||
importJson(uri)
|
||||
return@execute
|
||||
}
|
||||
}.onFailure {
|
||||
@@ -58,6 +55,7 @@ class FileAssociationViewModel(application: Application) : BaseAssociationViewMo
|
||||
}.onError {
|
||||
it.printOnDebug()
|
||||
errorLive.postValue(it.localizedMessage)
|
||||
AppLog.put("无法打开文件\n${it.localizedMessage}", it)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package io.legado.app.ui.association
|
||||
|
||||
import android.app.Application
|
||||
import android.net.Uri
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import com.jayway.jsonpath.JsonPath
|
||||
import io.legado.app.R
|
||||
@@ -109,6 +110,12 @@ class ImportBookSourceViewModel(app: Application) : BaseViewModel(app) {
|
||||
mText.isAbsUrl() -> {
|
||||
importSourceUrl(mText)
|
||||
}
|
||||
mText.isUri() -> {
|
||||
val uri = Uri.parse(mText)
|
||||
uri.inputStream(context)?.let {
|
||||
allSources.addAll(BookSource.fromJsonArray(it).getOrThrow())
|
||||
}
|
||||
}
|
||||
else -> throw NoStackTraceException(context.getString(R.string.wrong_format))
|
||||
}
|
||||
}.onError {
|
||||
|
||||
@@ -21,6 +21,7 @@ import io.legado.app.data.entities.BookSource
|
||||
import io.legado.app.databinding.ActivityBookSourceBinding
|
||||
import io.legado.app.databinding.DialogEditTextBinding
|
||||
import io.legado.app.help.DirectLinkUpload
|
||||
import io.legado.app.help.IntentData
|
||||
import io.legado.app.help.config.LocalConfig
|
||||
import io.legado.app.lib.dialogs.alert
|
||||
import io.legado.app.lib.theme.primaryColor
|
||||
@@ -77,11 +78,7 @@ class BookSourceActivity : VMBaseActivity<ActivityBookSourceBinding, BookSourceV
|
||||
}
|
||||
private val importDoc = registerForActivityResult(HandleFileContract()) {
|
||||
it.uri?.let { uri ->
|
||||
try {
|
||||
showDialogFragment(ImportBookSourceDialog(uri.readText(this)))
|
||||
} catch (e: Exception) {
|
||||
toastOnUi("readTextError:${e.localizedMessage}")
|
||||
}
|
||||
showDialogFragment(ImportBookSourceDialog(uri.toString()))
|
||||
}
|
||||
}
|
||||
private val exportDir = registerForActivityResult(HandleFileContract()) {
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
package io.legado.app.utils
|
||||
|
||||
import java.io.InputStream
|
||||
import java.util.*
|
||||
|
||||
fun InputStream?.isJson(): Boolean {
|
||||
this ?: return false
|
||||
this.use {
|
||||
val byteArray = ByteArray(128)
|
||||
it.read(byteArray)
|
||||
val a = String(byteArray).trim()
|
||||
it.skip(it.available() - 128L)
|
||||
it.read(byteArray)
|
||||
val b = String(byteArray).trim()
|
||||
return (a + b).isJson()
|
||||
}
|
||||
}
|
||||
|
||||
fun InputStream?.contains(str: String): Boolean {
|
||||
this ?: return false
|
||||
this.use {
|
||||
val scanner = Scanner(it)
|
||||
return scanner.findWithinHorizon(str, 0) != null
|
||||
}
|
||||
}
|
||||
@@ -24,6 +24,11 @@ fun String.parseToUri(): Uri {
|
||||
}
|
||||
}
|
||||
|
||||
fun String?.isUri(): Boolean {
|
||||
this ?: return false
|
||||
return this.startsWith("file://", true) || isContentScheme()
|
||||
}
|
||||
|
||||
fun String?.isAbsUrl() =
|
||||
this?.let {
|
||||
it.startsWith("http://", true) || it.startsWith("https://", true)
|
||||
|
||||
@@ -6,6 +6,7 @@ import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.documentfile.provider.DocumentFile
|
||||
import androidx.fragment.app.Fragment
|
||||
import io.legado.app.R
|
||||
import io.legado.app.constant.AppLog
|
||||
import io.legado.app.exception.NoStackTraceException
|
||||
import io.legado.app.lib.permission.Permissions
|
||||
import io.legado.app.lib.permission.PermissionsCompat
|
||||
@@ -153,4 +154,25 @@ fun Uri.writeBytes(
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
fun Uri.inputStream(context: Context): InputStream? {
|
||||
val uri = this
|
||||
try {
|
||||
if (isContentScheme()) {
|
||||
val doc = DocumentFile.fromSingleUri(context, uri)
|
||||
doc ?: throw NoStackTraceException("未获取到文件")
|
||||
return context.contentResolver.openInputStream(uri)!!
|
||||
} else {
|
||||
RealPathUtil.getPath(context, uri)?.let { path ->
|
||||
val file = File(path)
|
||||
return FileInputStream(file)
|
||||
}
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
e.printOnDebug()
|
||||
context.toastOnUi("读取inputStream失败:${e.localizedMessage}")
|
||||
AppLog.put("读取inputStream失败:${e.localizedMessage}", e)
|
||||
}
|
||||
return null
|
||||
}
|
||||
Reference in New Issue
Block a user