diff --git a/app/src/main/java/com/all/pdfreader/pro/app/model/FileActionEvent.kt b/app/src/main/java/com/all/pdfreader/pro/app/model/FileActionEvent.kt index 17b5377..16f4cd0 100644 --- a/app/src/main/java/com/all/pdfreader/pro/app/model/FileActionEvent.kt +++ b/app/src/main/java/com/all/pdfreader/pro/app/model/FileActionEvent.kt @@ -12,4 +12,8 @@ sealed class FileActionEvent { data class SetPassword(val status: Status, val success: Boolean? = null) : FileActionEvent() { enum class Status { START, COMPLETE } } + + data class RemovePassword(val status: Status, val success: Boolean? = null) : FileActionEvent() { + enum class Status { START, COMPLETE } + } } \ No newline at end of file diff --git a/app/src/main/java/com/all/pdfreader/pro/app/ui/act/MainActivity.kt b/app/src/main/java/com/all/pdfreader/pro/app/ui/act/MainActivity.kt index 05a7c55..3ea4428 100644 --- a/app/src/main/java/com/all/pdfreader/pro/app/ui/act/MainActivity.kt +++ b/app/src/main/java/com/all/pdfreader/pro/app/ui/act/MainActivity.kt @@ -123,6 +123,25 @@ class MainActivity : BaseActivity(), PermissionDialogFragment.PermissionCallback } } } + + is FileActionEvent.RemovePassword -> { + when (event.status) { + FileActionEvent.RemovePassword.Status.START -> { + progressDialog = ProgressDialogFragment() + progressDialog?.show(supportFragmentManager, "progressDialog") + } + + FileActionEvent.RemovePassword.Status.COMPLETE -> { + progressDialog?.dismiss() + progressDialog = null + if (event.success == true) { + showToast(getString(R.string.remove_password_successfully)) + } else { + showToast(getString(R.string.remove_password_failed)) + } + } + } + } } } } diff --git a/app/src/main/java/com/all/pdfreader/pro/app/ui/dialog/ListMoreDialogFragment.kt b/app/src/main/java/com/all/pdfreader/pro/app/ui/dialog/ListMoreDialogFragment.kt index 7b8e091..7d0f1d1 100644 --- a/app/src/main/java/com/all/pdfreader/pro/app/ui/dialog/ListMoreDialogFragment.kt +++ b/app/src/main/java/com/all/pdfreader/pro/app/ui/dialog/ListMoreDialogFragment.kt @@ -110,7 +110,7 @@ class ListMoreDialogFragment(val filePath: String) : BottomSheetDialogFragment() } binding.setPasswordBtn.setOnClickListener { if (pdfDocument.isPassword) { - + PdfRemovePasswordDialog().show(parentFragmentManager, "PdfRemovePasswordDialog") } else { PdfSetPasswordDialog().show(parentFragmentManager, "PdfSetPasswordDialog") } diff --git a/app/src/main/java/com/all/pdfreader/pro/app/ui/dialog/PdfRemovePasswordDialog.kt b/app/src/main/java/com/all/pdfreader/pro/app/ui/dialog/PdfRemovePasswordDialog.kt new file mode 100644 index 0000000..dedd14d --- /dev/null +++ b/app/src/main/java/com/all/pdfreader/pro/app/ui/dialog/PdfRemovePasswordDialog.kt @@ -0,0 +1,81 @@ +package com.all.pdfreader.pro.app.ui.dialog + +import android.graphics.Color +import android.os.Bundle +import android.text.Editable +import android.text.TextWatcher +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.Toast +import androidx.core.graphics.drawable.toDrawable +import androidx.fragment.app.DialogFragment +import androidx.fragment.app.activityViewModels +import com.all.pdfreader.pro.app.R +import com.all.pdfreader.pro.app.databinding.DialogPdfRemovePasswordBinding +import com.all.pdfreader.pro.app.databinding.DialogPdfSetPasswordBinding +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.PdfSecurityUtils +import com.all.pdfreader.pro.app.viewmodel.PdfViewModel +import kotlin.getValue + +class PdfRemovePasswordDialog() : DialogFragment( + +) { + private lateinit var binding: DialogPdfRemovePasswordBinding + private val viewModel: PdfViewModel by activityViewModels() + private lateinit var pdfDocument: PdfDocumentEntity + + override fun onCreateView( + inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? + ): View? { + binding = DialogPdfRemovePasswordBinding.inflate(layoutInflater) + return binding.root + } + + override fun onStart() { + super.onStart() + isCancelable = false + dialog?.window?.apply { + // 去掉系统默认的背景 padding + setBackgroundDrawable(Color.TRANSPARENT.toDrawable()) + // 设置宽度为全屏减去 16dp + val margin = resources.getDimensionPixelSize(R.dimen.dialog_margin) // 16dp + val width = resources.displayMetrics.widthPixels - margin * 2 + setLayout(width, ViewGroup.LayoutParams.WRAP_CONTENT) + } + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + viewModel.pdfDocument.value?.let { + pdfDocument = it + binding.etPassword.showKeyboard() + setupListeners() + } ?: run { + showToast(getString(R.string.file_not)) + dismiss() + } + } + + private fun setupListeners() { + binding.tvCancel.setOnClickListener { + dismiss() + } + + binding.tvConfirm.setOnClickListener { + val password = binding.etPassword.text.toString() + if (PdfSecurityUtils.isPdfPasswordCorrect(pdfDocument.filePath, password)) { + viewModel.removePassword(pdfDocument.filePath, password) + dismiss() + } else { + binding.tilPassword.error = getString(R.string.incorrect_password) + } + } + } + + private fun showToast(message: String) { + Toast.makeText(requireActivity(), message, Toast.LENGTH_SHORT).show() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/all/pdfreader/pro/app/util/PdfSecurityUtils.kt b/app/src/main/java/com/all/pdfreader/pro/app/util/PdfSecurityUtils.kt index 9c22b6c..d74b730 100644 --- a/app/src/main/java/com/all/pdfreader/pro/app/util/PdfSecurityUtils.kt +++ b/app/src/main/java/com/all/pdfreader/pro/app/util/PdfSecurityUtils.kt @@ -41,4 +41,16 @@ object PdfSecurityUtils { false // 返回解密失败的标志 } } + + fun isPdfPasswordCorrect(filePath: String, password: String): Boolean { + return try { + // 只尝试打开 PDF,不读取页面内容 + PDDocument.load(File(filePath), password).use { document -> + // 如果能成功打开且不抛异常,则密码正确 + true + } + } catch (e: Exception) { + false + } + } } diff --git a/app/src/main/java/com/all/pdfreader/pro/app/viewmodel/PdfViewModel.kt b/app/src/main/java/com/all/pdfreader/pro/app/viewmodel/PdfViewModel.kt index e9fc96b..7c3d7e2 100644 --- a/app/src/main/java/com/all/pdfreader/pro/app/viewmodel/PdfViewModel.kt +++ b/app/src/main/java/com/all/pdfreader/pro/app/viewmodel/PdfViewModel.kt @@ -151,4 +151,25 @@ class PdfViewModel : ViewModel() { ) } } + + fun removePassword(filePath: String, password: String) { + viewModelScope.launch { + _fileActionEvent.postValue(FileActionEvent.RemovePassword(FileActionEvent.RemovePassword.Status.START)) + + val success = withContext(Dispatchers.IO) { + PdfSecurityUtils.removePasswordFromPdf(filePath, password).also { + if (it) { + pdfRepository.updateIsPassword(filePath, false) + } + } + } + + _fileActionEvent.postValue( + FileActionEvent.SetPassword( + FileActionEvent.SetPassword.Status.COMPLETE, + success + ) + ) + } + } } \ No newline at end of file diff --git a/app/src/main/res/layout/dialog_pdf_remove_password.xml b/app/src/main/res/layout/dialog_pdf_remove_password.xml new file mode 100644 index 0000000..350cbfd --- /dev/null +++ b/app/src/main/res/layout/dialog_pdf_remove_password.xml @@ -0,0 +1,85 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 014801e..398c107 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -52,6 +52,7 @@ Set Password successfully Set Password failed Remove Password + This file will no longer be password protected. Remove Password successfully Remove Password failed Duplicate File