优化
This commit is contained in:
@@ -69,7 +69,7 @@ fun Book.getLocalUri(): Uri {
|
||||
Uri.fromFile(File(bookUrl))
|
||||
}
|
||||
//先检测uri是否有效,这个比较快
|
||||
uri.inputStream(appCtx)?.use {
|
||||
uri.inputStream(appCtx).getOrNull()?.use {
|
||||
localUriCache[bookUrl] = uri
|
||||
}?.let {
|
||||
return uri
|
||||
|
||||
@@ -43,10 +43,11 @@ object LocalBook {
|
||||
fun getBookInputStream(book: Book): InputStream {
|
||||
val uri = book.getLocalUri()
|
||||
//文件不存在 尝试下载webDav文件
|
||||
val inputStream = uri.inputStream(appCtx) ?: let {
|
||||
book.removeLocalUriCache()
|
||||
downloadRemoteBook(book)
|
||||
}
|
||||
val inputStream = uri.inputStream(appCtx).getOrNull()
|
||||
?: let {
|
||||
book.removeLocalUriCache()
|
||||
downloadRemoteBook(book)
|
||||
}
|
||||
if (inputStream != null) return inputStream
|
||||
book.removeLocalUriCache()
|
||||
throw FileNotFoundException("${uri.path} 文件不存在")
|
||||
@@ -241,7 +242,12 @@ object LocalBook {
|
||||
?: throw NoStackTraceException("没有设置书籍保存位置!")
|
||||
val bytes = when {
|
||||
str.isAbsUrl() -> AnalyzeUrl(str, source = source).getInputStream()
|
||||
str.isDataUrl() -> ByteArrayInputStream(Base64.decode(str.substringAfter("base64,"), Base64.DEFAULT))
|
||||
str.isDataUrl() -> ByteArrayInputStream(
|
||||
Base64.decode(
|
||||
str.substringAfter("base64,"),
|
||||
Base64.DEFAULT
|
||||
)
|
||||
)
|
||||
else -> throw NoStackTraceException("在线导入书籍支持http/https/DataURL")
|
||||
}
|
||||
return saveBookFile(bytes, fileName)
|
||||
@@ -324,7 +330,7 @@ object LocalBook {
|
||||
localBook.bookUrl = if (it.isContentScheme()) it.toString() else it.path!!
|
||||
localBook.save()
|
||||
localBook.cacheLocalUri(it)
|
||||
it.inputStream(appCtx)
|
||||
it.inputStream(appCtx).getOrThrow()
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
e.printOnDebug()
|
||||
|
||||
@@ -15,7 +15,7 @@ abstract class BaseAssociationViewModel(application: Application) : BaseViewMode
|
||||
|
||||
fun importJson(uri: Uri) {
|
||||
when {
|
||||
uri.inputStream(context).contains("bookSourceUrl") ->
|
||||
uri.inputStream(context).getOrNull().contains("bookSourceUrl") ->
|
||||
successLive.postValue(Pair("bookSource", uri.toString()))
|
||||
else -> importJson(uri.readText(context))
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ class FileAssociationViewModel(application: Application) : BaseAssociationViewMo
|
||||
val fileDoc = FileDoc.fromUri(uri, false)
|
||||
fileName = fileDoc.name
|
||||
kotlin.runCatching {
|
||||
if (uri.inputStream(context).isJson()) {
|
||||
if (uri.inputStream(context).getOrNull().isJson()) {
|
||||
importJson(uri)
|
||||
return@execute
|
||||
}
|
||||
|
||||
@@ -112,7 +112,7 @@ class ImportBookSourceViewModel(app: Application) : BaseViewModel(app) {
|
||||
}
|
||||
mText.isUri() -> {
|
||||
val uri = Uri.parse(mText)
|
||||
uri.inputStream(context)?.let {
|
||||
uri.inputStream(context).getOrThrow().let {
|
||||
allSources.addAll(BookSource.fromJsonArray(it).getOrThrow())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@ import io.legado.app.lib.dialogs.alert
|
||||
import io.legado.app.lib.theme.primaryColor
|
||||
import io.legado.app.utils.*
|
||||
import io.legado.app.utils.viewbindingdelegate.viewBinding
|
||||
import splitties.init.appCtx
|
||||
import splitties.views.onClick
|
||||
import java.io.FileOutputStream
|
||||
|
||||
@@ -27,17 +28,23 @@ class GroupEditDialog() : BaseDialogFragment(R.layout.dialog_book_group_edit) {
|
||||
private val viewModel by viewModels<GroupViewModel>()
|
||||
private var bookGroup: BookGroup? = null
|
||||
val selectImage = registerForActivityResult(SelectImageContract()) {
|
||||
readUri(it?.uri) { fileDoc, inputStream ->
|
||||
var file = requireContext().externalFiles
|
||||
val suffix = fileDoc.name.substringAfterLast(".")
|
||||
val fileName = it.uri!!.inputStream(requireContext())!!.use {
|
||||
MD5Utils.md5Encode(it) + ".$suffix"
|
||||
it ?: return@registerForActivityResult
|
||||
it.uri ?: return@registerForActivityResult
|
||||
readUri(it.uri) { fileDoc, inputStream ->
|
||||
try {
|
||||
var file = requireContext().externalFiles
|
||||
val suffix = fileDoc.name.substringAfterLast(".")
|
||||
val fileName = it.uri.inputStream(requireContext()).getOrThrow().use { tmp ->
|
||||
MD5Utils.md5Encode(tmp) + ".$suffix"
|
||||
}
|
||||
file = FileUtils.createFileIfNotExist(file, "covers", fileName)
|
||||
FileOutputStream(file).use { outputStream ->
|
||||
inputStream.copyTo(outputStream)
|
||||
}
|
||||
binding.ivCover.load(file.absolutePath)
|
||||
} catch (e: Exception) {
|
||||
appCtx.toastOnUi(e.localizedMessage)
|
||||
}
|
||||
file = FileUtils.createFileIfNotExist(file, "covers", fileName)
|
||||
FileOutputStream(file).use { outputStream ->
|
||||
inputStream.copyTo(outputStream)
|
||||
}
|
||||
binding.ivCover.load(file.absolutePath)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@ import io.legado.app.help.book.isLocal
|
||||
import io.legado.app.ui.book.changecover.ChangeCoverDialog
|
||||
import io.legado.app.utils.*
|
||||
import io.legado.app.utils.viewbindingdelegate.viewBinding
|
||||
import splitties.init.appCtx
|
||||
import java.io.FileOutputStream
|
||||
|
||||
class BookInfoEditActivity :
|
||||
@@ -120,17 +121,21 @@ class BookInfoEditActivity :
|
||||
|
||||
private fun coverChangeTo(uri: Uri) {
|
||||
readUri(uri) { fileDoc, inputStream ->
|
||||
inputStream.use {
|
||||
var file = this.externalFiles
|
||||
val suffix = fileDoc.name.substringAfterLast(".")
|
||||
val fileName = uri.inputStream(this)!!.use {
|
||||
MD5Utils.md5Encode(it) + ".$suffix"
|
||||
runCatching {
|
||||
inputStream.use {
|
||||
var file = this.externalFiles
|
||||
val suffix = fileDoc.name.substringAfterLast(".")
|
||||
val fileName = uri.inputStream(this).getOrThrow().use {
|
||||
MD5Utils.md5Encode(it) + ".$suffix"
|
||||
}
|
||||
file = FileUtils.createFileIfNotExist(file, "covers", fileName)
|
||||
FileOutputStream(file).use { outputStream ->
|
||||
inputStream.copyTo(outputStream)
|
||||
}
|
||||
coverChangeTo(file.absolutePath)
|
||||
}
|
||||
file = FileUtils.createFileIfNotExist(file, "covers", fileName)
|
||||
FileOutputStream(file).use { outputStream ->
|
||||
inputStream.copyTo(outputStream)
|
||||
}
|
||||
coverChangeTo(file.absolutePath)
|
||||
}.onFailure {
|
||||
appCtx.toastOnUi(it.localizedMessage)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,6 +34,7 @@ import io.legado.app.ui.document.HandleFileContract
|
||||
import io.legado.app.ui.widget.seekbar.SeekBarChangeListener
|
||||
import io.legado.app.utils.*
|
||||
import io.legado.app.utils.viewbindingdelegate.viewBinding
|
||||
import splitties.init.appCtx
|
||||
|
||||
import java.io.File
|
||||
import java.io.FileOutputStream
|
||||
@@ -353,17 +354,21 @@ class BgTextConfigDialog : BaseDialogFragment(R.layout.dialog_read_bg_text) {
|
||||
|
||||
private fun setBgFromUri(uri: Uri) {
|
||||
readUri(uri) { fileDoc, inputStream ->
|
||||
var file = requireContext().externalFiles
|
||||
val suffix = fileDoc.name.substringAfterLast(".")
|
||||
val fileName = uri.inputStream(requireContext())!!.use {
|
||||
MD5Utils.md5Encode(it) + ".$suffix"
|
||||
kotlin.runCatching {
|
||||
var file = requireContext().externalFiles
|
||||
val suffix = fileDoc.name.substringAfterLast(".")
|
||||
val fileName = uri.inputStream(requireContext()).getOrThrow().use {
|
||||
MD5Utils.md5Encode(it) + ".$suffix"
|
||||
}
|
||||
file = FileUtils.createFileIfNotExist(file, "bg", fileName)
|
||||
FileOutputStream(file).use { outputStream ->
|
||||
inputStream.copyTo(outputStream)
|
||||
}
|
||||
ReadBookConfig.durConfig.setCurBg(2, file.absolutePath)
|
||||
postEvent(EventBus.UP_CONFIG, false)
|
||||
}.onFailure {
|
||||
appCtx.toastOnUi(it.localizedMessage)
|
||||
}
|
||||
file = FileUtils.createFileIfNotExist(file, "bg", fileName)
|
||||
FileOutputStream(file).use { outputStream ->
|
||||
inputStream.copyTo(outputStream)
|
||||
}
|
||||
ReadBookConfig.durConfig.setCurBg(2, file.absolutePath)
|
||||
postEvent(EventBus.UP_CONFIG, false)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -14,6 +14,7 @@ import io.legado.app.lib.prefs.fragment.PreferenceFragment
|
||||
import io.legado.app.lib.theme.primaryColor
|
||||
import io.legado.app.model.BookCover
|
||||
import io.legado.app.utils.*
|
||||
import splitties.init.appCtx
|
||||
import java.io.FileOutputStream
|
||||
|
||||
class CoverConfigFragment : PreferenceFragment(),
|
||||
@@ -139,17 +140,21 @@ class CoverConfigFragment : PreferenceFragment(),
|
||||
|
||||
private fun setCoverFromUri(preferenceKey: String, uri: Uri) {
|
||||
readUri(uri) { fileDoc, inputStream ->
|
||||
var file = requireContext().externalFiles
|
||||
val suffix = fileDoc.name.substringAfterLast(".")
|
||||
val fileName = uri.inputStream(requireContext())!!.use {
|
||||
MD5Utils.md5Encode(it) + ".$suffix"
|
||||
kotlin.runCatching {
|
||||
var file = requireContext().externalFiles
|
||||
val suffix = fileDoc.name.substringAfterLast(".")
|
||||
val fileName = uri.inputStream(requireContext()).getOrThrow().use {
|
||||
MD5Utils.md5Encode(it) + ".$suffix"
|
||||
}
|
||||
file = FileUtils.createFileIfNotExist(file, "covers", fileName)
|
||||
FileOutputStream(file).use {
|
||||
inputStream.copyTo(it)
|
||||
}
|
||||
putPrefString(preferenceKey, file.absolutePath)
|
||||
BookCover.upDefaultCover()
|
||||
}.onFailure {
|
||||
appCtx.toastOnUi(it.localizedMessage)
|
||||
}
|
||||
file = FileUtils.createFileIfNotExist(file, "covers", fileName)
|
||||
FileOutputStream(file).use {
|
||||
inputStream.copyTo(it)
|
||||
}
|
||||
putPrefString(preferenceKey, file.absolutePath)
|
||||
BookCover.upDefaultCover()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -30,6 +30,7 @@ import io.legado.app.lib.theme.primaryColor
|
||||
import io.legado.app.ui.widget.number.NumberPickerDialog
|
||||
import io.legado.app.ui.widget.seekbar.SeekBarChangeListener
|
||||
import io.legado.app.utils.*
|
||||
import splitties.init.appCtx
|
||||
import java.io.FileOutputStream
|
||||
|
||||
|
||||
@@ -303,17 +304,21 @@ class ThemeConfigFragment : PreferenceFragment(),
|
||||
|
||||
private fun setBgFromUri(uri: Uri, preferenceKey: String, success: () -> Unit) {
|
||||
readUri(uri) { fileDoc, inputStream ->
|
||||
var file = requireContext().externalFiles
|
||||
val suffix = fileDoc.name.substringAfterLast(".")
|
||||
val fileName = uri.inputStream(requireContext())!!.use {
|
||||
MD5Utils.md5Encode(it) + ".$suffix"
|
||||
kotlin.runCatching {
|
||||
var file = requireContext().externalFiles
|
||||
val suffix = fileDoc.name.substringAfterLast(".")
|
||||
val fileName = uri.inputStream(requireContext()).getOrThrow().use {
|
||||
MD5Utils.md5Encode(it) + ".$suffix"
|
||||
}
|
||||
file = FileUtils.createFileIfNotExist(file, preferenceKey, fileName)
|
||||
FileOutputStream(file).use {
|
||||
inputStream.copyTo(it)
|
||||
}
|
||||
putPrefString(preferenceKey, file.absolutePath)
|
||||
success()
|
||||
}.onFailure {
|
||||
appCtx.toastOnUi(it.localizedMessage)
|
||||
}
|
||||
file = FileUtils.createFileIfNotExist(file, preferenceKey, fileName)
|
||||
FileOutputStream(file).use {
|
||||
inputStream.copyTo(it)
|
||||
}
|
||||
putPrefString(preferenceKey, file.absolutePath)
|
||||
success()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@ import io.legado.app.lib.prefs.fragment.PreferenceFragment
|
||||
import io.legado.app.lib.theme.primaryColor
|
||||
import io.legado.app.model.BookCover
|
||||
import io.legado.app.utils.*
|
||||
import splitties.init.appCtx
|
||||
import java.io.FileOutputStream
|
||||
|
||||
class WelcomeConfigFragment : PreferenceFragment(),
|
||||
@@ -119,16 +120,20 @@ class WelcomeConfigFragment : PreferenceFragment(),
|
||||
|
||||
private fun setCoverFromUri(preferenceKey: String, uri: Uri) {
|
||||
readUri(uri) { fileDoc, inputStream ->
|
||||
var file = requireContext().externalFiles
|
||||
val suffix = fileDoc.name.substringAfterLast(".")
|
||||
val fileName = uri.inputStream(requireContext())!!.use {
|
||||
MD5Utils.md5Encode(it) + ".$suffix"
|
||||
kotlin.runCatching {
|
||||
var file = requireContext().externalFiles
|
||||
val suffix = fileDoc.name.substringAfterLast(".")
|
||||
val fileName = uri.inputStream(requireContext()).getOrThrow().use {
|
||||
MD5Utils.md5Encode(it) + ".$suffix"
|
||||
}
|
||||
file = FileUtils.createFileIfNotExist(file, "covers", fileName)
|
||||
FileOutputStream(file).use {
|
||||
inputStream.copyTo(it)
|
||||
}
|
||||
putPrefString(preferenceKey, file.absolutePath)
|
||||
}.onFailure {
|
||||
appCtx.toastOnUi(it.localizedMessage)
|
||||
}
|
||||
file = FileUtils.createFileIfNotExist(file, "covers", fileName)
|
||||
FileOutputStream(file).use {
|
||||
inputStream.copyTo(it)
|
||||
}
|
||||
putPrefString(preferenceKey, file.absolutePath)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -173,23 +173,28 @@ fun Uri.writeBytes(
|
||||
return false
|
||||
}
|
||||
|
||||
fun Uri.inputStream(context: Context): InputStream? {
|
||||
fun Uri.inputStream(context: Context): Result<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 ->
|
||||
return kotlin.runCatching {
|
||||
try {
|
||||
if (isContentScheme()) {
|
||||
DocumentFile.fromSingleUri(context, uri)
|
||||
?: throw NoStackTraceException("未获取到文件")
|
||||
return@runCatching context.contentResolver.openInputStream(uri)!!
|
||||
} else {
|
||||
val path = RealPathUtil.getPath(context, uri)
|
||||
?: throw NoStackTraceException("未获取到文件")
|
||||
val file = File(path)
|
||||
return FileInputStream(file)
|
||||
if (file.exists()) {
|
||||
return@runCatching FileInputStream(file)
|
||||
} else {
|
||||
throw NoStackTraceException("文件不存在")
|
||||
}
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
e.printOnDebug()
|
||||
AppLog.put("读取inputStream失败:${e.localizedMessage}", e)
|
||||
throw e
|
||||
}
|
||||
} 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