Commit a78574ea authored by wanglei's avatar wanglei

Merge remote-tracking branch 'origin/master'

parents eea6cec9 66f0c395
......@@ -35,3 +35,18 @@
java.lang.String getId();
boolean isLimitAdTrackingEnabled();
}
# 删除控制台日志打印
-assumenosideeffects class android.util.Log {
public static boolean isLoggable(java.lang.String, int);
public static int v(...);
public static int i(...);
public static int w(...);
public static int d(...);
public static int e(...);
}
-assumenosideeffects class java.io.PrintStream {
public *** println(...);
public *** print(...);
}
......@@ -162,6 +162,7 @@
<activity
android:name=".ui.document.pdf.PdfActivity"
android:exported="false"
android:launchMode="singleTask"
android:screenOrientation="portrait"
android:theme="@style/Theme.PDFViewerScannerWhite"
tools:ignore="DiscouragedApi,LockedOrientationActivity" />
......
......@@ -32,7 +32,6 @@ import com.base.pdfviewerscannerwhite.ads.admob.AdmobInterstitialUtils
import com.base.pdfviewerscannerwhite.ads.admob.AdmobNativeUtils
import com.base.pdfviewerscannerwhite.bean.ConstObject.DO_SAVE_PDF
import com.base.pdfviewerscannerwhite.bean.ConstObject.haveGuideGesture
import com.base.pdfviewerscannerwhite.bean.PdfPageBean
import com.base.pdfviewerscannerwhite.databinding.ActivityPdfBinding
import com.base.pdfviewerscannerwhite.helper.BaseActivity
import com.base.pdfviewerscannerwhite.helper.MyApplication
......@@ -86,6 +85,7 @@ class PdfActivity : BaseActivity<ActivityPdfBinding>(), PdfView {
super.onDestroy()
muPDFCore?.onDestroy()
AdmobNativeUtils.onDestroy()
pdfPageAdapter.release()
}
......@@ -108,7 +108,7 @@ class PdfActivity : BaseActivity<ActivityPdfBinding>(), PdfView {
val file = File(path)
binding.tvPdfName.text = file.name
pdfPresenter = PdfPresenter(this, this)
pdfPresenter = PdfPresenter(this)
initAdapter()
changeNormalUI()
......@@ -121,13 +121,15 @@ class PdfActivity : BaseActivity<ActivityPdfBinding>(), PdfView {
SearchTaskResult.set(null)
if (muPDFCore?.needsPassword() == true) {
val pwd = intent.extras?.getString("pwd") ?: ""
//val pwd = intent.extras?.getString("pwd") ?: ""
val flag = muPDFCore?.authenticatePassword(pwd) ?: false
if (flag) {
pdfPresenter.password = pwd
pdfPageAdapter.setPassword(pwd)
// pdfPageAdapter.setPassword(pwd)
createPdfUI()
muPDFCore?.countPages()?.let { pdfPresenter.iniPdfPage(it) }
muPDFCore?.countPages()?.let {
//pdfPresenter.iniPdfPage(it)
}
SpStringUtils.addSpString(LAST_VIEW_KEY, "${path}_/_${System.currentTimeMillis()}")
} else {
toast("unknown error")
......@@ -135,7 +137,9 @@ class PdfActivity : BaseActivity<ActivityPdfBinding>(), PdfView {
}
} else {
createPdfUI()
muPDFCore?.countPages()?.let { pdfPresenter.iniPdfPage(it) }
muPDFCore?.countPages()?.let {
//pdfPresenter.iniPdfPage(it)
}
SpStringUtils.addSpString(LAST_VIEW_KEY, "${path}_/_${System.currentTimeMillis()}")
}
......@@ -347,7 +351,9 @@ class PdfActivity : BaseActivity<ActivityPdfBinding>(), PdfView {
}
private fun initAdapter() {
pdfPageAdapter = PdfPagerAdapter(path, uri)
pdfPageAdapter = PdfPagerAdapter(path, uri, mPassword = pwd){
iniSetVerticalSeekbar(it)
}
pdfPageAdapter.clickAction = { pageIndex ->
binding.mupdfReaderView.displayedViewIndex = pageIndex
}
......@@ -361,7 +367,8 @@ class PdfActivity : BaseActivity<ActivityPdfBinding>(), PdfView {
isShowTopBottomLayout = false
hideKeyboard(binding.editSearch)
val topAnim: Animation = TranslateAnimation(0f, 0f, 0f, -binding.vAnimatorTop.height.toFloat())
val topAnim: Animation =
TranslateAnimation(0f, 0f, 0f, -binding.vAnimatorTop.height.toFloat())
topAnim.setDuration(200)
topAnim.setAnimationListener(object : Animation.AnimationListener {
override fun onAnimationStart(animation: Animation) {}
......@@ -372,7 +379,8 @@ class PdfActivity : BaseActivity<ActivityPdfBinding>(), PdfView {
})
binding.vAnimatorTop.startAnimation(topAnim)
val bottomAnim: Animation = TranslateAnimation(0f, 0f, 0f, binding.vAnimatorBottom.height.toFloat())
val bottomAnim: Animation =
TranslateAnimation(0f, 0f, 0f, binding.vAnimatorBottom.height.toFloat())
bottomAnim.duration = 200
bottomAnim.setAnimationListener(object : Animation.AnimationListener {
override fun onAnimationStart(animation: Animation) {}
......@@ -392,7 +400,8 @@ class PdfActivity : BaseActivity<ActivityPdfBinding>(), PdfView {
if (!isShowTopBottomLayout) {
isShowTopBottomLayout = true
val topAnim: Animation = TranslateAnimation(0f, 0f, -binding.vAnimatorTop.height.toFloat(), 0f)
val topAnim: Animation =
TranslateAnimation(0f, 0f, -binding.vAnimatorTop.height.toFloat(), 0f)
topAnim.setDuration(200)
topAnim.setAnimationListener(object : Animation.AnimationListener {
override fun onAnimationStart(animation: Animation) {
......@@ -405,7 +414,8 @@ class PdfActivity : BaseActivity<ActivityPdfBinding>(), PdfView {
})
binding.vAnimatorTop.startAnimation(topAnim)
val bottomAnim: Animation = TranslateAnimation(0f, 0f, binding.vAnimatorBottom.height.toFloat(), 0f)
val bottomAnim: Animation =
TranslateAnimation(0f, 0f, binding.vAnimatorBottom.height.toFloat(), 0f)
bottomAnim.duration = 200
bottomAnim.setAnimationListener(object : Animation.AnimationListener {
override fun onAnimationStart(animation: Animation) {
......@@ -602,7 +612,8 @@ class PdfActivity : BaseActivity<ActivityPdfBinding>(), PdfView {
fun switchOrientation() {
requestedOrientation = if (requestedOrientation == ActivityInfo.SCREEN_ORIENTATION_PORTRAIT) {
requestedOrientation =
if (requestedOrientation == ActivityInfo.SCREEN_ORIENTATION_PORTRAIT) {
ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE
} else {
ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
......@@ -631,10 +642,4 @@ class PdfActivity : BaseActivity<ActivityPdfBinding>(), PdfView {
const val SAVE_MODE_PAINTING_BRUSH = "Painting Brush"
}
override fun initPdfPageRv(items: List<PdfPageBean>) {
pdfPageAdapter.submitList(items)
pdfPageAdapter.changeSelectPager(0)
iniSetVerticalSeekbar(items.size)
}
}
\ No newline at end of file
......@@ -7,12 +7,15 @@ import android.graphics.drawable.Drawable
import android.net.Uri
import com.base.pdfviewerscannerwhite.helper.MyApplication.Companion.context
import com.base.pdfviewerscannerwhite.utils.LogEx
import com.base.pdfviewerscannerwhite.utils.Paths
import com.base.pdfviewerscannerwhite.utils.UriUtils.readFileToByteArray
import com.tom_roush.pdfbox.io.MemoryUsageSetting
import com.tom_roush.pdfbox.pdmodel.PDDocument
import com.tom_roush.pdfbox.pdmodel.PDPage
import com.tom_roush.pdfbox.pdmodel.PDPageContentStream
import com.tom_roush.pdfbox.pdmodel.common.PDRectangle
import com.tom_roush.pdfbox.pdmodel.encryption.AccessPermission
import com.tom_roush.pdfbox.pdmodel.encryption.InvalidPasswordException
import com.tom_roush.pdfbox.pdmodel.encryption.StandardProtectionPolicy
import com.tom_roush.pdfbox.pdmodel.graphics.image.PDImageXObject
import com.tom_roush.pdfbox.rendering.ImageType
......@@ -25,38 +28,48 @@ import java.io.IOException
object PdfBoxUtils {
private val TAG = "PdfUtils"
fun getNumberOfPages(filePath: String, password: String? = null, uri: String? = null): Int {
val document =
loadPDDocument(path = filePath, password, uri)
val number = document.numberOfPages
document.close()
return number
val memoryUsageSetting by lazy {
// MemoryUsageSetting.setupMainMemoryOnly()
// LogEx.logDebug("ttttttt","${Runtime.getRuntime().maxMemory() / 2}")
MemoryUsageSetting.setupMixed(Runtime.getRuntime().maxMemory() / 2, 512 * 1024 * 1024)
.also {
it.tempDir = Paths.cacheDir(Paths.PdfDir)
}
}
fun getPdfDrawablePage(
context: Context,
fun getPdfDocument(
filePath: String,
password: String? = null,
uri: String? = null,
): PDDocument {
return loadPDDocument(filePath, password, uri)
}
fun getPdfDrawablePage(
context: Context,
pageIndex: Int,
scale: Float = 1f,
renderer: PDFRenderer,
): Drawable {
val document = loadPDDocument(filePath, password, uri)
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)
val drawable = BitmapDrawable(context.resources, bitmap)
document.close()
return drawable
}
fun checkPdfEncryption(filePath: String = "", uri: String? = null): Int {
@Synchronized
fun checkPdfEncryption(
filePath: String = "",
uri: String? = null,
memUsageSetting: MemoryUsageSetting? = null
): Int {
var state = 0
var pdfDocument: PDDocument? = null
try {
pdfDocument = loadPDDocument(filePath, null, uri)
pdfDocument =
loadPDDocument(filePath, null, uri, memUsageSetting ?: memoryUsageSetting)
pdfDocument.use { document ->
if (document.isEncrypted) {
println("The PDF is encrypted.")
......@@ -78,9 +91,12 @@ object PdfBoxUtils {
state = 0
}
}
} catch (e: IOException) {
}catch (e: InvalidPasswordException){
e.printStackTrace()
state = 1
} catch (e: IOException) {
e.printStackTrace()
state = -1
} finally {
pdfDocument?.close()
}
......@@ -171,19 +187,37 @@ object PdfBoxUtils {
/**
* 注意一下PDDocument用完都要关闭一下
*/
private fun loadPDDocument(path: String, password: String?, uri: String? = null): PDDocument {
private fun loadPDDocument(
path: String,
password: String?,
uri: String? = null,
memUsageSetting: MemoryUsageSetting? = null
): PDDocument {
val memSet = memUsageSetting ?: MemoryUsageSetting.setupMainMemoryOnly()
return if (uri == null) {
if (password == null) {
PDDocument.load(File(path))
PDDocument.load(File(path), memSet)
} else {
PDDocument.load(File(path), password)
PDDocument.load(File(path), password, memSet)
}
} else {
if (password == null) {
PDDocument.load(readFileToByteArray(context, Uri.parse(uri)) ?: byteArrayOf())
PDDocument.load(
readFileToByteArray(context, Uri.parse(uri)) ?: byteArrayOf(),
"",
null,
null,
memSet
)
} else {
PDDocument.load(readFileToByteArray(context, Uri.parse(uri)) ?: byteArrayOf(), password)
PDDocument.load(
readFileToByteArray(context, Uri.parse(uri)) ?: byteArrayOf(),
password,
null,
null,
memSet
)
}
}
}
......
......@@ -61,6 +61,7 @@ class PdfMergeActivity : BaseActivity<ActivityPdfMergeBinding>() {
putExtra("doWhat", DO_MERGE_PDF)
putExtra("newPath", pdfPresenter.createNewPdfPath(name))
})
finish()
})
}
......
......@@ -2,10 +2,8 @@ package com.base.pdfviewerscannerwhite.ui.document.pdf
import android.annotation.SuppressLint
import android.content.Context
import android.net.Uri
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import androidx.recyclerview.widget.RecyclerView.ViewHolder
import com.base.pdfviewerscannerwhite.R
import com.base.pdfviewerscannerwhite.bean.PdfPageBean
......@@ -13,33 +11,119 @@ import com.base.pdfviewerscannerwhite.databinding.ItemPdfPagerBinding
import com.base.pdfviewerscannerwhite.databinding.ItemPdfPagerSplitBinding
import com.base.pdfviewerscannerwhite.utils.XmlEx.inflate
import com.chad.library.adapter4.BaseQuickAdapter
import java.util.concurrent.LinkedBlockingQueue
import java.util.concurrent.ThreadPoolExecutor
import java.util.concurrent.TimeUnit
import com.tom_roush.pdfbox.pdmodel.PDDocument
import com.tom_roush.pdfbox.rendering.PDFRenderer
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.MainScope
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.cancel
import kotlinx.coroutines.isActive
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
class PdfPagerAdapter(
val pdfPath: String,
val uri: String? = null,
val itemLayout: Int = R.layout.item_pdf_pager,
private val previewScale: Float = 1f,
private val mPassword: String? = null,
initCallBack: ((itemCount: Int) -> Unit)? = null
) : BaseQuickAdapter<PdfPageBean, PdfPagerAdapter.PdfPagerViewHolder>() {
var mPassword: String? = null
var selectAction: ((enable: Boolean, allSelect: Boolean) -> Unit)? = null
var clickAction: ((pageIndex: Int) -> Unit)? = null
inner class PdfPagerViewHolder(view: View) : ViewHolder(view)
var corePoolSize = 4 // 核心线程数
var maximumPoolSize = 10 // 最大线程数
var keepAliveTime: Long = 120 // 非核心线程空闲存活时间
var threadPoolExecutor = ThreadPoolExecutor(
corePoolSize,
maximumPoolSize,
keepAliveTime,
TimeUnit.SECONDS,
LinkedBlockingQueue()
// var corePoolSize = 4 // 核心线程数
// var maximumPoolSize = 10 // 最大线程数
// var keepAliveTime: Long = 120 // 非核心线程空闲存活时间
// var threadPoolExecutor = ThreadPoolExecutor(
// corePoolSize,
// maximumPoolSize,
// keepAliveTime,
// TimeUnit.SECONDS,
// LinkedBlockingQueue()
// )
private val scope = MainScope()
private var pdfDocument: PDDocument? = null
private var pdfRender: PDFRenderer? = null
private val selectPayLoad = 0
private val refreshPayLoad = 1
init {
scope.launch(SupervisorJob() + Dispatchers.IO) {
pdfDocument = PdfBoxUtils.getPdfDocument(pdfPath, mPassword, uri)
pdfRender = PDFRenderer(pdfDocument)
val dataList = mutableListOf<PdfPageBean>()
repeat(pdfDocument?.numberOfPages ?: 0) {
dataList.add(PdfPageBean(it))
}
if (dataList.isNotEmpty()) {
dataList[0].isSelect = true
}
withContext(Dispatchers.Main) {
submitList(dataList)
initCallBack?.invoke(dataList.size)
}
items.forEachIndexed { index, pdfPageBean ->
val render = pdfRender ?: return@launch
if (pdfPageBean.pageDrawable != null) return@forEachIndexed
if (!isActive) return@launch
runCatching {
val drawable = PdfBoxUtils.getPdfDrawablePage(
context, index, previewScale, render
)
pdfPageBean.pageDrawable = drawable
}.onFailure {
return@launch
}
withContext(Dispatchers.Main) {
pdfPageBean.pageDrawable?.let {
notifyItemChanged(index, refreshPayLoad)
}
}
}
}
}
override fun onBindViewHolder(
holder: PdfPagerViewHolder,
position: Int,
item: PdfPageBean?,
payloads: List<Any>
) {
if (payloads.isNotEmpty()) {
if (item == null) return
when (itemLayout) {
R.layout.item_pdf_pager -> {
val binding = ItemPdfPagerBinding.bind(holder.itemView)
if (payloads[0] == 0) {
binding.tvPagerIndex.isSelected = item.isSelect
binding.tvPagerIndex.text = (item.pageIndex + 1).toString()
binding.flBorder.isSelected = item.isSelect
} else if (payloads[0] == 1) {
binding.ivPager.setImageDrawable(item.pageDrawable)
}
}
R.layout.item_pdf_pager_split -> {
val binding = ItemPdfPagerSplitBinding.bind(holder.itemView)
if (payloads[0] == 0) {
binding.ivSelector.isSelected = item.isSelect
} else if (payloads[0] == 1) {
binding.ivPager.setImageDrawable(item.pageDrawable)
}
}
}
} else
super.onBindViewHolder(holder, position, item, payloads)
}
@SuppressLint("SetTextI18n")
override fun onBindViewHolder(holder: PdfPagerViewHolder, position: Int, item: PdfPageBean?) {
......@@ -47,16 +131,13 @@ class PdfPagerAdapter(
when (itemLayout) {
R.layout.item_pdf_pager -> {
val binding = ItemPdfPagerBinding.bind(holder.itemView)
val context = holder.itemView.context
binding.tvPagerIndex.isSelected = item.isSelect
binding.tvPagerIndex.text = (item.pageIndex + 1).toString()
binding.flBorder.isSelected = item.isSelect
if (item.pageDrawable != null) {
//if (item.pageDrawable != null) {
binding.ivPager.setImageDrawable(item.pageDrawable)
} else {
loadPagerDrawable(context, item, binding.root, binding.ivPager)
}
// }
binding.root.setOnClickListener {
clickAction?.invoke(item.pageIndex)
}
......@@ -65,14 +146,12 @@ class PdfPagerAdapter(
R.layout.item_pdf_pager_split -> {
val binding = ItemPdfPagerSplitBinding.bind(holder.itemView)
binding.ivSelector.isSelected = item.isSelect
if (item.pageDrawable != null) {
// if (item.pageDrawable != null) {
binding.ivPager.setImageDrawable(item.pageDrawable)
} else {
loadPagerDrawable(context, item, binding.root, binding.ivPager, 1.5f)
}
//}
binding.ivSelector.setOnClickListener {
item.isSelect = !item.isSelect
notifyItemChanged(position, "aaa")
notifyItemChanged(position, selectPayLoad)
selectAction?.invoke(items.any { it.isSelect }, items.all { it.isSelect })
}
}
......@@ -81,28 +160,11 @@ class PdfPagerAdapter(
}
private fun loadPagerDrawable(
override fun onCreateViewHolder(
context: Context,
item: PdfPageBean,
itemView: View,
iv: ImageView,
scale: Float = 1f
) {
threadPoolExecutor.execute {
runCatching {
val drawable = PdfBoxUtils.getPdfDrawablePage(context, pdfPath, mPassword, uri, item.pageIndex, scale)
item.pageDrawable = drawable
itemView.post {
item.pageDrawable?.let {
iv.setImageDrawable(it)
}
}
}
}
}
override fun onCreateViewHolder(context: Context, parent: ViewGroup, viewType: Int): PdfPagerViewHolder {
parent: ViewGroup,
viewType: Int
): PdfPagerViewHolder {
return PdfPagerViewHolder(itemLayout.inflate(parent))
}
......@@ -121,9 +183,10 @@ class PdfPagerAdapter(
notifyDataSetChanged()
}
@SuppressLint("NotifyDataSetChanged")
fun setPassword(password: String) {
mPassword = password
notifyDataSetChanged()
fun release() {
scope.cancel()
pdfRender = null
pdfDocument?.close()
pdfDocument = null
}
}
\ No newline at end of file
......@@ -7,7 +7,6 @@ import com.artifex.mupdfdemo.MuPDFCore
import com.artifex.mupdfdemo.OutlineActivityData
import com.base.pdfviewerscannerwhite.R
import com.base.pdfviewerscannerwhite.bean.ConstObject.MIME_TYPE_PDF
import com.base.pdfviewerscannerwhite.bean.PdfPageBean
import com.base.pdfviewerscannerwhite.ui.document.pdf.PdfMergeActivity.Companion.mergePdfList
import com.base.pdfviewerscannerwhite.utils.LogEx
import com.base.pdfviewerscannerwhite.utils.UriUtils.readFileToByteArray
......@@ -17,8 +16,7 @@ import java.io.File
class PdfPresenter(
val context: Context,
val pdfView: PdfView? = null
val context: Context
) {
private val TAG = "PdfPresenter"
var password: String? = null
......@@ -41,25 +39,6 @@ class PdfPresenter(
return muPDFCore
}
fun iniPdfPage(filePath: String, uri: String? = null) {
val list = arrayListOf<PdfPageBean>()
val number = PdfBoxUtils.getNumberOfPages(filePath, password, uri)
repeat(number) {
list.add(PdfPageBean(it))
}
pdfView?.initPdfPageRv(list)
}
fun iniPdfPage(pageCount: Int) {
val list = arrayListOf<PdfPageBean>()
repeat(pageCount) {
list.add(PdfPageBean(it))
}
pdfView?.initPdfPageRv(list)
}
fun splitPdf(
srcPath: String,
newPath: String,
......@@ -118,7 +97,10 @@ class PdfPresenter(
private fun createAppDocumentDir(): File {
val appName = context.resources.getString(R.string.app_name)
val appDir = File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS), appName)
val appDir = File(
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS),
appName
)
if (!appDir.exists()) {
appDir.mkdirs()
}
......
......@@ -4,7 +4,6 @@ import android.content.Intent
import androidx.activity.addCallback
import com.base.pdfviewerscannerwhite.R
import com.base.pdfviewerscannerwhite.bean.ConstObject
import com.base.pdfviewerscannerwhite.bean.PdfPageBean
import com.base.pdfviewerscannerwhite.databinding.ActivityPdfSplitBinding
import com.base.pdfviewerscannerwhite.helper.BaseActivity
import com.base.pdfviewerscannerwhite.helper.MyApplication
......@@ -30,7 +29,7 @@ class PdfSplitActivity : BaseActivity<ActivityPdfSplitBinding>(), PdfView {
}
override fun initView() {
pdfPresenter = PdfPresenter(this, this)
pdfPresenter = PdfPresenter(this)
path = intent.extras?.getString("path", "") ?: ""
pwd = intent.extras?.getString("pwd", "") ?: ""
uri = intent.extras?.getString("uri")
......@@ -40,7 +39,7 @@ class PdfSplitActivity : BaseActivity<ActivityPdfSplitBinding>(), PdfView {
initAdapter()
pdfPresenter.iniPdfPage(path, uri)
//pdfPresenter.iniPdfPage(path, uri)
}
override fun initListener() {
......@@ -71,8 +70,7 @@ class PdfSplitActivity : BaseActivity<ActivityPdfSplitBinding>(), PdfView {
}
private fun initAdapter() {
pdfPagerAdapter = PdfPagerAdapter(path, null, R.layout.item_pdf_pager_split)
pdfPagerAdapter.mPassword = pwd
pdfPagerAdapter = PdfPagerAdapter(path, null, R.layout.item_pdf_pager_split, 1.5f, mPassword = pwd)
pdfPagerAdapter.selectAction = { enable, allSelect ->
binding.tvBtnSplit.isEnabled = enable
binding.ivSelector.isSelected = allSelect
......@@ -81,8 +79,8 @@ class PdfSplitActivity : BaseActivity<ActivityPdfSplitBinding>(), PdfView {
}
override fun initPdfPageRv(items: List<PdfPageBean>) {
pdfPagerAdapter.submitList(items)
override fun onDestroy() {
super.onDestroy()
pdfPagerAdapter.release()
}
}
\ No newline at end of file
package com.base.pdfviewerscannerwhite.ui.document.pdf
import com.base.pdfviewerscannerwhite.bean.PdfPageBean
interface PdfView {
fun initPdfPageRv(items: List<PdfPageBean>)
fun jumpPage(pageIndex: Int) = Unit
fun jumpSplit() = Unit
......
......@@ -148,8 +148,9 @@ class DocumentFragment(
currentPage.refreshData()
}
}
binding.tvTittle.setOnClickListener {
if (BuildConfig.DEBUG) {
binding.tvTittle.setOnClickListener {
android.os.Process.killProcess(android.os.Process.myPid());
System.exit(0);
}
......@@ -244,7 +245,7 @@ class DocumentFragment(
fun changeSelectUI(show: Boolean) {
if (show) {
binding.viewPager2.isUserInputEnabled = false
(requireActivity() as MainActivity).callback.isEnabled = true
//(requireActivity() as MainActivity).callback.isEnabled = true
uiMode = UI_MODE_SELECT
binding.ivPaixu.visibility = View.INVISIBLE
......@@ -260,7 +261,7 @@ class DocumentFragment(
currentPage.changeSelectUi(true)
} else {
binding.viewPager2.isUserInputEnabled = true
(requireActivity() as MainActivity).callback.isEnabled = false
// (requireActivity() as MainActivity).callback.isEnabled = false
uiMode = UI_MODE_NORMAL
binding.flFanhui.visibility = View.INVISIBLE
binding.ivAllSelector.visibility = View.INVISIBLE
......@@ -289,7 +290,7 @@ class DocumentFragment(
fun changeSearchUI(show: Boolean) {
if (show) {
uiMode = UI_MODE_SEARCH
(requireActivity() as MainActivity).callback.isEnabled = true
// (requireActivity() as MainActivity).callback.isEnabled = true
binding.card.elevation = 0f
binding.tvTittle.visibility = View.INVISIBLE
......@@ -309,7 +310,7 @@ class DocumentFragment(
} else {
uiMode = UI_MODE_NORMAL
(requireActivity() as MainActivity).callback.isEnabled = false
// (requireActivity() as MainActivity).callback.isEnabled = false
binding.card.elevation = resources.getDimension(R.dimen.dp_5)
binding.editSearch.visibility = View.INVISIBLE
......
......@@ -13,6 +13,7 @@ import com.base.pdfviewerscannerwhite.utils.getMediaFile
import com.base.pdfviewerscannerwhite.utils.upDateDemoStore
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import java.io.File
class DocumentPresenter(
......@@ -37,19 +38,23 @@ class DocumentPresenter(
if (type == DocumentBean.TYPE_PDF) {
selectionArgs = arrayOf(ConstObject.MIME_TYPE_PDF)
demoDocumentBean.path = demoFile.listFiles()?.find { it.name.contains(".pdf") }?.absolutePath ?: ""
demoDocumentBean.path =
demoFile.listFiles()?.find { it.name.contains(".pdf") }?.absolutePath ?: ""
}
if (type == DocumentBean.TYPE_WORD) {
selectionArgs = arrayOf(ConstObject.MIME_TYPE_DOC, ConstObject.MIME_TYPE_DOCX)
demoDocumentBean.path = demoFile.listFiles()?.find { it.name.contains(".docx") }?.absolutePath ?: ""
demoDocumentBean.path =
demoFile.listFiles()?.find { it.name.contains(".docx") }?.absolutePath ?: ""
}
if (type == DocumentBean.TYPE_EXCEL) {
selectionArgs = arrayOf(ConstObject.MIME_TYPE_XLS, ConstObject.MIME_TYPE_XLSX)
demoDocumentBean.path = demoFile.listFiles()?.find { it.name.contains(".xlsx") }?.absolutePath ?: ""
demoDocumentBean.path =
demoFile.listFiles()?.find { it.name.contains(".xlsx") }?.absolutePath ?: ""
}
if (type == DocumentBean.TYPE_PPT) {
selectionArgs = arrayOf(ConstObject.MIME_TYPE_PPT, ConstObject.MIME_TYPE_PPTX)
demoDocumentBean.path = demoFile.listFiles()?.find { it.name.contains(".pptx") }?.absolutePath ?: ""
demoDocumentBean.path =
demoFile.listFiles()?.find { it.name.contains(".pptx") }?.absolutePath ?: ""
}
demoDocumentBean.type = type
......@@ -57,7 +62,12 @@ class DocumentPresenter(
val list = context.getMediaFile(selectionArgs = selectionArgs)
val documentList = list.map {
DocumentBean(it.path, uri = it.uri, type = type, isBookmarked = bookmarkList.contains(it.path))
DocumentBean(
it.path,
uri = it.uri,
type = type,
isBookmarked = bookmarkList.contains(it.path)
)
}
val new = documentList.toMutableList()
if (File(demoDocumentBean.path).exists()) {
......@@ -68,31 +78,45 @@ class DocumentPresenter(
fun initData() = lifecycleScope.launch(Dispatchers.IO) {
val documentList = getDocumentBeanList()
launch(Dispatchers.Main) {
documentView.refreshDocumentRv(documentList)
val realList = documentList.filter {
val file = File(it.path)
file.exists() && file.length() > 0
}
realList.forEach {
it.state = PdfBoxUtils.checkPdfEncryption(it.path)
}
withContext(Dispatchers.Main) {
documentView.refreshDocumentRv(realList)
}
}
fun initUnLockData() = lifecycleScope.launch(Dispatchers.IO) {
val documentList = getDocumentBeanList()
documentList.forEach {
val realList = documentList.filter {
val file = File(it.path)
file.exists() && file.length() > 0
}
realList.forEach {
it.state = PdfBoxUtils.checkPdfEncryption(it.path)
}
val list = documentList.filter { it.state == 0 }
launch(Dispatchers.Main) {
val list = realList.filter { it.state == 0 }
withContext(Dispatchers.Main) {
documentView.refreshDocumentRv(list)
}
}
fun initLoadData() = lifecycleScope.launch(Dispatchers.IO) {
val documentList = getDocumentBeanList()
documentList.forEach {
val realList= documentList.filter {
val file = File(it.path)
file.exists() && file.length() > 0
}
realList.forEach {
it.state = PdfBoxUtils.checkPdfEncryption(it.path)
}
val list = documentList.filter { it.state == 1 }
launch(Dispatchers.Main) {
val list = realList.filter { it.state == 1 }
withContext(Dispatchers.Main) {
documentView.refreshDocumentRv(list)
}
}
......
......@@ -326,18 +326,9 @@ class MainActivity : BaseActivity<ActivityMainBinding>(), MainView {
var isBookmarkAdd: Boolean = false
var isToolAdd: Boolean = false
@SuppressLint("MissingSuperCall")
override fun onBackPressed() {
LogEx.logDebug(TAG, "onBackPressed")
showAppExitDialog()
}
//OnBackPressedCallback 并将 isEnabled 设置为 false 时,默认的返回键行为将被禁用。
lateinit var callback: OnBackPressedCallback
override fun initListener() {
super.initListener()
callback = object : OnBackPressedCallback(false) {
val callback: OnBackPressedCallback by lazy(LazyThreadSafetyMode.NONE) {
object : OnBackPressedCallback(true) {
override fun handleOnBackPressed() {
LogEx.logDebug(TAG, "handleOnBackPressed")
if (currentFragment is DocumentFragment) {
......@@ -345,13 +336,20 @@ class MainActivity : BaseActivity<ActivityMainBinding>(), MainView {
LogEx.logDebug(TAG, "handleOnBackPressed uiMode=${documentFragment.uiMode}")
if (documentFragment.uiMode == ConstObject.UI_MODE_SELECT) {
documentFragment.changeSelectUI(false)
return
}
if (documentFragment.uiMode == ConstObject.UI_MODE_SEARCH) {
documentFragment.changeSearchUI(false)
return
}
}
showAppExitDialog()
}
}
}
override fun initListener() {
super.initListener()
onBackPressedDispatcher.addCallback(callback)
binding.llDocument.setOnClickListener {
......
......@@ -71,9 +71,10 @@ class MainPresenter(
var mainRefreshData: Boolean = false
}
fun initAllDocumentData() = lifecycleScope.launch(Dispatchers.IO) {
fun initAllDocumentData() {
if (!mainRefreshData) {
mainRefreshData = true
lifecycleScope.launch(Dispatchers.IO) {
val start = System.currentTimeMillis()
Log.d("glc", "pdfs 清理前:" + pdfDocuments.size)
context.upDateDemoStore()
......@@ -82,7 +83,17 @@ class MainPresenter(
ConstObject.haveSaveDemo = true
}
val pdfs = initAllPdfData()
pdfs.map { it.state = PdfBoxUtils.checkPdfEncryption(it.path) }
val largePdf = mutableListOf<DocumentBean>()
pdfs.map {
it.state = PdfBoxUtils.checkPdfEncryption(
it.path,
memUsageSetting = PdfBoxUtils.memoryUsageSetting.getPartitionedCopy(pdfs.size)
)
if (it.state == -1) largePdf.add(it)
}
largePdf.map {
it.state = PdfBoxUtils.checkPdfEncryption(it.path)
}
pdfDocuments.clear()
wordDocuments.clear()
excelDocuments.clear()
......@@ -93,12 +104,13 @@ class MainPresenter(
wordDocuments.addAll(initAllWordData())
excelDocuments.addAll(initAllExcelData())
pptDocuments.addAll(initAllPptData())
mainRefreshData = false
withContext(Dispatchers.Main) {
val end = System.currentTimeMillis()
val time = end - start
LogEx.logDebug(TAG, "time=$time")
mainView.refreshPageList()
mainRefreshData = false
}
}
}
}
......@@ -113,10 +125,18 @@ class MainPresenter(
when (documentType) {
TYPE_PDF -> {
val data = arrayListOf<DocumentBean>()
val largeData = mutableListOf<DocumentBean>()
data.addAll(pdfDocuments)
data.forEach {
it.isBookmarked = bookmarkList.contains(it.path)
it.state = PdfBoxUtils.checkPdfEncryption(
it.path,
memUsageSetting = PdfBoxUtils.memoryUsageSetting.getPartitionedCopy(data.size)
)
if (it.state == -1) largeData.add(it)
}
largeData.forEach {
it.state = PdfBoxUtils.checkPdfEncryption(it.path)
}
when (dataType) {
......@@ -240,7 +260,10 @@ class MainPresenter(
val list = context.getMediaFile(selectionArgs = selectionArgs)
val documentList = list.map {
val documentList = list.filter {
val file = File(it.path)
file.exists() && file.length() > 0f
}.map {
DocumentBean(it.path, uri = it.uri, type = TYPE_PDF)
}
val new = documentList.toMutableList()
......
......@@ -2,10 +2,13 @@ package com.base.pdfviewerscannerwhite.ui.permission
import android.annotation.SuppressLint
import android.graphics.Color
import android.os.Build
import android.os.Environment
import android.text.SpannableString
import android.text.SpannableStringBuilder
import android.text.style.ForegroundColorSpan
import androidx.activity.addCallback
import androidx.annotation.RequiresApi
import androidx.core.content.ContextCompat
import androidx.core.view.updatePadding
import com.base.pdfviewerscannerwhite.R
......@@ -13,6 +16,9 @@ import com.base.pdfviewerscannerwhite.databinding.ActivityPermissionBinding
import com.base.pdfviewerscannerwhite.helper.BaseActivity
import com.base.pdfviewerscannerwhite.utils.BarUtils
import com.base.pdfviewerscannerwhite.utils.PermissionUtils.requestStoragePermission
import kotlinx.coroutines.MainScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
class PermissionActivity : BaseActivity<ActivityPermissionBinding>() {
......@@ -52,10 +58,25 @@ class PermissionActivity : BaseActivity<ActivityPermissionBinding>() {
onBackPressedDispatcher.onBackPressed()
}
binding.tvAllow.setOnClickListener {
requestStoragePermission(launcher) {
requestStoragePermission(launcher, jumpAction = {
MainScope().launch {
if(!delayOpen()){
delayOpen()
}
}
}) {
onBackPressedDispatcher.onBackPressed()
}
}
}
@RequiresApi(Build.VERSION_CODES.R)
private suspend fun delayOpen():Boolean{
delay(600)
if (Environment.isExternalStorageManager()) {
onBackPressedDispatcher.onBackPressed()
return true
}
return false
}
}
\ No newline at end of file
......@@ -9,6 +9,7 @@ import android.content.Intent
import android.graphics.Color
import android.net.Uri
import android.os.Build
import android.os.Environment
import android.text.SpannableString
import android.text.SpannableStringBuilder
import android.text.style.ForegroundColorSpan
......@@ -52,7 +53,6 @@ import com.base.pdfviewerscannerwhite.utils.KotlinExt.toFormatSize
import com.base.pdfviewerscannerwhite.utils.KotlinExt.toFormatTime2
import com.base.pdfviewerscannerwhite.utils.KotlinExt.toFormatTime3
import com.base.pdfviewerscannerwhite.utils.KotlinExt.toFormatTime4
import com.base.pdfviewerscannerwhite.utils.PermissionUtils.checkNotificationPermission
import com.base.pdfviewerscannerwhite.utils.PermissionUtils.checkStorePermission
import com.base.pdfviewerscannerwhite.utils.PermissionUtils.requestStoragePermission
import com.base.pdfviewerscannerwhite.utils.SpStringUtils
......@@ -60,6 +60,9 @@ import com.base.pdfviewerscannerwhite.utils.SpStringUtils.LAST_VIEW_KEY
import com.base.pdfviewerscannerwhite.utils.ToastUtils.toast
import com.google.android.material.bottomsheet.BottomSheetBehavior
import com.google.android.material.bottomsheet.BottomSheetDialog
import kotlinx.coroutines.MainScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import java.io.File
object DialogView {
......@@ -84,7 +87,19 @@ object DialogView {
binding.tvSet.setOnClickListener {
dialog.dismiss()
requestStoragePermission(launcher) {
requestStoragePermission(launcher, {
MainScope().launch {
delay(600)
if (Environment.isExternalStorageManager()) {
startActivity(Intent(this@showStoragePermission, MainActivity::class.java))
}else{
delay(600)
if (Environment.isExternalStorageManager()) {
startActivity(Intent(this@showStoragePermission, MainActivity::class.java))
}
}
}
}) {
launcherAction?.invoke(it)
}
}
......@@ -196,7 +211,8 @@ object DialogView {
val file = File(path)
binding.tvName.text = file.name
binding.tvPath.text = file.absolutePath
val lastView = SpStringUtils.getSpStringList(LAST_VIEW_KEY).find { it.contains(file.absolutePath) }
val lastView =
SpStringUtils.getSpStringList(LAST_VIEW_KEY).find { it.contains(file.absolutePath) }
if (lastView != null) {
val lastTime = lastView.split("_/_")[1]
binding.tvLastView.text = lastTime.toLong().toFormatTime3()
......@@ -233,7 +249,8 @@ object DialogView {
val file = File(item.path)
binding.tvName.text = file.name
binding.tvInfo.text = file.lastModified().toFormatTime4() + " " + file.length().toFormatSize()
binding.tvInfo.text =
file.lastModified().toFormatTime4() + " " + file.length().toFormatSize()
if (item.isBookmarked) {
binding.ivBookmark.setImageResource(R.mipmap.h_soucang_s)
} else {
......
package com.base.pdfviewerscannerwhite.utils
import android.net.Uri
import androidx.core.net.toUri
import com.base.pdfviewerscannerwhite.helper.MyApplication
import java.io.File
object Paths {
const val PdfDir = "pdf"
/**
* 应用存储文件的文件夹 (不需要读写权限)
* @name 子文件夹名称
*/
fun fileDir(name: String): File? {
return runCatching {
(MyApplication.context.getExternalFilesDir(name)?.apply {
if (!exists() || !isDirectory) {
mkdirs()
}
}) ?: (MyApplication.context.filesDir?.let {
File(it, name).apply {
if (!exists() || !isDirectory) {
mkdirs()
}
}
})
}.getOrNull()
}
/**
* 应用缓存文件夹 (不需要读写权限)
* @name 子文件夹名称
*/
fun cacheDir(name: String): File? {
return runCatching {
val dir = MyApplication.context.externalCacheDir ?: MyApplication.context.cacheDir
dir?.let {
File(it, name).apply {
if (!exists() || !isDirectory) {
mkdirs()
}
}
}
}.getOrNull()
}
fun String.toUriCompat(): Uri {
var uri = this.toUri()
if (uri.scheme.isNullOrEmpty()) {
uri = "file://$this".toUri()
}
return uri
}
}
\ No newline at end of file
......@@ -32,7 +32,7 @@ object ShortcutUtils {
.setShortLabel("Split Pdf")
.setIcon(Icon.createWithResource(this, R.mipmap.chaifen_shortcut))
.setIntent(Intent(Intent.ACTION_MAIN, null, this, SplashActivity::class.java).apply {
putExtra("actionId", ConstObject.SHORTCUT_MERGE_PDF)
putExtra("actionId", ConstObject.SHORTCUT_SPLIT_PDF)
})
.build()
......
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="splash.theme" parent="Theme.AppCompat.DayNight.NoActionBar">
<style name="splash.theme" parent="Base.Theme.PDFViewerScannerWhite">
<item name="android:windowBackground">@drawable/splash_bp</item>
<item name="android:windowFullscreen">false</item>
<item name="android:forceDarkAllowed">false</item>
<item name="android:navigationBarColor">@android:color/transparent</item>
<item name="android:statusBarColor">@android:color/transparent</item>
</style>
</resources>
\ No newline at end of file
......@@ -7,7 +7,7 @@
<style name="Theme.PDFViewerScannerWhite" parent="Base.Theme.PDFViewerScannerWhite" />
<style name="splash.theme" parent="Theme.AppCompat.DayNight.NoActionBar">
<style name="splash.theme" parent="Base.Theme.PDFViewerScannerWhite">
<item name="android:windowBackground">@drawable/splash_bp</item>
<item name="android:windowFullscreen">false</item>
</style>
......
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