优化扫描方法:
1.分快速扫描与全盘扫描 2.下拉刷新必定调用全扫 3.每次重新创建应用则进行全盘扫描 4.每次只进入onResume则进行快速扫描
This commit is contained in:
parent
810399bcf8
commit
1f664cd191
@ -11,6 +11,8 @@ class PDFReaderApplication : Application() {
|
|||||||
private lateinit var instance: PDFReaderApplication
|
private lateinit var instance: PDFReaderApplication
|
||||||
fun getInstance(): PDFReaderApplication = instance
|
fun getInstance(): PDFReaderApplication = instance
|
||||||
fun getContext(): Context = instance.applicationContext
|
fun getContext(): Context = instance.applicationContext
|
||||||
|
//是新创建了界面,则需要全盘扫描,进入onResume判定,扫描方法调用后置为false
|
||||||
|
var isNeedFullScan = false
|
||||||
}
|
}
|
||||||
|
|
||||||
private lateinit var fileChangeObserver: FileChangeObserver
|
private lateinit var fileChangeObserver: FileChangeObserver
|
||||||
@ -18,7 +20,7 @@ class PDFReaderApplication : Application() {
|
|||||||
override fun onCreate() {
|
override fun onCreate() {
|
||||||
super.onCreate()
|
super.onCreate()
|
||||||
instance = this
|
instance = this
|
||||||
|
isNeedFullScan = true
|
||||||
// 初始化文件变化监听(不立即启动)
|
// 初始化文件变化监听(不立即启动)
|
||||||
fileChangeObserver = FileChangeObserver(this)
|
fileChangeObserver = FileChangeObserver(this)
|
||||||
|
|
||||||
|
|||||||
@ -158,20 +158,28 @@ class MainActivity : BaseActivity(), PermissionDialogFragment.PermissionCallback
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun scanningStrategy() {
|
private fun scanningStrategy() {
|
||||||
// 智能扫描策略
|
if (StoragePermissionHelper.hasBasicStoragePermission(this)) {
|
||||||
if (pdfScanner.shouldScan()) {
|
lifecycleScope.launch {
|
||||||
logDebug("🔄 需要扫描PDF文件 (首次启动或超过24小时)")
|
pdfScanner.scanAndLoadPdfFiles(PDFReaderApplication.isNeedFullScan)
|
||||||
if (StoragePermissionHelper.hasBasicStoragePermission(this)) {
|
|
||||||
lifecycleScope.launch {
|
|
||||||
pdfScanner.scanAndLoadPdfFiles()
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
logDebug("❌ 权限不足,跳过扫描")
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
val hoursAgo = pdfScanner.getHoursSinceLastScan()
|
logDebug("❌ 权限不足,跳过扫描")
|
||||||
logDebug("⏭️ 跳过扫描,上次扫描在${hoursAgo}小时前")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// // 智能扫描策略
|
||||||
|
// if (pdfScanner.shouldScan()) {
|
||||||
|
// logDebug("🔄 需要扫描PDF文件 (首次启动或超过24小时)")
|
||||||
|
// if (StoragePermissionHelper.hasBasicStoragePermission(this)) {
|
||||||
|
// lifecycleScope.launch {
|
||||||
|
// pdfScanner.scanAndLoadPdfFiles()
|
||||||
|
// }
|
||||||
|
// } else {
|
||||||
|
// logDebug("❌ 权限不足,跳过扫描")
|
||||||
|
// }
|
||||||
|
// } else {
|
||||||
|
// val hoursAgo = pdfScanner.getHoursSinceLastScan()
|
||||||
|
// logDebug("⏭️ 跳过扫描,上次扫描在${hoursAgo}小时前")
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
// 授权后续操作
|
// 授权后续操作
|
||||||
|
|||||||
@ -52,7 +52,7 @@ class HomeFrag : BaseFrag(), MainActivity.SortableFragment {
|
|||||||
binding.swipeRefreshLayout.setOnRefreshListener {
|
binding.swipeRefreshLayout.setOnRefreshListener {
|
||||||
lifecycleScope.launch {
|
lifecycleScope.launch {
|
||||||
val pdfScanner = PdfScanner(requireContext(), getRepository())
|
val pdfScanner = PdfScanner(requireContext(), getRepository())
|
||||||
pdfScanner.scanAndLoadPdfFiles { b ->
|
pdfScanner.scanAndLoadPdfFiles(true) { b ->
|
||||||
binding.swipeRefreshLayout.isRefreshing = false
|
binding.swipeRefreshLayout.isRefreshing = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -8,11 +8,14 @@ import android.os.Looper
|
|||||||
import android.provider.MediaStore
|
import android.provider.MediaStore
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import androidx.lifecycle.LifecycleObserver
|
import androidx.lifecycle.LifecycleObserver
|
||||||
|
import com.all.pdfreader.pro.app.room.repository.PdfRepository
|
||||||
|
import com.all.pdfreader.pro.app.util.FileUtils.getFileFromUri
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.SupervisorJob
|
import kotlinx.coroutines.SupervisorJob
|
||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
import java.io.File
|
||||||
|
|
||||||
class FileChangeObserver(
|
class FileChangeObserver(
|
||||||
private val context: Context,
|
private val context: Context,
|
||||||
@ -32,7 +35,15 @@ class FileChangeObserver(
|
|||||||
contentObserver = object : ContentObserver(Handler(Looper.getMainLooper())) {
|
contentObserver = object : ContentObserver(Handler(Looper.getMainLooper())) {
|
||||||
override fun onChange(selfChange: Boolean, uri: Uri?) {
|
override fun onChange(selfChange: Boolean, uri: Uri?) {
|
||||||
super.onChange(selfChange, uri)
|
super.onChange(selfChange, uri)
|
||||||
handleFileChange()
|
if (uri != null) {
|
||||||
|
val file = getFileFromUri(context, uri)
|
||||||
|
if (file != null) {
|
||||||
|
Log.d("ocean", "修改的文件: ${file.absolutePath}")
|
||||||
|
// 可以传给你的增量扫描逻辑
|
||||||
|
|
||||||
|
handleFileChange(file)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -63,7 +74,7 @@ class FileChangeObserver(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun handleFileChange() {
|
private fun handleFileChange(file: File) {
|
||||||
val currentTime = System.currentTimeMillis()
|
val currentTime = System.currentTimeMillis()
|
||||||
if (currentTime - lastScanTime < debounceDelay) {
|
if (currentTime - lastScanTime < debounceDelay) {
|
||||||
return // 防抖
|
return // 防抖
|
||||||
@ -76,7 +87,18 @@ class FileChangeObserver(
|
|||||||
|
|
||||||
if (StoragePermissionHelper.hasBasicStoragePermission(context)) {
|
if (StoragePermissionHelper.hasBasicStoragePermission(context)) {
|
||||||
Log.d("ocean", "📂 检测到文件变化,可以执行增量扫描...")
|
Log.d("ocean", "📂 检测到文件变化,可以执行增量扫描...")
|
||||||
|
val pdfRepository = PdfRepository.getInstance()
|
||||||
|
val existingDoc = pdfRepository.getDocumentByPath(file.absolutePath)
|
||||||
|
if (existingDoc != null) {
|
||||||
|
LogUtil.logDebug(
|
||||||
|
"ocean",
|
||||||
|
"PdfScanner: 📖 ${existingDoc.fileName} - ${existingDoc.pageCount}页 - ${
|
||||||
|
FileUtils.formatFileSize(
|
||||||
|
existingDoc.fileSize
|
||||||
|
)
|
||||||
|
} - ${existingDoc.thumbnailPath}"
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -344,4 +344,35 @@ object FileUtils {
|
|||||||
} catch (_: Exception) {}
|
} catch (_: Exception) {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun getFileFromUri(context: Context, uri: Uri): File? {
|
||||||
|
// 先尝试通过 DATA 字段获取
|
||||||
|
val projection = arrayOf(MediaStore.Files.FileColumns.DATA)
|
||||||
|
context.contentResolver.query(uri, projection, null, null, null)?.use { cursor ->
|
||||||
|
if (cursor.moveToFirst()) {
|
||||||
|
val path = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Files.FileColumns.DATA))
|
||||||
|
if (!path.isNullOrEmpty()) {
|
||||||
|
val file = File(path)
|
||||||
|
if (file.exists()) {
|
||||||
|
return file
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Android 10+ 或 DATA 字段为空时,使用 ContentResolver 流访问
|
||||||
|
return try {
|
||||||
|
val tempFile = File(context.cacheDir, "temp_pdf_${System.currentTimeMillis()}.pdf")
|
||||||
|
context.contentResolver.openInputStream(uri)?.use { input ->
|
||||||
|
tempFile.outputStream().use { output ->
|
||||||
|
input.copyTo(output)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tempFile
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Log.e("ocean", "无法获取文件: ${e.message}", e)
|
||||||
|
null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -8,6 +8,7 @@ import android.graphics.pdf.PdfRenderer
|
|||||||
import android.os.ParcelFileDescriptor
|
import android.os.ParcelFileDescriptor
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import androidx.core.graphics.createBitmap
|
import androidx.core.graphics.createBitmap
|
||||||
|
import com.all.pdfreader.pro.app.PDFReaderApplication
|
||||||
import com.all.pdfreader.pro.app.room.entity.PdfDocumentEntity
|
import com.all.pdfreader.pro.app.room.entity.PdfDocumentEntity
|
||||||
import com.all.pdfreader.pro.app.room.repository.PdfRepository
|
import com.all.pdfreader.pro.app.room.repository.PdfRepository
|
||||||
import com.all.pdfreader.pro.app.util.FileUtils.isPdfEncrypted
|
import com.all.pdfreader.pro.app.util.FileUtils.isPdfEncrypted
|
||||||
@ -23,167 +24,208 @@ class PdfScanner(
|
|||||||
|
|
||||||
private val TAG = "ocean-PdfScanner"
|
private val TAG = "ocean-PdfScanner"
|
||||||
|
|
||||||
suspend fun scanAndLoadPdfFiles(callback: (Boolean) -> Unit = {}) {
|
suspend fun scanAndLoadPdfFiles(isNeedFullScan: Boolean, callback: (Boolean) -> Unit = {}) {
|
||||||
if (!StoragePermissionHelper.hasBasicStoragePermission(context)) {
|
if (!StoragePermissionHelper.hasBasicStoragePermission(context)) {
|
||||||
LogUtil.logDebug(TAG, "PdfScanner: 权限不足")
|
LogUtil.logDebug(TAG, "权限不足")
|
||||||
callback.invoke(false)
|
callback.invoke(false)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
withContext(Dispatchers.IO) {
|
withContext(Dispatchers.IO) {
|
||||||
try {
|
try {
|
||||||
LogUtil.logDebug(TAG, "PdfScanner: 🔍 开始扫描PDF文件...")
|
val startScannerTime = System.currentTimeMillis()
|
||||||
|
LogUtil.logDebug(TAG, "🔍开始扫描PDF文件...")
|
||||||
// 扫描应用私有目录(无需权限)
|
LogUtil.logDebug(TAG, "获取数据库数据")
|
||||||
val privateFiles = FileUtils.scanPdfFiles(context)
|
val cachedDocs = pdfRepository.getAllDocumentsOnce()
|
||||||
LogUtil.logDebug(
|
var needFullScan = isNeedFullScan
|
||||||
TAG, "PdfScanner: 📁 应用私有目录找到: ${privateFiles.size} 个PDF文件"
|
if (!needFullScan) {
|
||||||
)
|
cachedDocs.forEach { doc ->
|
||||||
privateFiles.forEach { file ->
|
val file = File(doc.filePath)//得到数据库存储的文件路径
|
||||||
LogUtil.logDebug(
|
if (file.exists()) {
|
||||||
TAG,
|
LogUtil.logDebug(TAG, "$file 文件存在,检测是否存在变化")
|
||||||
"PdfScanner: 📄 ${file.name} (${FileUtils.formatFileSize(file.length())})"
|
var needUpdate = false
|
||||||
)
|
var updatedDoc = doc.copy()
|
||||||
}
|
// 修改时间 与 文件大小
|
||||||
|
if (file.lastModified() != doc.lastModified || file.length() != doc.fileSize) {
|
||||||
// 扫描MediaStore(需要权限)
|
LogUtil.logDebug(TAG, "文件时间或者大小被修改 -> ${doc.fileName}")
|
||||||
val mediaStoreFiles = FileUtils.scanPdfFilesFromMediaStore(context)
|
updatedDoc = updatedDoc.copy(
|
||||||
LogUtil.logDebug(
|
|
||||||
TAG, "PdfScanner: 📱 MediaStore找到: ${mediaStoreFiles.size} 个PDF文件"
|
|
||||||
)
|
|
||||||
mediaStoreFiles.forEach { file ->
|
|
||||||
LogUtil.logDebug(
|
|
||||||
TAG,
|
|
||||||
"PdfScanner: 📱 ${file.name} (${FileUtils.formatFileSize(file.length())})"
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 合并并去重
|
|
||||||
val allFiles = (privateFiles + mediaStoreFiles).distinctBy { it.absolutePath }
|
|
||||||
LogUtil.logDebug(TAG, "PdfScanner: 📊 总计扫描到: ${allFiles.size} 个PDF文件")
|
|
||||||
|
|
||||||
// 处理每个PDF文件
|
|
||||||
allFiles.forEachIndexed { index, file ->
|
|
||||||
LogUtil.logDebug(
|
|
||||||
TAG,
|
|
||||||
"PdfScanner: 🔄 处理文件 ${index + 1}/${allFiles.size}: ${file.name} - ${file.absolutePath}"
|
|
||||||
)
|
|
||||||
|
|
||||||
if (FileUtils.isPdfFile(file)) {
|
|
||||||
val fileHash = FileUtils.calculateFileHash(file.absolutePath)
|
|
||||||
LogUtil.logDebug(TAG, "PdfScanner: 🔑 文件哈希: $fileHash")
|
|
||||||
|
|
||||||
if (fileHash != null) {
|
|
||||||
val existingDoc = pdfRepository.getDocumentByPath(file.absolutePath)
|
|
||||||
|
|
||||||
if (existingDoc == null) {
|
|
||||||
LogUtil.logDebug(
|
|
||||||
TAG, "PdfScanner: 🆕 发现新PDF文件: ${file.name}"
|
|
||||||
)
|
|
||||||
var thumbnailPath: String? = null
|
|
||||||
val isPassword = isPdfEncrypted(file)
|
|
||||||
LogUtil.logDebug(TAG, "PdfScanner: isPassword->${isPassword}")
|
|
||||||
if (!isPassword) {//没有密码的情况下才去获取缩略图
|
|
||||||
thumbnailPath = generateThumbnail(context, file) ?: ""
|
|
||||||
}
|
|
||||||
LogUtil.logDebug(TAG, "PdfScanner: thumbnailPath->${thumbnailPath}")
|
|
||||||
val metadata =
|
|
||||||
PdfMetadataExtractor.extractMetadata(file.absolutePath)
|
|
||||||
val document = PdfDocumentEntity(
|
|
||||||
fileHash = fileHash,
|
|
||||||
filePath = file.absolutePath,
|
|
||||||
fileName = file.name,
|
|
||||||
fileSize = file.length(),
|
|
||||||
lastModified = file.lastModified(),
|
lastModified = file.lastModified(),
|
||||||
pageCount = metadata?.pageCount ?: 0,
|
fileSize = file.length()
|
||||||
thumbnailPath = thumbnailPath,
|
|
||||||
metadataTitle = metadata?.title,
|
|
||||||
metadataAuthor = metadata?.author,
|
|
||||||
metadataSubject = metadata?.subject,
|
|
||||||
metadataKeywords = metadata?.keywords,
|
|
||||||
metadataCreationDate = metadata?.creationDate?.time,
|
|
||||||
metadataModificationDate = metadata?.modificationDate?.time,
|
|
||||||
isPassword = isPassword
|
|
||||||
)
|
)
|
||||||
pdfRepository.insertOrUpdateDocument(document)
|
needUpdate = true
|
||||||
LogUtil.logDebug(
|
}
|
||||||
TAG, "PdfScanner: ✅ 已保存到数据库: ${file.name}"
|
if (needUpdate) {
|
||||||
)
|
// 是否加密
|
||||||
} else {
|
|
||||||
LogUtil.logDebug(TAG, "PdfScanner: 📋 文件已存在: ${file.name}")
|
|
||||||
// 🔹 文件已存在,检查是否需要更新
|
|
||||||
var needUpdate = false
|
|
||||||
var updatedDoc = existingDoc.copy()
|
|
||||||
|
|
||||||
// 路径/修改时间更新
|
|
||||||
if (existingDoc.filePath != file.absolutePath || existingDoc.lastModified != file.lastModified()) {
|
|
||||||
LogUtil.logDebug(TAG, "PdfScanner: ✅ 路径/修改时间需要更新")
|
|
||||||
updatedDoc = updatedDoc.copy(
|
|
||||||
filePath = file.absolutePath,
|
|
||||||
lastModified = file.lastModified()
|
|
||||||
)
|
|
||||||
needUpdate = true
|
|
||||||
}
|
|
||||||
|
|
||||||
// 是否加密更新
|
|
||||||
val currentIsPassword = isPdfEncrypted(file)
|
val currentIsPassword = isPdfEncrypted(file)
|
||||||
if (existingDoc.isPassword != currentIsPassword) {
|
if (doc.isPassword != currentIsPassword) {
|
||||||
LogUtil.logDebug(TAG, "PdfScanner: ✅ 密码状态需要更新")
|
LogUtil.logDebug(TAG, "密码状态变化 -> ${doc.fileName}")
|
||||||
updatedDoc = updatedDoc.copy(isPassword = currentIsPassword)
|
updatedDoc = updatedDoc.copy(isPassword = currentIsPassword)
|
||||||
needUpdate = true
|
|
||||||
}
|
}
|
||||||
|
// 缩略图(仅非加密文件)
|
||||||
if (!currentIsPassword) {
|
if (!currentIsPassword) {
|
||||||
// 如果不是加密 PDF,再生成缩略图
|
|
||||||
val newThumbnail = generateThumbnail(context, file)
|
val newThumbnail = generateThumbnail(context, file)
|
||||||
if (existingDoc.thumbnailPath != newThumbnail) {
|
if (doc.thumbnailPath != newThumbnail) {
|
||||||
LogUtil.logDebug(TAG, "PdfScanner: ✅ 缩略图需要更新")
|
|
||||||
updatedDoc = updatedDoc.copy(thumbnailPath = newThumbnail)
|
updatedDoc = updatedDoc.copy(thumbnailPath = newThumbnail)
|
||||||
|
}
|
||||||
|
} else if (doc.thumbnailPath != null) {
|
||||||
|
updatedDoc = updatedDoc.copy(thumbnailPath = null)
|
||||||
|
}
|
||||||
|
pdfRepository.insertOrUpdateDocument(updatedDoc)
|
||||||
|
LogUtil.logDebug(TAG, "✅数据库已更新: ${doc.fileName}")
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 文件不存在 → 删除数据库记录,并触发全盘扫描
|
||||||
|
LogUtil.logDebug(TAG, "文件不存在 -> ${doc.fileName}, 删除记录")
|
||||||
|
pdfRepository.deleteDocument(doc.fileHash)
|
||||||
|
needFullScan = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (needFullScan || cachedDocs.isEmpty()) {
|
||||||
|
LogUtil.logDebug(TAG, "数据库不完整,执行全盘扫描...")
|
||||||
|
// 扫描应用私有目录(无需权限)
|
||||||
|
val privateFiles = FileUtils.scanPdfFiles(context)
|
||||||
|
LogUtil.logDebug(TAG, "📁应用私有目录找到: ${privateFiles.size} 个PDF文件")
|
||||||
|
// 扫描MediaStore(需要权限)
|
||||||
|
val mediaStoreFiles = FileUtils.scanPdfFilesFromMediaStore(context)
|
||||||
|
LogUtil.logDebug(TAG, "📱MediaStore找到: ${mediaStoreFiles.size} 个PDF文件")
|
||||||
|
// 合并并去重
|
||||||
|
val allFiles = (privateFiles + mediaStoreFiles).distinctBy { it.absolutePath }
|
||||||
|
LogUtil.logDebug(TAG, "📊总计扫描到: ${allFiles.size} 个PDF文件")
|
||||||
|
// 处理每个PDF文件
|
||||||
|
allFiles.forEachIndexed { index, file ->
|
||||||
|
LogUtil.logDebug(
|
||||||
|
TAG,
|
||||||
|
"🔄处理文件 ${index + 1}/${allFiles.size}: ${file.name} - ${file.absolutePath}"
|
||||||
|
)
|
||||||
|
|
||||||
|
if (FileUtils.isPdfFile(file)) {
|
||||||
|
val fileHash = FileUtils.calculateFileHash(file.absolutePath)
|
||||||
|
LogUtil.logDebug(TAG, "🔑文件哈希: $fileHash")
|
||||||
|
|
||||||
|
if (fileHash != null) {
|
||||||
|
val existingDoc = pdfRepository.getDocumentByPath(file.absolutePath)
|
||||||
|
|
||||||
|
if (existingDoc == null) {
|
||||||
|
LogUtil.logDebug(
|
||||||
|
TAG, "🆕发现新PDF文件: ${file.name}"
|
||||||
|
)
|
||||||
|
var thumbnailPath: String? = null
|
||||||
|
val isPassword = isPdfEncrypted(file)
|
||||||
|
LogUtil.logDebug(TAG, "isPassword->${isPassword}")
|
||||||
|
if (!isPassword) {//没有密码的情况下才去获取缩略图
|
||||||
|
thumbnailPath = generateThumbnail(context, file) ?: ""
|
||||||
|
}
|
||||||
|
LogUtil.logDebug(TAG, "thumbnailPath->${thumbnailPath}")
|
||||||
|
val metadata =
|
||||||
|
PdfMetadataExtractor.extractMetadata(file.absolutePath)
|
||||||
|
val document = PdfDocumentEntity(
|
||||||
|
fileHash = fileHash,
|
||||||
|
filePath = file.absolutePath,
|
||||||
|
fileName = file.name,
|
||||||
|
fileSize = file.length(),
|
||||||
|
lastModified = file.lastModified(),
|
||||||
|
pageCount = metadata?.pageCount ?: 0,
|
||||||
|
thumbnailPath = thumbnailPath,
|
||||||
|
metadataTitle = metadata?.title,
|
||||||
|
metadataAuthor = metadata?.author,
|
||||||
|
metadataSubject = metadata?.subject,
|
||||||
|
metadataKeywords = metadata?.keywords,
|
||||||
|
metadataCreationDate = metadata?.creationDate?.time,
|
||||||
|
metadataModificationDate = metadata?.modificationDate?.time,
|
||||||
|
isPassword = isPassword
|
||||||
|
)
|
||||||
|
pdfRepository.insertOrUpdateDocument(document)
|
||||||
|
LogUtil.logDebug(
|
||||||
|
TAG, " ✅ 已保存到数据库: ${file.name}"
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
LogUtil.logDebug(TAG, " 📋 文件已存在: ${file.name}")
|
||||||
|
// 🔹 文件已存在,检查是否需要更新
|
||||||
|
var needUpdate = false
|
||||||
|
var updatedDoc = existingDoc.copy()
|
||||||
|
|
||||||
|
// 路径/修改时间更新
|
||||||
|
if (existingDoc.filePath != file.absolutePath || existingDoc.lastModified != file.lastModified()) {
|
||||||
|
LogUtil.logDebug(TAG, "✅ 路径/修改时间需要更新")
|
||||||
|
updatedDoc = updatedDoc.copy(
|
||||||
|
filePath = file.absolutePath,
|
||||||
|
lastModified = file.lastModified()
|
||||||
|
)
|
||||||
needUpdate = true
|
needUpdate = true
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
updatedDoc = updatedDoc.copy(thumbnailPath = null)
|
|
||||||
needUpdate = true
|
|
||||||
}
|
|
||||||
|
|
||||||
// 执行更新
|
// 是否加密更新
|
||||||
if (needUpdate) {
|
val currentIsPassword = isPdfEncrypted(file)
|
||||||
pdfRepository.insertOrUpdateDocument(updatedDoc)
|
if (existingDoc.isPassword != currentIsPassword) {
|
||||||
LogUtil.logDebug(
|
LogUtil.logDebug(TAG, "✅ 密码状态需要更新")
|
||||||
TAG, "PdfScanner: ✅ 数据库已更新: ${file.name}"
|
updatedDoc = updatedDoc.copy(isPassword = currentIsPassword)
|
||||||
)
|
needUpdate = true
|
||||||
} else {
|
}
|
||||||
LogUtil.logDebug(
|
|
||||||
TAG, "PdfScanner: ⏩ 无需更新: ${file.name}"
|
if (!currentIsPassword) {
|
||||||
)
|
// 如果不是加密 PDF,再生成缩略图
|
||||||
|
val newThumbnail = generateThumbnail(context, file)
|
||||||
|
if (existingDoc.thumbnailPath != newThumbnail) {
|
||||||
|
LogUtil.logDebug(TAG, "✅ 缩略图需要更新")
|
||||||
|
updatedDoc =
|
||||||
|
updatedDoc.copy(thumbnailPath = newThumbnail)
|
||||||
|
needUpdate = true
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
updatedDoc = updatedDoc.copy(thumbnailPath = null)
|
||||||
|
needUpdate = true
|
||||||
|
}
|
||||||
|
|
||||||
|
// 执行更新
|
||||||
|
if (needUpdate) {
|
||||||
|
pdfRepository.insertOrUpdateDocument(updatedDoc)
|
||||||
|
LogUtil.logDebug(
|
||||||
|
TAG, "✅ 数据库已更新: ${file.name}"
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
LogUtil.logDebug(
|
||||||
|
TAG, "⏩ 无需更新: ${file.name}"
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// 打印数据库中的总记录数
|
||||||
|
pdfRepository.getAllDocumentsOnce().forEach { doc ->
|
||||||
|
LogUtil.logDebug(
|
||||||
|
TAG, " 📖 ${doc.fileName} - ${doc.pageCount}页 - ${
|
||||||
|
FileUtils.formatFileSize(
|
||||||
|
doc.fileSize
|
||||||
|
)
|
||||||
|
} - ${doc.thumbnailPath}"
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 打印数据库中的总记录数
|
|
||||||
pdfRepository.getAllDocumentsOnce().forEach { doc ->
|
|
||||||
LogUtil.logDebug(
|
|
||||||
TAG, "PdfScanner: 📖 ${doc.fileName} - ${doc.pageCount}页 - ${
|
|
||||||
FileUtils.formatFileSize(
|
|
||||||
doc.fileSize
|
|
||||||
)
|
|
||||||
} - ${doc.thumbnailPath}"
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 标记扫描完成
|
// 标记扫描完成
|
||||||
ScanManager.markScanComplete(context)
|
ScanManager.markScanComplete(context)
|
||||||
val lastScanTime = ScanManager.getLastScanTime(context)
|
val lastScanTime = ScanManager.getLastScanTime(context)
|
||||||
LogUtil.logDebug(
|
LogUtil.logDebug(
|
||||||
TAG, "PdfScanner: ✅ 扫描完成,记录时间: ${java.util.Date(lastScanTime)}"
|
TAG, "✅ 扫描完成,记录时间: ${java.util.Date(lastScanTime)}"
|
||||||
)
|
)
|
||||||
|
var string = if (needFullScan) {
|
||||||
|
"全盘扫描"
|
||||||
|
} else if (cachedDocs.isEmpty()) {
|
||||||
|
"数据库没有值,第一次全盘扫描"
|
||||||
|
} else {
|
||||||
|
"快速扫描"
|
||||||
|
}
|
||||||
|
// 计算扫描耗时
|
||||||
|
val scannerTime = System.currentTimeMillis() - startScannerTime
|
||||||
|
LogUtil.logDebug(
|
||||||
|
TAG,
|
||||||
|
"$string 本次扫描耗时: $scannerTime ms (${scannerTime / 1000.0} 秒)"
|
||||||
|
)
|
||||||
|
PDFReaderApplication.isNeedFullScan = false
|
||||||
callback.invoke(true)
|
callback.invoke(true)
|
||||||
|
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
Log.e(TAG, "PdfScanner: ❌ 扫描出错: ${e.message}", e)
|
Log.e(TAG, "❌ 扫描出错: ${e.message}", e)
|
||||||
callback.invoke(false)
|
callback.invoke(false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user