This commit is contained in:
kunfei
2023-07-30 15:52:40 +08:00
parent 37aed12428
commit 88d243c27d
5 changed files with 57 additions and 57 deletions
@@ -2,41 +2,32 @@ package io.legado.app.ui.book.bookmark
import android.app.Application import android.app.Application
import android.net.Uri import android.net.Uri
import androidx.documentfile.provider.DocumentFile
import io.legado.app.base.BaseViewModel import io.legado.app.base.BaseViewModel
import io.legado.app.constant.AppLog import io.legado.app.constant.AppLog
import io.legado.app.data.appDb import io.legado.app.data.appDb
import io.legado.app.utils.* import io.legado.app.utils.FileDoc
import java.io.File import io.legado.app.utils.GSON
import java.io.FileOutputStream import io.legado.app.utils.createFileIfNotExist
import io.legado.app.utils.openOutputStream
import io.legado.app.utils.toastOnUi
import io.legado.app.utils.writeToOutputStream
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
import java.util.* import java.util.Date
import java.util.Locale
class AllBookmarkViewModel(application: Application) : BaseViewModel(application) { class AllBookmarkViewModel(application: Application) : BaseViewModel(application) {
@Suppress("BlockingMethodInNonBlockingContext") /**
* 导出书签
*/
fun saveToFile(treeUri: Uri) { fun saveToFile(treeUri: Uri) {
execute { execute {
val dateFormat = SimpleDateFormat("yyMMddHHmmss", Locale.getDefault()) val dateFormat = SimpleDateFormat("yyMMddHHmmss", Locale.getDefault())
val bookmark = appDb.bookmarkDao.all val fileName = "bookmark-${dateFormat.format(Date())}"
if (treeUri.isContentScheme()) { val dirDoc = FileDoc.fromUri(treeUri, true)
val doc = DocumentFile.fromTreeUri(context, treeUri) dirDoc.createFileIfNotExist(fileName).openOutputStream().getOrThrow().use {
?.createFile("", "bookmark-${dateFormat.format(Date())}") GSON.writeToOutputStream(it, appDb.bookmarkDao.all)
doc?.let {
context.contentResolver.openOutputStream(doc.uri)!!.use {
GSON.writeToOutputStream(it, bookmark)
}
}
} else {
val path = treeUri.path!!
val file = FileUtils.createFileIfNotExist(
File(path),
"bookmark-${dateFormat.format(Date())}"
)
FileOutputStream(file).use {
GSON.writeToOutputStream(it, bookmark)
}
} }
}.onError { }.onError {
AppLog.put("导出失败\n${it.localizedMessage}", it, true) AppLog.put("导出失败\n${it.localizedMessage}", it, true)
@@ -157,7 +157,7 @@ class TocActivity : VMBaseActivity<ActivityChapterListBinding, TocViewModel>(),
viewModel.chapterListCallBack?.upChapterList(searchView?.query?.toString()) viewModel.chapterListCallBack?.upChapterList(searchView?.query?.toString())
} }
R.id.menu_export -> exportDir.launch() R.id.menu_export_bookmark -> exportDir.launch()
R.id.menu_log -> showDialogFragment<AppLogDialog>() R.id.menu_log -> showDialogFragment<AppLogDialog>()
} }
@@ -3,7 +3,6 @@ package io.legado.app.ui.book.toc
import android.app.Application import android.app.Application
import android.net.Uri import android.net.Uri
import androidx.documentfile.provider.DocumentFile
import androidx.lifecycle.MutableLiveData import androidx.lifecycle.MutableLiveData
import io.legado.app.R import io.legado.app.R
import io.legado.app.base.BaseViewModel import io.legado.app.base.BaseViewModel
@@ -12,16 +11,11 @@ import io.legado.app.data.appDb
import io.legado.app.data.entities.Book import io.legado.app.data.entities.Book
import io.legado.app.exception.NoStackTraceException import io.legado.app.exception.NoStackTraceException
import io.legado.app.model.localBook.LocalBook import io.legado.app.model.localBook.LocalBook
import io.legado.app.utils.FileUtils import io.legado.app.utils.FileDoc
import io.legado.app.utils.GSON import io.legado.app.utils.GSON
import io.legado.app.utils.isContentScheme import io.legado.app.utils.createFileIfNotExist
import io.legado.app.utils.toastOnUi import io.legado.app.utils.toastOnUi
import io.legado.app.utils.writeToOutputStream import io.legado.app.utils.writeText
import java.io.File
import java.io.FileOutputStream
import java.text.SimpleDateFormat
import java.util.Date
import java.util.Locale
class TocViewModel(application: Application) : BaseViewModel(application) { class TocViewModel(application: Application) : BaseViewModel(application) {
var bookUrl: String = "" var bookUrl: String = ""
@@ -78,34 +72,17 @@ class TocViewModel(application: Application) : BaseViewModel(application) {
bookMarkCallBack?.upBookmark(newText) bookMarkCallBack?.upBookmark(newText)
} }
@Suppress("BlockingMethodInNonBlockingContext")
fun saveBookmark(treeUri: Uri) { fun saveBookmark(treeUri: Uri) {
execute { execute {
val book = bookData.value val book = bookData.value
?: throw NoStackTraceException(context.getString(R.string.no_book)) ?: throw NoStackTraceException(context.getString(R.string.no_book))
val dateFormat = SimpleDateFormat("yyMMddHHmmss", Locale.getDefault()) val fileName = "bookmark-${book.name} ${book.author}"
val bookmark = appDb.bookmarkDao.getByBook(book.name, book.author) val doc = FileDoc.fromUri(treeUri, true)
if (treeUri.isContentScheme()) { doc.createFileIfNotExist(fileName).writeText(
val doc = DocumentFile.fromTreeUri(context, treeUri) GSON.toJson(
?.createFile("", "bookmark-${dateFormat.format(Date())}") appDb.bookmarkDao.getByBook(book.name, book.author)
doc?.let {
context.contentResolver.openOutputStream(doc.uri)!!.use {
GSON.writeToOutputStream(it, bookmark)
}
}
} else {
val path = treeUri.path!!
val file = FileUtils.createFileIfNotExist(
File(path), "bookmark-${
dateFormat.format(
Date()
)
}"
) )
FileOutputStream(file).use { )
GSON.writeToOutputStream(it, bookmark)
}
}
}.onError { }.onError {
AppLog.put("导出失败\n${it.localizedMessage}", it, true) AppLog.put("导出失败\n${it.localizedMessage}", it, true)
}.onSuccess { }.onSuccess {
@@ -232,6 +232,10 @@ fun FileDoc.openInputStream(): Result<InputStream> {
return uri.inputStream(appCtx) return uri.inputStream(appCtx)
} }
fun FileDoc.openOutputStream(): Result<OutputStream> {
return uri.outputStream(appCtx)
}
fun FileDoc.exists( fun FileDoc.exists(
fileName: String, fileName: String,
vararg subDirs: String vararg subDirs: String
@@ -17,7 +17,9 @@ import okio.source
import splitties.init.appCtx import splitties.init.appCtx
import java.io.File import java.io.File
import java.io.FileInputStream import java.io.FileInputStream
import java.io.FileOutputStream
import java.io.InputStream import java.io.InputStream
import java.io.OutputStream
import java.nio.charset.Charset import java.nio.charset.Charset
fun Uri.isContentScheme() = this.scheme == "content" fun Uri.isContentScheme() = this.scheme == "content"
@@ -204,6 +206,32 @@ fun Uri.inputStream(context: Context): Result<InputStream> {
} }
} }
fun Uri.outputStream(context: Context): Result<OutputStream> {
val uri = this
return kotlin.runCatching {
try {
if (isContentScheme()) {
DocumentFile.fromSingleUri(context, uri)
?: throw NoStackTraceException("未获取到文件")
return@runCatching context.contentResolver.openOutputStream(uri)!!
} else {
val path = RealPathUtil.getPath(context, uri)
?: throw NoStackTraceException("未获取到文件")
val file = File(path)
if (file.exists()) {
return@runCatching FileOutputStream(file)
} else {
throw NoStackTraceException("文件不存在")
}
}
} catch (e: Exception) {
e.printOnDebug()
AppLog.put("读取inputStream失败:${e.localizedMessage}", e)
throw e
}
}
}
fun Uri.toRequestBody(contentType: MediaType? = null): RequestBody { fun Uri.toRequestBody(contentType: MediaType? = null): RequestBody {
val uri = this val uri = this
return object : RequestBody() { return object : RequestBody() {