diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 73ff0cd..6c79ea4 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -74,7 +74,7 @@
android:screenOrientation="portrait" />
diff --git a/app/src/main/java/com/all/pdfreader/pro/app/model/PdfPickerSource.kt b/app/src/main/java/com/all/pdfreader/pro/app/model/PdfPickerSource.kt
index 552a9c0..8b0d120 100644
--- a/app/src/main/java/com/all/pdfreader/pro/app/model/PdfPickerSource.kt
+++ b/app/src/main/java/com/all/pdfreader/pro/app/model/PdfPickerSource.kt
@@ -4,7 +4,8 @@ enum class PdfPickerSource {
NONE, // 没有任何
MERGE, // PDF合并
SPLIT, // PDF拆分
- LOCK, // PDF加密/解密
+ LOCK, // PDF加密
+ UNLOCK, // PDF解密
TO_IMAGES, // PDF转图片
TO_LONG_IMAGE // PDF转长图
}
\ No newline at end of file
diff --git a/app/src/main/java/com/all/pdfreader/pro/app/model/PdfSplitResultItem.kt b/app/src/main/java/com/all/pdfreader/pro/app/model/PdfSplitResultItem.kt
index 1be956b..e17e3ac 100644
--- a/app/src/main/java/com/all/pdfreader/pro/app/model/PdfSplitResultItem.kt
+++ b/app/src/main/java/com/all/pdfreader/pro/app/model/PdfSplitResultItem.kt
@@ -3,5 +3,6 @@ package com.all.pdfreader.pro.app.model
data class PdfSplitResultItem(
val filePath: String,
val thumbnailPath: String? = null,
- var isSelected: Boolean
+ var isSelected: Boolean = false,
+ var isPassword: Boolean = false
)
\ No newline at end of file
diff --git a/app/src/main/java/com/all/pdfreader/pro/app/ui/act/MergePdfActivity.kt b/app/src/main/java/com/all/pdfreader/pro/app/ui/act/MergePdfActivity.kt
index 030e25a..2bdabb6 100644
--- a/app/src/main/java/com/all/pdfreader/pro/app/ui/act/MergePdfActivity.kt
+++ b/app/src/main/java/com/all/pdfreader/pro/app/ui/act/MergePdfActivity.kt
@@ -62,7 +62,7 @@ class MergePdfActivity : BaseActivity() {
}
binding.continueNowBtn.setOnSingleClickListener {
val list = selectedList.map { it.filePath }
- val intent = SplitPdfResultActivity.createIntentInputFile(
+ val intent = PdfResultActivity.createIntentInputFile(
this, ArrayList(list), PdfPickerSource.MERGE
)
startActivity(intent)
diff --git a/app/src/main/java/com/all/pdfreader/pro/app/ui/act/PdfPickerActivity.kt b/app/src/main/java/com/all/pdfreader/pro/app/ui/act/PdfPickerActivity.kt
index 9c32b0c..f0c60d9 100644
--- a/app/src/main/java/com/all/pdfreader/pro/app/ui/act/PdfPickerActivity.kt
+++ b/app/src/main/java/com/all/pdfreader/pro/app/ui/act/PdfPickerActivity.kt
@@ -15,6 +15,7 @@ import com.all.pdfreader.pro.app.model.SortConfig
import com.all.pdfreader.pro.app.room.entity.PdfDocumentEntity
import com.all.pdfreader.pro.app.room.repository.PdfRepository
import com.all.pdfreader.pro.app.ui.adapter.PdfAdapter
+import com.all.pdfreader.pro.app.ui.dialog.PdfSetPasswordDialog
import com.all.pdfreader.pro.app.util.AppUtils.setClickWithAnimation
import com.all.pdfreader.pro.app.util.AppUtils.setOnSingleClickListener
import com.gyf.immersionbar.ImmersionBar
@@ -80,7 +81,21 @@ class PdfPickerActivity : BaseActivity() {
finish()
}
- PdfPickerSource.LOCK -> {}
+ PdfPickerSource.LOCK -> {
+ PdfSetPasswordDialog(onOkClick = { password ->
+ val intent = PdfResultActivity.createIntentLock(
+ this, pdf.filePath, password,
+ PdfPickerSource.LOCK
+ )
+ startActivity(intent)
+ finish()
+ }).show(supportFragmentManager, "PdfSetPasswordDialog")
+ }
+
+ PdfPickerSource.UNLOCK -> {
+
+ }
+
PdfPickerSource.TO_IMAGES -> {}
PdfPickerSource.TO_LONG_IMAGE -> {}
PdfPickerSource.NONE -> {}
@@ -109,17 +124,25 @@ class PdfPickerActivity : BaseActivity() {
private fun initData() {
lifecycleScope.launch {
PdfRepository.getInstance().getAllDocuments().collect { list ->
+ if (list.isEmpty()) {
+ binding.noFilesLayout.visibility = View.VISIBLE
+ return@collect
+ }
val sortedList = sortDocuments(list)
// 标记已选择项
if (fromActivityResult == MergePdfActivity.TAG) {
markSelectedItems(sortedList, historyList)
}
- if (list.isNotEmpty()) {
- adapter.updateData(sortedList)
- binding.noFilesLayout.visibility = View.GONE
- } else {
- binding.noFilesLayout.visibility = View.VISIBLE
+ // 再根据来源过滤
+ val displayList = when (source) {
+ PdfPickerSource.LOCK -> sortedList.filter { !it.isPassword }//只展示没有被加密的
+ PdfPickerSource.UNLOCK -> sortedList.filter { it.isPassword }//只展示已经被加密的
+ else -> sortedList
}
+
+ adapter.updateData(displayList)
+ binding.noFilesLayout.visibility =
+ if (displayList.isEmpty()) View.VISIBLE else View.GONE
}
}
}
diff --git a/app/src/main/java/com/all/pdfreader/pro/app/ui/act/SplitPdfResultActivity.kt b/app/src/main/java/com/all/pdfreader/pro/app/ui/act/PdfResultActivity.kt
similarity index 81%
rename from app/src/main/java/com/all/pdfreader/pro/app/ui/act/SplitPdfResultActivity.kt
rename to app/src/main/java/com/all/pdfreader/pro/app/ui/act/PdfResultActivity.kt
index 1029958..e1fb587 100644
--- a/app/src/main/java/com/all/pdfreader/pro/app/ui/act/SplitPdfResultActivity.kt
+++ b/app/src/main/java/com/all/pdfreader/pro/app/ui/act/PdfResultActivity.kt
@@ -1,6 +1,5 @@
package com.all.pdfreader.pro.app.ui.act
-import android.annotation.SuppressLint
import android.content.Context
import android.content.Intent
import android.os.Build
@@ -16,11 +15,13 @@ import com.all.pdfreader.pro.app.databinding.ActivityPdfSplitResultBinding
import com.all.pdfreader.pro.app.model.PdfPickerSource
import com.all.pdfreader.pro.app.model.PdfSelectedPagesItem
import com.all.pdfreader.pro.app.model.PdfSplitResultItem
-import com.all.pdfreader.pro.app.ui.adapter.SplitPdfResultAdapter
+import com.all.pdfreader.pro.app.room.repository.PdfRepository
+import com.all.pdfreader.pro.app.ui.adapter.PdfResultAdapter
import com.all.pdfreader.pro.app.ui.dialog.PromptDialogFragment
import com.all.pdfreader.pro.app.util.AppUtils
import com.all.pdfreader.pro.app.util.FileUtils.toUnderscoreDateTime
import com.all.pdfreader.pro.app.util.PdfScanner
+import com.all.pdfreader.pro.app.util.PdfSecurityUtils
import com.all.pdfreader.pro.app.util.PdfUtils
import com.gyf.immersionbar.ImmersionBar
import kotlinx.coroutines.Dispatchers
@@ -29,18 +30,20 @@ import kotlinx.coroutines.withContext
import java.io.File
import java.io.Serializable
-class SplitPdfResultActivity : BaseActivity() {
- override val TAG: String = "SplitPdfResultActivity"
+class PdfResultActivity : BaseActivity() {
+ override val TAG: String = "PdfResultActivity"
companion object {
private const val EXTRA_SELECTED_LIST = "extra_selected_list"
private const val EXTRA_FILE_LIST = "extra_file_list"
private const val EXTRA_SOURCE = "extra_source"
+ private const val EXTRA_PASSWORD = "extra_password"
+ private const val EXTRA_FILE_PATH = "extra_file_path"
fun createIntentPdfSelectedPagesItem(
context: Context, list: ArrayList, source: PdfPickerSource
): Intent {
- return Intent(context, SplitPdfResultActivity::class.java).apply {
+ return Intent(context, PdfResultActivity::class.java).apply {
putParcelableArrayListExtra(EXTRA_SELECTED_LIST, list)
putExtra(EXTRA_SOURCE, source)
}
@@ -49,23 +52,35 @@ class SplitPdfResultActivity : BaseActivity() {
fun createIntentInputFile(
context: Context, list: ArrayList, source: PdfPickerSource
): Intent {
- return Intent(context, SplitPdfResultActivity::class.java).apply {
+ return Intent(context, PdfResultActivity::class.java).apply {
putStringArrayListExtra(EXTRA_FILE_LIST, list)
putExtra(EXTRA_SOURCE, source)
}
}
+
+ fun createIntentLock(
+ context: Context, filepath: String, password: String, source: PdfPickerSource
+ ): Intent {
+ return Intent(context, PdfResultActivity::class.java).apply {
+ putExtra(EXTRA_FILE_PATH, filepath)
+ putExtra(EXTRA_PASSWORD, password)
+ putExtra(EXTRA_SOURCE, source)
+ }
+ }
}
private lateinit var binding: ActivityPdfSplitResultBinding
- private lateinit var adapter: SplitPdfResultAdapter
+ private lateinit var adapter: PdfResultAdapter
private var resultList: MutableList = mutableListOf()
private lateinit var selectedList: ArrayList
private lateinit var inputFile: ArrayList
private lateinit var source: PdfPickerSource
- private var isSplitting = false
+ private var isProcessing = false
private var exitDialog: PromptDialogFragment? = null
private val pdfRepository = getRepository()
private lateinit var pdfScanner: PdfScanner
+ private lateinit var filepath: String
+ private lateinit var password: String
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
@@ -76,6 +91,8 @@ class SplitPdfResultActivity : BaseActivity() {
.navigationBarColor(R.color.bg_color).init()
selectedList = requireParcelableArrayList(EXTRA_SELECTED_LIST)
inputFile = requireStringArrayList(EXTRA_FILE_LIST)
+ filepath = intent.getStringExtra(EXTRA_FILE_PATH) ?: ""
+ password = intent.getStringExtra(EXTRA_PASSWORD) ?: ""
source = getSerializableOrDefault(EXTRA_SOURCE, PdfPickerSource.NONE)
if (source == PdfPickerSource.NONE) {
showToast(getString(R.string.pdf_loading_failed))
@@ -94,6 +111,12 @@ class SplitPdfResultActivity : BaseActivity() {
finish()
return
}
+ } else if (source == PdfPickerSource.LOCK) {
+ if (filepath.isEmpty() || password.isEmpty()) {
+ showToast(getString(R.string.pdf_loading_failed))
+ finish()
+ return
+ }
}
}
pdfScanner = PdfScanner(this, pdfRepository)
@@ -103,7 +126,7 @@ class SplitPdfResultActivity : BaseActivity() {
}
private fun initView() {
- adapter = SplitPdfResultAdapter(resultList)
+ adapter = PdfResultAdapter(resultList)
binding.recyclerView.layoutManager = LinearLayoutManager(this)
binding.recyclerView.adapter = adapter
}
@@ -111,7 +134,7 @@ class SplitPdfResultActivity : BaseActivity() {
private fun initData() {
lifecycleScope.launch(Dispatchers.IO) {
withContext(Dispatchers.Main) {
- isSplitting = true
+ isProcessing = true
binding.processingLayout.visibility = View.VISIBLE
binding.progressBar.isIndeterminate = false
binding.progressBar.progress = 0
@@ -143,7 +166,7 @@ class SplitPdfResultActivity : BaseActivity() {
}
})?.let { resultFile ->
val thumbnails =
- AppUtils.generateFastThumbnail(this@SplitPdfResultActivity, resultFile)
+ AppUtils.generateFastThumbnail(this@PdfResultActivity, resultFile)
val result = PdfSplitResultItem(resultFile.absolutePath, thumbnails, false)
pdfScanner.addNewPdfToDatabase(result.filePath, result.thumbnailPath) {
resultList.add(result)
@@ -172,13 +195,27 @@ class SplitPdfResultActivity : BaseActivity() {
}
})?.let { resultFile ->
val thumbnails =
- AppUtils.generateFastThumbnail(this@SplitPdfResultActivity, resultFile)
+ AppUtils.generateFastThumbnail(this@PdfResultActivity, resultFile)
val result = PdfSplitResultItem(resultFile.absolutePath, thumbnails, false)
pdfScanner.addNewPdfToDatabase(result.filePath, result.thumbnailPath) {
resultList.add(result)
}
}
}
+ } else if (source == PdfPickerSource.LOCK) {
+ binding.congratulationsDesc.text = getString(R.string.set_password_successfully)
+ PdfSecurityUtils.setPasswordToPdfWithProgress(
+ filepath, password, password
+ ) { progress ->
+ binding.progressBar.progress = progress
+ binding.progressTv.text = "$progress"
+ }.let { it ->
+ if (it) {
+ PdfRepository.getInstance().updateIsPassword(filepath, true)
+ }
+ val result = PdfSplitResultItem(filePath = filepath, isPassword = true)
+ resultList.add(result)
+ }
}
withContext(Dispatchers.Main) {
binding.processingLayout.visibility = View.GONE
@@ -187,7 +224,7 @@ class SplitPdfResultActivity : BaseActivity() {
resultList[0].isSelected = true
}
adapter.updateAdapter()
- isSplitting = false//拆分结束
+ isProcessing = false//拆分结束
exitDialog?.dismissAllowingStateLoss()
exitDialog = null
}
@@ -216,12 +253,15 @@ class SplitPdfResultActivity : BaseActivity() {
override fun onDestroy() {
super.onDestroy()
+ isProcessing = false
+ exitDialog?.dismissAllowingStateLoss()
+ exitDialog = null
}
private fun setupBackPressedCallback() {
onBackPressedDispatcher.addCallback(this, object : OnBackPressedCallback(true) {
override fun handleOnBackPressed() {
- if (isSplitting) {
+ if (isProcessing) {
exitDialog = PromptDialogFragment(
getString(R.string.exit_split),
getString(R.string.confirm_discard_changes),
diff --git a/app/src/main/java/com/all/pdfreader/pro/app/ui/act/SearchActivity.kt b/app/src/main/java/com/all/pdfreader/pro/app/ui/act/SearchActivity.kt
index dda8d32..42bec52 100644
--- a/app/src/main/java/com/all/pdfreader/pro/app/ui/act/SearchActivity.kt
+++ b/app/src/main/java/com/all/pdfreader/pro/app/ui/act/SearchActivity.kt
@@ -25,6 +25,7 @@ import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.launch
import org.json.JSONArray
+import kotlin.math.log
class SearchActivity : BaseActivity() {
override val TAG: String = "SearchActivity"
@@ -87,8 +88,9 @@ class SearchActivity : BaseActivity() {
delay(150)
pdfRepository.searchDocuments(query).collectLatest { list ->
if (list.isNotEmpty()) {
- adapter.updateData(list)
- adapter.highlightItems(query.trim())
+ adapter.updateData(list) {
+ adapter.highlightItems(query.trim())
+ }
binding.noFilesLayout.visibility = View.GONE
} else {
adapter.updateData(emptyList())
diff --git a/app/src/main/java/com/all/pdfreader/pro/app/ui/act/SplitPdfActivity.kt b/app/src/main/java/com/all/pdfreader/pro/app/ui/act/SplitPdfActivity.kt
index 0c57c36..b60fee6 100644
--- a/app/src/main/java/com/all/pdfreader/pro/app/ui/act/SplitPdfActivity.kt
+++ b/app/src/main/java/com/all/pdfreader/pro/app/ui/act/SplitPdfActivity.kt
@@ -5,9 +5,7 @@ import android.content.Intent
import android.os.Bundle
import android.view.View
import androidx.activity.OnBackPressedCallback
-import androidx.lifecycle.Lifecycle
import androidx.lifecycle.lifecycleScope
-import androidx.lifecycle.repeatOnLifecycle
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.LinearLayoutManager
import com.all.pdfreader.pro.app.R
@@ -140,7 +138,7 @@ class SplitPdfActivity : BaseActivity() {
binding.splitBtn.setOnSingleClickListener {
logDebug("${selectedList.size}")
//因为图片做的路径缓存方式,所以这里直接传入整个集合到result页处理
- val intent = SplitPdfResultActivity.createIntentPdfSelectedPagesItem(
+ val intent = PdfResultActivity.createIntentPdfSelectedPagesItem(
this,
ArrayList(selectedList),
PdfPickerSource.SPLIT
diff --git a/app/src/main/java/com/all/pdfreader/pro/app/ui/adapter/SplitPdfResultAdapter.kt b/app/src/main/java/com/all/pdfreader/pro/app/ui/adapter/PdfResultAdapter.kt
similarity index 84%
rename from app/src/main/java/com/all/pdfreader/pro/app/ui/adapter/SplitPdfResultAdapter.kt
rename to app/src/main/java/com/all/pdfreader/pro/app/ui/adapter/PdfResultAdapter.kt
index 701f572..da33187 100644
--- a/app/src/main/java/com/all/pdfreader/pro/app/ui/adapter/SplitPdfResultAdapter.kt
+++ b/app/src/main/java/com/all/pdfreader/pro/app/ui/adapter/PdfResultAdapter.kt
@@ -6,7 +6,7 @@ import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.all.pdfreader.pro.app.R
-import com.all.pdfreader.pro.app.databinding.AdapterSplitSelectedResultItemBinding
+import com.all.pdfreader.pro.app.databinding.AdapterSelectedResultItemBinding
import com.all.pdfreader.pro.app.model.PdfSplitResultItem
import com.all.pdfreader.pro.app.util.AppUtils.dpToPx
import com.bumptech.glide.Glide
@@ -14,15 +14,15 @@ import com.bumptech.glide.load.resource.bitmap.CenterCrop
import com.bumptech.glide.load.resource.bitmap.RoundedCorners
import java.io.File
-class SplitPdfResultAdapter(
+class PdfResultAdapter(
private val list: MutableList
-) : RecyclerView.Adapter() {
+) : RecyclerView.Adapter() {
- inner class PdfViewHolder(val binding: AdapterSplitSelectedResultItemBinding) :
+ inner class PdfViewHolder(val binding: AdapterSelectedResultItemBinding) :
RecyclerView.ViewHolder(binding.root)
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = PdfViewHolder(
- AdapterSplitSelectedResultItemBinding.inflate(
+ AdapterSelectedResultItemBinding.inflate(
LayoutInflater.from(parent.context), parent, false
)
)
@@ -35,6 +35,11 @@ class SplitPdfResultAdapter(
.transform(CenterCrop(), RoundedCorners(8.dpToPx(holder.binding.root.context)))
.into(holder.binding.image)
}
+ if (item.isPassword) {
+ holder.binding.lockLayout.visibility = View.VISIBLE
+ } else {
+ holder.binding.lockLayout.visibility = View.GONE
+ }
holder.binding.nameTv.text = File(item.filePath).name
holder.binding.pathTv.text =
holder.binding.root.context.getString(R.string.path_details, item.filePath)
diff --git a/app/src/main/java/com/all/pdfreader/pro/app/ui/adapter/SearchPdfAdapter.kt b/app/src/main/java/com/all/pdfreader/pro/app/ui/adapter/SearchPdfAdapter.kt
index 0217c44..4ba99d4 100644
--- a/app/src/main/java/com/all/pdfreader/pro/app/ui/adapter/SearchPdfAdapter.kt
+++ b/app/src/main/java/com/all/pdfreader/pro/app/ui/adapter/SearchPdfAdapter.kt
@@ -1,6 +1,7 @@
package com.all.pdfreader.pro.app.ui.adapter
import android.annotation.SuppressLint
+import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
@@ -24,7 +25,7 @@ class SearchPdfAdapter(
private var showMoreButton: Boolean = true, // 是否显示更多按钮
private var showCheckButton: Boolean = false // 是否显示选择框按钮
) : ListAdapter(PdfDiffCallback()) {
-
+ private var searchKeyword: String? = null // 保存当前搜索关键字
inner class PdfViewHolder(val binding: AdapterPdfItemBinding) :
RecyclerView.ViewHolder(binding.root)
@@ -54,12 +55,13 @@ class SearchPdfAdapter(
holder.binding.checkBtn.visibility = if (showCheckButton) View.VISIBLE else View.GONE
holder.binding.moreBtn.visibility = if (showMoreButton) View.VISIBLE else View.GONE
+ holder.binding.deleteBtn.visibility = View.GONE
- // 文件名高亮,如果 highlightKeyword 为 null 或空字符串,就显示普通文本
- holder.binding.tvFileName.text = if (highlightKeyword.isNullOrBlank()) {
+ val keyword = highlightKeyword ?: searchKeyword
+ holder.binding.tvFileName.text = if (keyword.isNullOrBlank()) {
item.fileName
} else {
- item.fileName.toHighlightedSpannable(highlightKeyword, holder.binding.root.context.getColor(R.color.icon_sel_on_color))
+ item.fileName.toHighlightedSpannable(keyword, holder.binding.root.context.getColor(R.color.icon_sel_on_color))
}
holder.binding.tvFileSize.text = item.fileSize.toFormatFileSize()
@@ -85,14 +87,17 @@ class SearchPdfAdapter(
holder.binding.moreBtn.setOnClickListener { onMoreClick(item) }
}
- fun updateData(newList: List) {
- submitList(newList.toList())
+ fun updateData(newList: List, onComplete: (() -> Unit)? = null) {
+ submitList(newList.toList()) {
+ onComplete?.invoke()
+ }
}
/**
* 搜索场景使用:只刷新高亮,不刷新整个列表
*/
fun highlightItems(keyword: String) {
+ searchKeyword = keyword
for (i in 0 until itemCount) {
notifyItemChanged(i, keyword)
}
diff --git a/app/src/main/java/com/all/pdfreader/pro/app/ui/dialog/FileDetailsDialogFragment.kt b/app/src/main/java/com/all/pdfreader/pro/app/ui/dialog/FileDetailsDialogFragment.kt
index 991fa7a..0aa3b24 100644
--- a/app/src/main/java/com/all/pdfreader/pro/app/ui/dialog/FileDetailsDialogFragment.kt
+++ b/app/src/main/java/com/all/pdfreader/pro/app/ui/dialog/FileDetailsDialogFragment.kt
@@ -31,7 +31,7 @@ class FileDetailsDialogFragment() : BottomSheetDialogFragment() {
override fun onStart() {
super.onStart()
dialog?.window?.findViewById(com.google.android.material.R.id.design_bottom_sheet)
- ?.setBackgroundResource(R.drawable.dr_rounded_corner_12_bg_white)
+ ?.setBackgroundResource(R.drawable.dr_rc_top_12_bg_white)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
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 a859680..b247b3a 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
@@ -197,7 +197,9 @@ class ListMoreDialogFragment(val filePath: String) : BottomSheetDialogFragment()
if (pdfDocument.isPassword) {
PdfRemovePasswordDialog().show(parentFragmentManager, "PdfRemovePasswordDialog")
} else {
- PdfSetPasswordDialog().show(parentFragmentManager, "PdfSetPasswordDialog")
+ PdfSetPasswordDialog(onOkClick = { password ->
+ viewModel.setPassword(pdfDocument.filePath, password)
+ }).show(parentFragmentManager, "PdfSetPasswordDialog")
}
dismiss()
}
diff --git a/app/src/main/java/com/all/pdfreader/pro/app/ui/dialog/PdfSetPasswordDialog.kt b/app/src/main/java/com/all/pdfreader/pro/app/ui/dialog/PdfSetPasswordDialog.kt
index ed53bb2..c6c5dba 100644
--- a/app/src/main/java/com/all/pdfreader/pro/app/ui/dialog/PdfSetPasswordDialog.kt
+++ b/app/src/main/java/com/all/pdfreader/pro/app/ui/dialog/PdfSetPasswordDialog.kt
@@ -7,24 +7,17 @@ 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.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.ToastUtils
-import com.all.pdfreader.pro.app.viewmodel.PdfViewModel
-import kotlin.getValue
-class PdfSetPasswordDialog() : DialogFragment(
-
-) {
+class PdfSetPasswordDialog(
+ private val onOkClick: (password: String) -> Unit = {}
+) : DialogFragment() {
private lateinit var binding: DialogPdfSetPasswordBinding
- private val viewModel: PdfViewModel by activityViewModels()
- private lateinit var pdfDocument: PdfDocumentEntity
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
@@ -48,15 +41,9 @@ class PdfSetPasswordDialog() : DialogFragment(
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
- viewModel.pdfDocument.value?.let {
- pdfDocument = it
- binding.etPassword.showKeyboard()
- setupListeners()
- setupTextWatchers()
- } ?: run {
- showToast(getString(R.string.file_not))
- dismiss()
- }
+ binding.etPassword.showKeyboard()
+ setupListeners()
+ setupTextWatchers()
}
private fun setupListeners() {
@@ -68,7 +55,7 @@ class PdfSetPasswordDialog() : DialogFragment(
val password = binding.etPassword.text.toString()
val confirmPassword = binding.etConfirmPassword.text.toString()
if (validatePassword(password, confirmPassword)) {
- viewModel.setPassword(pdfDocument.filePath, password)
+ onOkClick(password)
dismiss()
}
}
diff --git a/app/src/main/java/com/all/pdfreader/pro/app/ui/fragment/ToolsFrag.kt b/app/src/main/java/com/all/pdfreader/pro/app/ui/fragment/ToolsFrag.kt
index 79cfdbd..200f792 100644
--- a/app/src/main/java/com/all/pdfreader/pro/app/ui/fragment/ToolsFrag.kt
+++ b/app/src/main/java/com/all/pdfreader/pro/app/ui/fragment/ToolsFrag.kt
@@ -33,5 +33,9 @@ class ToolsFrag : Fragment() {
val intent = PdfPickerActivity.createIntent(requireActivity(), PdfPickerSource.SPLIT)
startActivity(intent)
}
+ binding.lockBtn.setOnClickListener {
+ val intent = PdfPickerActivity.createIntent(requireActivity(), PdfPickerSource.LOCK)
+ startActivity(intent)
+ }
}
}
\ 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 9c8b4a6..a1667d8 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
@@ -1,23 +1,27 @@
package com.all.pdfreader.pro.app.util
+import android.graphics.pdf.PdfDocument
import com.tom_roush.pdfbox.pdmodel.PDDocument
import com.tom_roush.pdfbox.pdmodel.encryption.AccessPermission
import com.tom_roush.pdfbox.pdmodel.encryption.StandardProtectionPolicy
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.delay
+import kotlinx.coroutines.isActive
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.withContext
import java.io.File
object PdfSecurityUtils {
fun setPasswordToPdf(
- inputFilePath: String,
- userPassword: String,
- ownerPassword: String
+ inputFilePath: String, userPassword: String, ownerPassword: String
): Boolean {
return try {
PDDocument.load(File(inputFilePath)).use { document ->
val accessPermission = AccessPermission()
val protectionPolicy =
StandardProtectionPolicy(ownerPassword, userPassword, accessPermission)
- protectionPolicy.encryptionKeyLength = 256
+ protectionPolicy.encryptionKeyLength = 128
protectionPolicy.permissions = accessPermission
document.protect(protectionPolicy)
document.save(inputFilePath)
@@ -29,6 +33,44 @@ object PdfSecurityUtils {
}
}
+ suspend fun setPasswordToPdfWithProgress(
+ inputFilePath: String,
+ userPassword: String,
+ ownerPassword: String,
+ onProgress: (Int) -> Unit
+ ): Boolean = withContext(Dispatchers.IO) {
+ var success = false
+ // 假进度变量
+ var progress = 0
+ val job = launch {
+ while (isActive && progress < 98) {
+ delay(50)
+ // 专业曲线:前 80%慢,后 20%快
+ progress += when {
+ progress < 80 -> 1 // 前 80% 每次 +1
+ progress < 90 -> 2 // 80~90% 每次 +2
+ else -> 3 // 90~98% 每次 +3
+ }
+ if (progress > 98) progress = 98
+ withContext(Dispatchers.Main) {
+ onProgress(progress)
+ }
+ }
+ }
+
+ success = setPasswordToPdf(inputFilePath, userPassword, ownerPassword)
+
+ // 停止假进度
+ job.cancel()
+
+ // 最终完成直接 100%
+ withContext(Dispatchers.Main) {
+ onProgress(100)
+ }
+ success
+ }
+
+
fun removePasswordFromPdf(inputFilePath: String, password: String): Boolean {
return try {
PDDocument.load(File(inputFilePath), password).use { document ->
diff --git a/app/src/main/res/layout/activity_pdf_split_result.xml b/app/src/main/res/layout/activity_pdf_split_result.xml
index b083ca5..0626a24 100644
--- a/app/src/main/res/layout/activity_pdf_split_result.xml
+++ b/app/src/main/res/layout/activity_pdf_split_result.xml
@@ -109,6 +109,7 @@
android:textSize="20sp" />
+ tools:listitem="@layout/adapter_selected_result_item" />
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
\ 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 8852b40..c82a54a 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -29,7 +29,9 @@
Unable to access PDF file, please grant storage permission in settings
File does not exist
Lock
+ Lock PDF
Unlock
+ Unlock PDF
Eye Protect
Bookmarks
No Bookmarks Page