添加修改文件名功能。
This commit is contained in:
parent
ded6be90bf
commit
32374b0961
@ -42,6 +42,7 @@ android {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation(libs.androidx.fragment.ktx)
|
||||
implementation(libs.androidx.appcompat)
|
||||
implementation(libs.androidx.core.ktx)
|
||||
implementation(libs.androidx.lifecycle.runtime.ktx)
|
||||
|
||||
@ -0,0 +1,5 @@
|
||||
package com.all.pdfreader.pro.app.model
|
||||
|
||||
sealed class FileActionEvent {
|
||||
data class Rename(val renameResult: RenameResult) : FileActionEvent()
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
package com.all.pdfreader.pro.app.model
|
||||
|
||||
data class RenameResult(
|
||||
val success: Boolean,
|
||||
val errorMessage: String? = null
|
||||
) {
|
||||
companion object {
|
||||
fun success() = RenameResult(true)
|
||||
fun failure(message: String) = RenameResult(false, message)
|
||||
}
|
||||
}
|
||||
@ -36,4 +36,8 @@ interface PdfDocumentDao {
|
||||
|
||||
@Query("DELETE FROM pdf_documents WHERE filePath = :filePath")
|
||||
suspend fun deleteByPath(filePath: String)
|
||||
|
||||
@Query("UPDATE pdf_documents SET filePath = :newFilePath, fileName = :newName WHERE filePath = :oldFilePath")
|
||||
suspend fun updateFilePathAndFileName(oldFilePath: String, newFilePath: String, newName: String)
|
||||
|
||||
}
|
||||
@ -11,9 +11,7 @@ import java.security.MessageDigest
|
||||
class PdfRepository private constructor(context: Context) {
|
||||
|
||||
private val database = Room.databaseBuilder(
|
||||
context,
|
||||
PdfDatabase::class.java,
|
||||
PdfDatabase.DATABASE_NAME
|
||||
context, PdfDatabase::class.java, PdfDatabase.DATABASE_NAME
|
||||
).build()
|
||||
|
||||
private val pdfDao = database.pdfDocumentDao()
|
||||
@ -41,6 +39,17 @@ class PdfRepository private constructor(context: Context) {
|
||||
fun searchDocuments(query: String): Flow<List<PdfDocumentEntity>> =
|
||||
pdfDao.searchDocuments(query)
|
||||
|
||||
suspend fun updateFilePathAndFileName(oldFilePath: String, newFilePath: String, newName: String) {
|
||||
pdfDao.updateFilePathAndFileName(oldFilePath, newFilePath, newName)
|
||||
}
|
||||
|
||||
// suspend fun updateFilePathAndFileName(filePath: String, newFilePath: String, newName: String) {
|
||||
// val document = pdfDao.getByPath(filePath)?.copy(
|
||||
// filePath = newFilePath, fileName = newName
|
||||
// )
|
||||
// document?.let { pdfDao.update(it) }
|
||||
// }
|
||||
|
||||
suspend fun updateFavoriteStatus(filePath: String, isFavorite: Boolean) {
|
||||
val document = pdfDao.getByPath(filePath)?.copy(
|
||||
isFavorite = isFavorite,
|
||||
@ -79,7 +88,6 @@ class PdfRepository private constructor(context: Context) {
|
||||
document?.let { pdfDao.update(it) }
|
||||
}
|
||||
|
||||
|
||||
// 最近阅读相关操作
|
||||
suspend fun addToRecent(filePath: String, page: Int = 0) {
|
||||
val existing = recentDao.getByPdfHash(filePath)
|
||||
@ -88,8 +96,7 @@ class PdfRepository private constructor(context: Context) {
|
||||
} else {
|
||||
recentDao.insertOrUpdate(
|
||||
RecentReadEntity(
|
||||
filePath = filePath,
|
||||
lastOpenedTime = System.currentTimeMillis()
|
||||
filePath = filePath, lastOpenedTime = System.currentTimeMillis()
|
||||
)
|
||||
)
|
||||
}
|
||||
@ -120,12 +127,10 @@ class PdfRepository private constructor(context: Context) {
|
||||
|
||||
// 组合查询
|
||||
suspend fun getPdfWithDetails(pdfHash: String): Flow<PdfDetails> {
|
||||
return combine(
|
||||
pdfDao.getByHash(pdfHash)?.let { kotlinx.coroutines.flow.flowOf(it) }
|
||||
return combine(pdfDao.getByHash(pdfHash)?.let { kotlinx.coroutines.flow.flowOf(it) }
|
||||
?: kotlinx.coroutines.flow.flowOf(null),
|
||||
bookmarkDao.getBookmarksByPdf(pdfHash),
|
||||
noteDao.getNotesByPdf(pdfHash)
|
||||
) { document, bookmarks, notes ->
|
||||
noteDao.getNotesByPdf(pdfHash)) { document, bookmarks, notes ->
|
||||
PdfDetails(document, bookmarks, notes)
|
||||
}
|
||||
}
|
||||
|
||||
@ -5,10 +5,12 @@ import android.os.Bundle
|
||||
import android.view.View
|
||||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import com.all.pdfreader.pro.app.PRApp
|
||||
import com.all.pdfreader.pro.app.R
|
||||
import com.all.pdfreader.pro.app.databinding.ActivityMainBinding
|
||||
import com.all.pdfreader.pro.app.model.FileActionEvent
|
||||
import com.all.pdfreader.pro.app.ui.dialog.PermissionDialogFragment
|
||||
import com.all.pdfreader.pro.app.ui.dialog.SortDialogFragment
|
||||
import com.all.pdfreader.pro.app.ui.fragment.FavoriteFrag
|
||||
@ -18,6 +20,7 @@ import com.all.pdfreader.pro.app.ui.fragment.ToolsFrag
|
||||
import com.all.pdfreader.pro.app.util.AppUtils.setClickWithAnimation
|
||||
import com.all.pdfreader.pro.app.util.PdfScanner
|
||||
import com.all.pdfreader.pro.app.util.StoragePermissionHelper
|
||||
import com.all.pdfreader.pro.app.viewmodel.PdfViewModel
|
||||
import com.gyf.immersionbar.ImmersionBar
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
@ -38,10 +41,13 @@ class MainActivity : BaseActivity(), PermissionDialogFragment.PermissionCallback
|
||||
private var activeFragment: Fragment = homeFragment
|
||||
private val fragmentTag = "ACTIVE_FRAGMENT"
|
||||
|
||||
private val viewModel by lazy { ViewModelProvider(this)[PdfViewModel::class.java] }
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
binding = ActivityMainBinding.inflate(layoutInflater)
|
||||
setContentView(binding.root)
|
||||
initObserve()
|
||||
ImmersionBar.with(this).statusBarView(binding.view).statusBarDarkFont(true)
|
||||
.navigationBarColor(R.color.black).init()
|
||||
|
||||
@ -60,6 +66,21 @@ class MainActivity : BaseActivity(), PermissionDialogFragment.PermissionCallback
|
||||
updateSelectedNav(activeFragment)
|
||||
}
|
||||
|
||||
private fun initObserve(){
|
||||
//观察其余操作
|
||||
viewModel.fileActionEvent.observe(this) { event ->
|
||||
when (event) {
|
||||
is FileActionEvent.Rename -> {
|
||||
if (event.renameResult.success) {
|
||||
showToast(getString(R.string.rename_successfully))
|
||||
} else {
|
||||
showToast(event.renameResult.errorMessage.toString())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun setupFragments() {
|
||||
supportFragmentManager.beginTransaction().add(R.id.fragment_fl, toolsFragment, "TOOLS")
|
||||
.hide(toolsFragment).add(R.id.fragment_fl, favoriteFragment, "FAVORITE")
|
||||
|
||||
@ -7,6 +7,7 @@ import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import com.all.pdfreader.pro.app.R
|
||||
import com.all.pdfreader.pro.app.databinding.ActivityPdfViewBinding
|
||||
import com.all.pdfreader.pro.app.model.FileActionEvent
|
||||
import com.all.pdfreader.pro.app.room.entity.PdfDocumentEntity
|
||||
import com.all.pdfreader.pro.app.ui.dialog.PdfPasswordProtectionDialogFragment
|
||||
import com.all.pdfreader.pro.app.ui.view.CustomScrollHandle
|
||||
@ -40,10 +41,14 @@ class PdfViewActivity : BaseActivity(), OnLoadCompleteListener, OnPageChangeList
|
||||
super.onCreate(savedInstanceState)
|
||||
binding = ActivityPdfViewBinding.inflate(layoutInflater)
|
||||
setContentView(binding.root)
|
||||
|
||||
initObserve()
|
||||
val filePath = intent.getStringExtra(EXTRA_PDF_HASH)
|
||||
?: throw IllegalArgumentException("PDF file hash is required")
|
||||
// 加载PDF数据
|
||||
viewModel.getPDFDocument(filePath)
|
||||
}
|
||||
|
||||
private fun initObserve(){
|
||||
// 观察PDF文档数据
|
||||
viewModel.pdfDocument.observe(this) { document ->
|
||||
document?.let {
|
||||
@ -54,9 +59,19 @@ class PdfViewActivity : BaseActivity(), OnLoadCompleteListener, OnPageChangeList
|
||||
finish()
|
||||
}
|
||||
}
|
||||
|
||||
// 加载PDF数据
|
||||
viewModel.getPDFDocument(filePath)
|
||||
//观察其余操作
|
||||
viewModel.fileActionEvent.observe(this) { event ->
|
||||
logDebug("fileActionEvent响应 $event")
|
||||
when (event) {
|
||||
is FileActionEvent.Rename -> {
|
||||
if (event.renameResult.success) {
|
||||
showToast(getString(R.string.rename_successfully))
|
||||
} else {
|
||||
showToast(event.renameResult.errorMessage.toString())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun loadPdf() {
|
||||
|
||||
@ -5,6 +5,7 @@ import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.Toast
|
||||
import androidx.fragment.app.activityViewModels
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import com.all.pdfreader.pro.app.R
|
||||
@ -28,7 +29,7 @@ class ListMoreDialogFragment(val filePath: String) : BottomSheetDialogFragment()
|
||||
|
||||
private lateinit var binding: DialogListMoreBinding
|
||||
private val pdfRepository = PdfRepository.getInstance()
|
||||
private val viewModel by lazy { ViewModelProvider(this)[PdfViewModel::class.java] }
|
||||
private val viewModel: PdfViewModel by activityViewModels()
|
||||
private lateinit var pdfDocument: PdfDocumentEntity
|
||||
private var isFavorite: Boolean = false
|
||||
|
||||
|
||||
@ -3,7 +3,6 @@ package com.all.pdfreader.pro.app.ui.dialog
|
||||
import android.graphics.Color
|
||||
import android.os.Bundle
|
||||
import android.text.Editable
|
||||
import android.text.InputType
|
||||
import android.text.TextWatcher
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
@ -11,23 +10,21 @@ import android.view.ViewGroup
|
||||
import android.widget.Toast
|
||||
import androidx.core.graphics.drawable.toDrawable
|
||||
import androidx.fragment.app.DialogFragment
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.fragment.app.activityViewModels
|
||||
import com.all.pdfreader.pro.app.R
|
||||
import com.all.pdfreader.pro.app.databinding.DialogPdfPasswordProtectionBinding
|
||||
import com.all.pdfreader.pro.app.databinding.DialogRenameFileBinding
|
||||
import com.all.pdfreader.pro.app.room.entity.PdfDocumentEntity
|
||||
import com.all.pdfreader.pro.app.util.AppUtils.showKeyboard
|
||||
import com.all.pdfreader.pro.app.util.FileUtils
|
||||
import com.all.pdfreader.pro.app.util.FileUtils.isPdfPasswordCorrect
|
||||
import com.all.pdfreader.pro.app.viewmodel.PdfViewModel
|
||||
import java.io.File
|
||||
|
||||
class RenameDialogFragment(
|
||||
private val filePath: String,
|
||||
private val filePath: String
|
||||
) : DialogFragment() {
|
||||
|
||||
private lateinit var binding: DialogRenameFileBinding
|
||||
private val viewModel by lazy { ViewModelProvider(this)[PdfViewModel::class.java] }
|
||||
private val viewModel: PdfViewModel by activityViewModels()
|
||||
private lateinit var pdfDocument: PdfDocumentEntity
|
||||
|
||||
override fun onCreateView(
|
||||
@ -81,13 +78,7 @@ class RenameDialogFragment(
|
||||
binding.tvConfirm.setOnClickListener {
|
||||
val text = binding.etName.text.toString()
|
||||
if (validateEnter(text)) {
|
||||
val renameResult =
|
||||
FileUtils.renameFile(File(pdfDocument.filePath), text)
|
||||
if (renameResult.success) {
|
||||
showToast(getString(R.string.rename_successfully))
|
||||
} else {
|
||||
showToast(renameResult.errorMessage.toString())
|
||||
}
|
||||
viewModel.renamePdf(pdfDocument.filePath, text)
|
||||
dismiss()
|
||||
}
|
||||
}
|
||||
@ -96,6 +87,7 @@ class RenameDialogFragment(
|
||||
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
|
||||
binding.tilName.error = null
|
||||
}
|
||||
|
||||
override fun afterTextChanged(s: Editable?) {}
|
||||
})
|
||||
}
|
||||
|
||||
@ -20,19 +20,7 @@ import java.security.MessageDigest
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.Date
|
||||
import java.util.Locale
|
||||
|
||||
/**
|
||||
* 文件重命名结果封装类
|
||||
*/
|
||||
data class RenameResult(
|
||||
val success: Boolean,
|
||||
val errorMessage: String? = null
|
||||
) {
|
||||
companion object {
|
||||
fun success() = RenameResult(true)
|
||||
fun failure(message: String) = RenameResult(false, message)
|
||||
}
|
||||
}
|
||||
import com.all.pdfreader.pro.app.model.RenameResult
|
||||
|
||||
object FileUtils {
|
||||
|
||||
|
||||
@ -5,9 +5,13 @@ import androidx.lifecycle.LiveData
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import com.all.pdfreader.pro.app.model.FileActionEvent
|
||||
import com.all.pdfreader.pro.app.room.entity.PdfDocumentEntity
|
||||
import com.all.pdfreader.pro.app.room.repository.PdfRepository
|
||||
import com.all.pdfreader.pro.app.util.FileUtils
|
||||
import com.all.pdfreader.pro.app.util.LogUtil
|
||||
import kotlinx.coroutines.launch
|
||||
import java.io.File
|
||||
|
||||
class PdfViewModel : ViewModel() {
|
||||
private val pdfRepository = PdfRepository.getInstance()
|
||||
@ -15,6 +19,11 @@ class PdfViewModel : ViewModel() {
|
||||
private val _pdfDocument = MutableLiveData<PdfDocumentEntity?>()
|
||||
val pdfDocument: LiveData<PdfDocumentEntity?> = _pdfDocument
|
||||
|
||||
// 用于操作结果或通知UI
|
||||
private val _fileActionEvent = MutableLiveData<FileActionEvent>()
|
||||
val fileActionEvent: LiveData<FileActionEvent> = _fileActionEvent
|
||||
|
||||
|
||||
fun getPDFDocument(filePath: String) {
|
||||
viewModelScope.launch {
|
||||
val document = pdfRepository.getDocumentByPath(filePath)
|
||||
@ -22,4 +31,32 @@ class PdfViewModel : ViewModel() {
|
||||
_pdfDocument.postValue(document)
|
||||
}
|
||||
}
|
||||
|
||||
//触发修改文件名操作
|
||||
fun renamePdf(filePath: String, newName: String) {
|
||||
viewModelScope.launch {
|
||||
val oldFile = File(filePath)
|
||||
val renameResult = FileUtils.renameFile(oldFile, newName)
|
||||
Log.d("ocean", "renamePdf->oldFile: $oldFile, newName=$newName, renameResult=$renameResult")
|
||||
if (renameResult.success) {//修改成功更新数据库
|
||||
val finalName = if (newName.contains('.')) {
|
||||
// 用户提供了后缀,使用用户的
|
||||
newName
|
||||
} else {
|
||||
// 用户没有提供后缀,自动添加原文件后缀
|
||||
val originalExtension = File(filePath).extension
|
||||
if (originalExtension.isNotEmpty()) {
|
||||
"$newName.$originalExtension"
|
||||
} else {
|
||||
newName
|
||||
}
|
||||
}
|
||||
val parentDir = oldFile.parentFile
|
||||
val newFilePath = File(parentDir, finalName).absolutePath.toString()
|
||||
Log.d("ocean", "renamePdf->newFilePath: $newFilePath, finalName=$finalName")
|
||||
pdfRepository.updateFilePathAndFileName(filePath, newFilePath, finalName)
|
||||
}
|
||||
_fileActionEvent.postValue(FileActionEvent.Rename(renameResult))
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2,6 +2,7 @@
|
||||
androidpdfviewer = "3.2.8"
|
||||
appcompat = "1.7.1"
|
||||
agp = "8.10.1"
|
||||
fragmentKtx = "1.8.9"
|
||||
glide = "5.0.4"
|
||||
kotlin = "2.0.21"
|
||||
ksp = "2.0.21-1.0.27"
|
||||
@ -23,6 +24,7 @@ material = "1.12.0"
|
||||
androidpdfviewer = { module = "com.github.marain87:AndroidPdfViewer", version.ref = "androidpdfviewer" }
|
||||
androidx-appcompat = { module = "androidx.appcompat:appcompat", version.ref = "appcompat" }
|
||||
androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" }
|
||||
androidx-fragment-ktx = { module = "androidx.fragment:fragment-ktx", version.ref = "fragmentKtx" }
|
||||
androidx-room-compiler = { group = "androidx.room", name = "room-compiler", version.ref = "room_version" }
|
||||
androidx-room-ktx = { group = "androidx.room", name = "room-ktx", version.ref = "room_version" }
|
||||
androidx-room-runtime = { group = "androidx.room", name = "room-runtime", version.ref = "room_version" }
|
||||
|
||||
Loading…
Reference in New Issue
Block a user