Commit 4ca8c937 authored by wanglei's avatar wanglei

...

parent 172606ed
...@@ -68,18 +68,32 @@ class PdfActivity : BaseActivity<ActivityPdfBinding>(), PdfView { ...@@ -68,18 +68,32 @@ class PdfActivity : BaseActivity<ActivityPdfBinding>(), PdfView {
changeNormalUI() changeNormalUI()
muPDFCore = pdfPresenter.openFile(path) muPDFCore = pdfPresenter.openFile(path)
muPDFCore?.needsPassword()
// 搜索设为空 // 搜索设为空
SearchTaskResult.set(null) SearchTaskResult.set(null)
if (muPDFCore == null) { if (muPDFCore?.needsPassword() == true) {
toast("can't open pdf") val pwd = intent.extras?.getString("pwd") ?: ""
val flag = muPDFCore?.authenticatePassword(pwd) ?: false
if (flag) {
pdfPresenter.password = pwd
pdfPageAdapter.setPassword(pwd)
createPdfUI()
binding.root.postDelayed({
pdfPresenter.iniPdfPage(path)
}, 500)
} else {
toast("unknown error")
finish()
}
} else { } else {
createPdfUI() createPdfUI()
binding.root.postDelayed({ binding.root.postDelayed({
pdfPresenter.iniPdfPage(path) pdfPresenter.iniPdfPage(path)
}, 500) }, 500)
} }
} }
override fun initListener() { override fun initListener() {
......
...@@ -42,8 +42,8 @@ object PdfBoxUtils { ...@@ -42,8 +42,8 @@ object PdfBoxUtils {
return drawableList return drawableList
} }
fun getNumberOfPages(filePath: String): Int { fun getNumberOfPages(filePath: String, password: String? = null): Int {
val document = PDDocument.load(File(filePath)) val document = if (password == null) PDDocument.load(File(filePath)) else PDDocument.load(File(filePath), password)
return document.numberOfPages return document.numberOfPages
} }
...@@ -51,9 +51,10 @@ object PdfBoxUtils { ...@@ -51,9 +51,10 @@ object PdfBoxUtils {
context: Context, context: Context,
filePath: String, filePath: String,
pageIndex: Int, pageIndex: Int,
scale: Float = 1f scale: Float = 1f,
password: String? = null
): Drawable { ): Drawable {
val document = PDDocument.load(File(filePath)) val document = if (password == null) PDDocument.load(File(filePath)) else PDDocument.load(File(filePath), password)
val renderer = PDFRenderer(document) val renderer = PDFRenderer(document)
val bitmap: Bitmap = renderer.renderImage(pageIndex, scale, ImageType.RGB, RenderDestination.EXPORT) val bitmap: Bitmap = renderer.renderImage(pageIndex, scale, ImageType.RGB, RenderDestination.EXPORT)
...@@ -115,6 +116,44 @@ object PdfBoxUtils { ...@@ -115,6 +116,44 @@ object PdfBoxUtils {
} catch (e: Exception) { } catch (e: Exception) {
} }
}
fun clearPassword(filePath: String, password: String) {
try {
PDDocument.load(File(filePath), password).use { document ->
if (document.isEncrypted) {
val ap: AccessPermission = document.getCurrentAccessPermission()
if (ap.isOwnerPermission) {
// 创建一个新的保护策略,不设置密码
val spp = StandardProtectionPolicy(
"", "",
AccessPermission.getOwnerAccessPermission()
)
document.protect(spp)
}
}
// 保存PDF文件到新的位置,没有密码保护
document.save(File(filePath))
}
} catch (e: IOException) {
e.printStackTrace()
}
}
fun checkPwd(filePath: String, password: String): Boolean {
try {
// 尝试使用提供的密码加载PDF文件
PDDocument.load(File(filePath), password).use { document ->
// 如果没有抛出异常,说明密码正确
return true
}
} catch (e: Exception) {
// 加载文件时,如果密码保护策略异常,密码可能错误
println("Incorrect password or restricted permissions.")
} catch (e: IOException) {
// 其他I/O异常处理
println("An I/O error occurred: " + e.message)
}
return false
} }
} }
\ No newline at end of file
...@@ -17,11 +17,14 @@ import java.util.concurrent.ThreadPoolExecutor ...@@ -17,11 +17,14 @@ import java.util.concurrent.ThreadPoolExecutor
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
class PdfPagerAdapter(val pdfPath: String, val itemLayout: Int = R.layout.item_pdf_pager) : class PdfPagerAdapter(
BaseQuickAdapter<PdfPageBean, PdfPagerAdapter.PdfPagerViewHolder>() { val pdfPath: String,
val itemLayout: Int = R.layout.item_pdf_pager,
) : BaseQuickAdapter<PdfPageBean, PdfPagerAdapter.PdfPagerViewHolder>() {
var mPassword: String? = null
var selectAction: ((enable: Boolean, allSelect: Boolean) -> Unit)? = null var selectAction: ((enable: Boolean, allSelect: Boolean) -> Unit)? = null
var clickAction: ((pageIndex:Int) -> Unit)? = null var clickAction: ((pageIndex: Int) -> Unit)? = null
inner class PdfPagerViewHolder(view: View) : ViewHolder(view) inner class PdfPagerViewHolder(view: View) : ViewHolder(view)
...@@ -85,7 +88,7 @@ class PdfPagerAdapter(val pdfPath: String, val itemLayout: Int = R.layout.item_p ...@@ -85,7 +88,7 @@ class PdfPagerAdapter(val pdfPath: String, val itemLayout: Int = R.layout.item_p
) { ) {
threadPoolExecutor.execute { threadPoolExecutor.execute {
runCatching { runCatching {
val drawable = PdfBoxUtils.getPdfDrawablePage(context, pdfPath, item.pageIndex, scale) val drawable = PdfBoxUtils.getPdfDrawablePage(context, pdfPath, item.pageIndex, scale, mPassword)
item.pageDrawable = drawable item.pageDrawable = drawable
itemView.post { itemView.post {
item.pageDrawable?.let { item.pageDrawable?.let {
...@@ -115,4 +118,10 @@ class PdfPagerAdapter(val pdfPath: String, val itemLayout: Int = R.layout.item_p ...@@ -115,4 +118,10 @@ class PdfPagerAdapter(val pdfPath: String, val itemLayout: Int = R.layout.item_p
} }
notifyDataSetChanged() notifyDataSetChanged()
} }
@SuppressLint("NotifyDataSetChanged")
fun setPassword(password: String) {
mPassword = password
notifyDataSetChanged()
}
} }
\ No newline at end of file
...@@ -18,6 +18,7 @@ class PdfPresenter( ...@@ -18,6 +18,7 @@ class PdfPresenter(
val pdfView: PdfView? = null val pdfView: PdfView? = null
) { ) {
private val TAG = "PdfPresenter" private val TAG = "PdfPresenter"
var password: String? = null
fun openFile(path: String): MuPDFCore? { fun openFile(path: String): MuPDFCore? {
var muPDFCore: MuPDFCore? = null var muPDFCore: MuPDFCore? = null
...@@ -36,7 +37,7 @@ class PdfPresenter( ...@@ -36,7 +37,7 @@ class PdfPresenter(
fun iniPdfPage(filePath: String) { fun iniPdfPage(filePath: String) {
val list = arrayListOf<PdfPageBean>() val list = arrayListOf<PdfPageBean>()
val number = PdfBoxUtils.getNumberOfPages(filePath) val number = PdfBoxUtils.getNumberOfPages(filePath, password)
repeat(number) { repeat(number) {
list.add(PdfPageBean(it)) list.add(PdfPageBean(it))
} }
...@@ -50,7 +51,7 @@ class PdfPresenter( ...@@ -50,7 +51,7 @@ class PdfPresenter(
try { try {
// 加载现有 PDF 文档 // 加载现有 PDF 文档
val sourceDocument = PDDocument.load(File(srcPath)) val sourceDocument = PDDocument.load(File(srcPath), password)
// 创建新的 PDF 文档 // 创建新的 PDF 文档
val newDocument = PDDocument() val newDocument = PDDocument()
......
...@@ -12,6 +12,7 @@ import com.base.pdfviewerscannerwhite.ui.document.pdf.PdfActivity ...@@ -12,6 +12,7 @@ import com.base.pdfviewerscannerwhite.ui.document.pdf.PdfActivity
import com.base.pdfviewerscannerwhite.ui.document.pdf.PdfSplitActivity import com.base.pdfviewerscannerwhite.ui.document.pdf.PdfSplitActivity
import com.base.pdfviewerscannerwhite.ui.view.DialogView.showDocumentRenameDialog import com.base.pdfviewerscannerwhite.ui.view.DialogView.showDocumentRenameDialog
import com.base.pdfviewerscannerwhite.ui.view.DialogView.showPdfDetailDialog import com.base.pdfviewerscannerwhite.ui.view.DialogView.showPdfDetailDialog
import com.base.pdfviewerscannerwhite.ui.view.DialogView.showPdfPwdDialog
import com.base.pdfviewerscannerwhite.utils.PermissionUtils.checkStorePermission import com.base.pdfviewerscannerwhite.utils.PermissionUtils.checkStorePermission
import java.io.File import java.io.File
...@@ -47,9 +48,23 @@ class DocumentFragment() : BaseFragment<FragmentDocumentBinding>(), DocumentView ...@@ -47,9 +48,23 @@ class DocumentFragment() : BaseFragment<FragmentDocumentBinding>(), DocumentView
documentPresenter.saveBookmarkChange(addRemove, path) documentPresenter.saveBookmarkChange(addRemove, path)
} }
adapter.itemClick = { item -> adapter.itemClick = { item ->
startActivity(Intent(requireContext(), PdfActivity::class.java).apply { if (type == TYPE_PDF) {
putExtra("path", item.path) if (item.state == 0) {
}) startActivity(Intent(requireContext(), PdfActivity::class.java).apply {
putExtra("path", item.path)
})
}
if (item.state == 1) {
requireContext().showPdfPwdDialog(null, item, true, verificationAction = { pwd ->
startActivity(Intent(requireContext(), PdfActivity::class.java).apply {
putExtra("path", item.path)
putExtra("pwd", pwd)
})
})
}
}
} }
adapter.moreAction = { item -> adapter.moreAction = { item ->
if (item.type == TYPE_PDF) { if (item.type == TYPE_PDF) {
......
...@@ -14,7 +14,7 @@ class SplashPresenter( ...@@ -14,7 +14,7 @@ class SplashPresenter(
private var jumpJob: Job? = null private var jumpJob: Job? = null
var loadingTime = 5L var loadingTime = 2L
/** /**
* 超时跳转 * 超时跳转
......
...@@ -34,6 +34,7 @@ import com.base.pdfviewerscannerwhite.utils.LogEx ...@@ -34,6 +34,7 @@ import com.base.pdfviewerscannerwhite.utils.LogEx
import com.base.pdfviewerscannerwhite.utils.SpStringUtils import com.base.pdfviewerscannerwhite.utils.SpStringUtils
import com.base.pdfviewerscannerwhite.utils.SpStringUtils.LAST_VIEW_KEY import com.base.pdfviewerscannerwhite.utils.SpStringUtils.LAST_VIEW_KEY
import com.base.pdfviewerscannerwhite.utils.ToastUtils.toast import com.base.pdfviewerscannerwhite.utils.ToastUtils.toast
import com.google.android.gms.dynamic.IFragmentWrapper
import com.google.android.material.bottomsheet.BottomSheetBehavior import com.google.android.material.bottomsheet.BottomSheetBehavior
import com.google.android.material.bottomsheet.BottomSheetDialog import com.google.android.material.bottomsheet.BottomSheetDialog
import java.io.File import java.io.File
...@@ -121,6 +122,12 @@ object DialogView { ...@@ -121,6 +122,12 @@ object DialogView {
documentView.deleteDocument(item) documentView.deleteDocument(item)
} }
} }
if (item.state == 1) {
binding.tvLock.text = "Unlock PDF"
}
if (item.state == 0) {
binding.tvLock.text = "Lock PDF"
}
binding.llLock.setOnClickListener { binding.llLock.setOnClickListener {
showPdfPwdDialog(dialog, item) showPdfPwdDialog(dialog, item)
} }
...@@ -179,7 +186,13 @@ object DialogView { ...@@ -179,7 +186,13 @@ object DialogView {
} }
private fun Context.showPdfPwdDialog(firstDialog: Dialog?, item: DocumentBean) { @SuppressLint("SetTextI18n")
fun Context.showPdfPwdDialog(
firstDialog: Dialog?,
item: DocumentBean,
isCheckPwd: Boolean = false,
verificationAction: ((pwd: String) -> Unit)? = null
) {
val dialog = BottomSheetDialog(this, R.style.BottomSheetDialog) val dialog = BottomSheetDialog(this, R.style.BottomSheetDialog)
val binding = DialogPdfPasswordBinding.inflate(LayoutInflater.from(this)) val binding = DialogPdfPasswordBinding.inflate(LayoutInflater.from(this))
dialog.setContentView(binding.root) dialog.setContentView(binding.root)
...@@ -195,11 +208,29 @@ object DialogView { ...@@ -195,11 +208,29 @@ object DialogView {
//展开 //展开
behavior.state = BottomSheetBehavior.STATE_EXPANDED behavior.state = BottomSheetBehavior.STATE_EXPANDED
binding.edit.requestFocus() if (!isCheckPwd) {
if (item.state == 1) {
binding.tvTittle.text = "Delete Password"
binding.tvTip.text = "Delete password, the file is not password protected"
}
if (item.state == 0) {
binding.tvTittle.text = "Set Password"
binding.tvTip.text = "Set password protection pdf"
}
} else {
binding.tvTittle.text = "Input Password"
val file = File(item.path)
binding.tvTip.text = "${file.name} password protected"
binding.tvInputTip.visibility = View.VISIBLE
}
binding.edit.requestFocus()
binding.edit.addTextChangedListener { binding.edit.addTextChangedListener {
binding.tvConfirm.isEnabled = it.toString().isNotEmpty() binding.tvConfirm.isEnabled = it.toString().isNotEmpty()
binding.tvErrorTip.visibility = View.GONE
} }
binding.tvCancel.setOnClickListener { binding.tvCancel.setOnClickListener {
dialog.dismiss() dialog.dismiss()
} }
...@@ -207,7 +238,25 @@ object DialogView { ...@@ -207,7 +238,25 @@ object DialogView {
dialog.dismiss() dialog.dismiss()
firstDialog?.dismiss() firstDialog?.dismiss()
val pwd = binding.edit.text.toString() val pwd = binding.edit.text.toString()
PdfBoxUtils.setPassword(item.path, pwd, pwd)
if (!isCheckPwd) {
if (item.state == 0) {
PdfBoxUtils.setPassword(item.path, pwd, pwd)
toast("Success Encryption")
}
if (item.state == 1) {
PdfBoxUtils.clearPassword(item.path, pwd)
toast("clear Encryption")
}
} else {
val result = PdfBoxUtils.checkPwd(item.path, pwd)
if (!result) {
binding.tvErrorTip.visibility = View.VISIBLE
return@setOnClickListener
}
verificationAction?.invoke(pwd)
}
} }
} }
......
...@@ -210,6 +210,7 @@ ...@@ -210,6 +210,7 @@
tools:ignore="ContentDescription" /> tools:ignore="ContentDescription" />
<TextView <TextView
android:id="@+id/tv_lock"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center_vertical" android:layout_gravity="center_vertical"
......
...@@ -60,7 +60,7 @@ ...@@ -60,7 +60,7 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center_vertical" android:layout_gravity="center_vertical"
android:layout_marginStart="13dp" android:layout_marginStart="13dp"
android:src="@mipmap/merge_tool" android:src="@mipmap/merge"
tools:ignore="ContentDescription" /> tools:ignore="ContentDescription" />
<TextView <TextView
......
...@@ -45,6 +45,7 @@ ...@@ -45,6 +45,7 @@
app:layout_constraintTop_toBottomOf="@id/fl"> app:layout_constraintTop_toBottomOf="@id/fl">
<TextView <TextView
android:id="@+id/tv_tip"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="16dp" android:layout_marginStart="16dp"
...@@ -54,6 +55,16 @@ ...@@ -54,6 +55,16 @@
android:textSize="18sp" android:textSize="18sp"
tools:ignore="HardcodedText" /> tools:ignore="HardcodedText" />
<TextView
android:id="@+id/tv_input_tip"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="8dp"
android:text="Enter the password to open the file"
android:visibility="gone"
tools:ignore="HardcodedText" />
<FrameLayout <FrameLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="55dp" android:layout_height="55dp"
...@@ -89,6 +100,17 @@ ...@@ -89,6 +100,17 @@
</FrameLayout> </FrameLayout>
<TextView
android:id="@+id/tv_error_tip"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="8dp"
android:text="Password Error"
android:textColor="#FA2232"
android:visibility="gone"
tools:ignore="HardcodedText" />
<LinearLayout <LinearLayout
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment