V1.2(3)fragment的无参构造,dialogFragment的安全显示,恢复中和删除中的调用避免内存泄漏

This commit is contained in:
litingting 2026-01-06 18:50:16 +08:00
parent 0c1980da94
commit 0f0a3301d2
22 changed files with 230 additions and 101 deletions

View File

@ -19,8 +19,8 @@ android {
applicationId = "com.ux.video.file.filerecovery"
minSdk = 24
targetSdk = 36
versionCode = 2
versionName = "1.1"
versionCode = 3
versionName = "1.2"
project.setProperty("archivesBaseName", "File Recovery Tool" + versionName + "(${versionCode})_$timestamp")
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
}

View File

@ -74,6 +74,12 @@
-keep class kotlinx.android.parcel.Parcelize
-keep class kotlin.Metadata { *; }
# 保留所有 Fragment 空构造函数
-keep class * extends androidx.fragment.app.Fragment {
public <init>();
}

View File

@ -22,9 +22,11 @@
tools:targetApi="31">
<activity
android:name=".settings.PrivacyPolicyActivity"
android:screenOrientation="portrait"
android:exported="false" />
<activity
android:name=".settings.SetupActivity"
android:screenOrientation="portrait"
android:exported="false" />
<activity
android:name=".welcome.SplashActivity"

View File

@ -18,10 +18,14 @@ import com.ux.video.file.filerecovery.databinding.DialogRecoveringBinding
*/
abstract class BaseIngDialogFragment() : DialogFragment() {
var total: Int = 0
var completeListener: ((number: Int) -> Unit)? = null
private lateinit var binding: DialogRecoveringBinding
private var _binding: DialogRecoveringBinding? = null
protected val binding get() = _binding!!
private var countDownTimer: CountDownTimer? = null
override fun onStart() {
super.onStart()
dialog?.setCanceledOnTouchOutside(false)
@ -40,15 +44,15 @@ abstract class BaseIngDialogFragment() : DialogFragment() {
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
binding = DialogRecoveringBinding.inflate(inflater)
_binding = DialogRecoveringBinding.inflate(inflater)
initUi(binding)
binding.run {
if (total < 20) {
val defaultTimer = 2000L
object : CountDownTimer(defaultTimer, 200) {
countDownTimer = object : CountDownTimer(defaultTimer, 200) {
override fun onFinish() {
progressBar.progress = 100
completeListener?.invoke(total)
// completeListener?.invoke(total)
}
override fun onTick(millisUntilFinished: Long) {
@ -57,7 +61,8 @@ abstract class BaseIngDialogFragment() : DialogFragment() {
progressBar.progress = i
}
}.start()
}.also { it.start() }
}
}
@ -69,6 +74,7 @@ abstract class BaseIngDialogFragment() : DialogFragment() {
@SuppressLint("SetTextI18n")
fun updateProgress(number: Int) {
val b = _binding ?: return
binding.tvRecoverNumber.text = "${number}/"
if (total < 20) {
return
@ -81,9 +87,15 @@ abstract class BaseIngDialogFragment() : DialogFragment() {
binding.progressBar.progress = progress
if (progress == 100) {
completeListener?.invoke(number)
// completeListener?.invoke(number)
}
}
override fun onDestroyView() {
countDownTimer?.cancel()
countDownTimer = null
_binding = null
super.onDestroyView()
}
}

View File

@ -103,8 +103,7 @@ class DetailsActivity : BaseActivity<ActivityDetailsBinding>() {
myData?.let { myData ->
RecoverOrDeleteManager.showConfirmDeleteDialog(
true,
supportFragmentManager,
lifecycleScope,
this@DetailsActivity,
setOf(myData)
) { count ->
complete(count, 1)
@ -128,8 +127,7 @@ class DetailsActivity : BaseActivity<ActivityDetailsBinding>() {
text = getString(R.string.recover)
setOnClickListener {
RecoverOrDeleteManager.showRecoveringDialog(
supportFragmentManager,
lifecycleScope,
this@DetailsActivity,
setOf(myData)
) { count ->
complete(count, 0)

View File

@ -19,6 +19,7 @@ import com.ux.video.file.filerecovery.databinding.ActivityMainBinding
import com.ux.video.file.filerecovery.recovery.RecoveryActivity
import com.ux.video.file.filerecovery.settings.SetupActivity
import com.ux.video.file.filerecovery.utils.Common
import com.ux.video.file.filerecovery.utils.ExtendFunctions.safeShow
import com.ux.video.file.filerecovery.utils.FileType
import com.ux.video.file.filerecovery.utils.ScanManager
@ -168,7 +169,8 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
private fun requestPermission() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
dialogPermission = dialogPermission ?: PermissionDialogFragment {
dialogPermission = dialogPermission ?: PermissionDialogFragment()
dialogPermission?.onClickAllow = {
try {
val intent =
Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION).apply {
@ -181,7 +183,9 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
}
isRequestPermission = true
}
dialogPermission?.show(supportFragmentManager, "")
dialogPermission?.safeShow(supportFragmentManager, Common.TAG_DIALOG_PERMISSION)
} else {
requestPermissionLauncher.launch(
arrayOf(

View File

@ -10,9 +10,11 @@ import androidx.fragment.app.DialogFragment
import com.ux.video.file.filerecovery.databinding.DialogPermissionBinding
class PermissionDialogFragment(val onClickAllow: () -> Unit) : DialogFragment() {
class PermissionDialogFragment() : DialogFragment() {
private lateinit var binding: DialogPermissionBinding
lateinit var onClickAllow: () -> Unit
override fun onStart() {
super.onStart()
dialog?.window?.apply {
@ -27,7 +29,7 @@ class PermissionDialogFragment(val onClickAllow: () -> Unit) : DialogFragment()
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
): View {
binding = DialogPermissionBinding.inflate(inflater)
binding.run {
cancel.setOnClickListener { dismiss() }

View File

@ -250,8 +250,7 @@ class RecoveredFragment : BaseFragment<FragmentRecoveryPhotoBinding>() {
layoutBottom.tvLeft.setOnClickListener {
selectedList?.let {
RecoverOrDeleteManager.showConfirmDeleteDialog(
fragmentManager = requireActivity().supportFragmentManager,
scope = lifecycleScope,
activity =requireActivity(),
selectedSetList = it
) { count ->
val removeSelectedFromSizeList =

View File

@ -11,9 +11,10 @@ import com.ux.video.file.filerecovery.databinding.DialogExitBinding
import com.ux.video.file.filerecovery.databinding.DialogPermissionBinding
class ExitDialogFragment(val onClickExit: () -> Unit) : DialogFragment() {
class ExitDialogFragment() : DialogFragment() {
private lateinit var binding: DialogExitBinding
lateinit var onClickExit: () -> Unit
override fun onStart() {
super.onStart()
dialog?.window?.apply {

View File

@ -12,6 +12,7 @@ import com.ux.video.file.filerecovery.db.ResultData
import com.ux.video.file.filerecovery.db.ResultDataFiles
import com.ux.video.file.filerecovery.sort.SortingActivity
import com.ux.video.file.filerecovery.utils.Common
import com.ux.video.file.filerecovery.utils.ExtendFunctions.safeShow
import com.ux.video.file.filerecovery.utils.FileType
import com.ux.video.file.filerecovery.utils.ScanType
@ -85,11 +86,15 @@ class ScanResultDisplayActivity : BaseActivity<ActivityScanResultDisplayBinding>
}
}
}
private fun dealExit() {
exitDialog = exitDialog ?: ExitDialogFragment {
exitDialog = exitDialog ?: ExitDialogFragment()
exitDialog?.onClickExit = {
finish()
}
exitDialog?.show(supportFragmentManager, "")
exitDialog?.safeShow(supportFragmentManager, Common.TAG_DIALOG_EXIT)
}
private fun setSelectTypeTitle(fileType: FileType) {

View File

@ -1,15 +1,30 @@
package com.ux.video.file.filerecovery.sort
import androidx.fragment.app.FragmentManager
import com.ux.video.file.filerecovery.R
import com.ux.video.file.filerecovery.base.BaseIngDialogFragment
import com.ux.video.file.filerecovery.databinding.DialogRecoveringBinding
import com.ux.video.file.filerecovery.utils.Common
import com.ux.video.file.filerecovery.utils.ExtendFunctions.safeShow
/**
* 删除中弹窗
*/
class DeletingDialogFragment() : BaseIngDialogFragment() {
companion object {
val TAG = Common.TAG_DIALOG_DELETEING
fun show(
fm: FragmentManager,
total: Int
): DeletingDialogFragment {
val dialog = DeletingDialogFragment()
dialog.total = total
dialog.safeShow(fm, TAG)
return dialog
}
}
override fun initUi(binding: DialogRecoveringBinding) {
binding.run {
relativeLayout.setBackgroundResource(R.drawable.bg_rectangle_fdad00_top_20)

View File

@ -1,10 +1,13 @@
package com.ux.video.file.filerecovery.sort
import androidx.fragment.app.FragmentActivity
import androidx.fragment.app.FragmentManager
import androidx.lifecycle.LifecycleOwner
import com.ux.video.file.filerecovery.db.ObjectBoxManager
import com.ux.video.file.filerecovery.db.ResultDataFiles
import com.ux.video.file.filerecovery.utils.Common
import com.ux.video.file.filerecovery.utils.ExtendFunctions.safeShow
import com.ux.video.file.filerecovery.utils.ScanManager
import com.ux.video.file.filerecovery.utils.ScanManager.copySelectedFilesAsync
import com.ux.video.file.filerecovery.utils.ScanManager.deleteFilesAsync
@ -12,9 +15,9 @@ import kotlinx.coroutines.CoroutineScope
object RecoverOrDeleteManager {
private var dialogRecovering: RecoveringDialogFragment? = null
// private var dialogRecovering: RecoveringDialogFragment? = null
private var dialogDeleting: DeletingDialogFragment? = null
// private var dialogDeleting: DeletingDialogFragment? = null
private var dialogConfirmDelete: ConfirmDeleteDialogFragment? = null
//详情页面进行删除操作的监听
@ -29,45 +32,45 @@ object RecoverOrDeleteManager {
* 显示恢复中弹窗
*/
fun showRecoveringDialog(
fragmentManager: FragmentManager,
scope: CoroutineScope,
activity: FragmentActivity,
selectedSetList: Set<ResultDataFiles>,
onComplete: (number: Int) -> Unit
) {
dialogRecovering = dialogRecovering ?: RecoveringDialogFragment()
dialogRecovering?.run {
total = selectedSetList.size
completeListener = { number ->
onComplete(number)
dialogRecovering?.dismiss()
}
show(fragmentManager, "")
}
scope.copySelectedFilesAsync(
val dialog = RecoveringDialogFragment.show(
activity.supportFragmentManager,
selectedSetList.size
)
activity.copySelectedFilesAsync(
selectedSet = selectedSetList,
folder = Common.recoveryPhotoDir,
onProgress = { currentCounts: Int, data: ResultDataFiles, fileName: String, success: Boolean ->
if(success){
ScanManager.showLog("--------恢复图片 ", "----------${currentCounts} ${fileName}")
dialogRecovering?.updateProgress(currentCounts)
if (success && !activity.isFinishing) {
ScanManager.showLog(
"--------恢复图片 ",
"----------${currentCounts} ${fileName}"
)
dialog.updateProgress(currentCounts)
ObjectBoxManager.addRecoveryFile(data)
}
}) { counts ->
dialogRecovering?.updateProgress(counts)
if (!activity.isFinishing) {
dialog.updateProgress(counts)
onComplete(counts)
dialog.dismissAllowingStateLoss()
ScanManager.showLog("--------恢复图片 ", "----------恢复完成 ${counts}")
}
}
}
/**
* 显示删除弹窗
* 显示确认删除弹窗
*/
fun showConfirmDeleteDialog(
isInfoDelete: Boolean = false,
fragmentManager: FragmentManager,
scope: CoroutineScope,
activity: FragmentActivity,
selectedSetList: Set<ResultDataFiles>,
onComplete: (number: Int) -> Unit
) {
@ -76,48 +79,48 @@ object RecoverOrDeleteManager {
onClickDelete = {
showDeletingDialog(
isInfoDelete,
fragmentManager,
scope,
activity,
selectedSetList,
onComplete
)
}
show(fragmentManager, "")
safeShow(activity.supportFragmentManager, Common.TAG_DIALOG_CONFIRM_DELETE)
}
}
/**
* 显示删除中弹窗
*/
private fun showDeletingDialog(
isInfoDelete: Boolean = false,
fragmentManager: FragmentManager,
scope: CoroutineScope,
activity: FragmentActivity,
selectedSetList: Set<ResultDataFiles>,
onComplete: (number: Int) -> Unit
) {
dialogDeleting = dialogDeleting ?: DeletingDialogFragment()
dialogDeleting?.run {
total = selectedSetList.size
completeListener = { number ->
dialogDeleting?.dismiss()
onComplete(number)
if (isInfoDelete && selectedSetList.size == 1) {
onSingleDeletedCompleteListener?.invoke(selectedSetList.first())
}
}
show(fragmentManager, "")
}
scope.deleteFilesAsync(
val dialog = DeletingDialogFragment.show(
activity.supportFragmentManager,
selectedSetList.size
)
activity.deleteFilesAsync(
selectedSet = selectedSetList,
onProgress = { currentCounts: Int, data: ResultDataFiles, path: String, success: Boolean ->
if (success) {
ScanManager.showLog("--------删除图片 ", "----------${currentCounts} ${path}")
dialogDeleting?.updateProgress(currentCounts)
dialog.updateProgress(currentCounts)
}
}) { counts ->
dialogDeleting?.updateProgress(counts)
ScanManager.showLog("--------恢复图片 ", "----------恢复完成 ${counts}")
if (isInfoDelete && selectedSetList.size == 1) {
onSingleDeletedCompleteListener?.invoke(selectedSetList.first())
}
onComplete(counts)
dialog.updateProgress(counts)
dialog.dismissAllowingStateLoss()
ScanManager.showLog("--------删除图片 ", "----------删除完成 ${counts}")
}
}
}

View File

@ -1,14 +1,33 @@
package com.ux.video.file.filerecovery.sort
import androidx.fragment.app.FragmentManager
import com.ux.video.file.filerecovery.R
import com.ux.video.file.filerecovery.base.BaseIngDialogFragment
import com.ux.video.file.filerecovery.databinding.DialogRecoveringBinding
import com.ux.video.file.filerecovery.utils.Common
import com.ux.video.file.filerecovery.utils.ExtendFunctions.safeShow
/**
* 恢复中弹窗
*/
class RecoveringDialogFragment() : BaseIngDialogFragment() {
companion object {
val TAG = Common.TAG_DIALOG_RECOVERING
fun show(
fm: FragmentManager,
total: Int
): RecoveringDialogFragment {
val dialog = RecoveringDialogFragment()
dialog.total = total
dialog.safeShow(fm, TAG)
return dialog
}
}
override fun initUi(binding: DialogRecoveringBinding) {
binding.run {
relativeLayout.setBackgroundResource(R.drawable.bg_rectangle_0048fd_top_20)

View File

@ -11,14 +11,18 @@ import androidx.fragment.app.DialogFragment
import com.ux.video.file.filerecovery.R
import com.ux.video.file.filerecovery.databinding.CommonLayoutSortItemBinding
import com.ux.video.file.filerecovery.databinding.DialogSortBinding
import com.ux.video.file.filerecovery.recovery.ui.recoveryphoto.RecoveredFragment
class SortDialogFragment(val onClickSort: (type: Int) -> Unit) : DialogFragment() {
class SortDialogFragment() : DialogFragment() {
private lateinit var binding: DialogSortBinding
private var clickType = SortingActivity.SORT_DESC_DATE
private lateinit var LayoutList: List<CommonLayoutSortItemBinding>
lateinit var onClickSort: (type: Int) -> Unit
override fun onStart() {
super.onStart()
dialog?.window?.apply {

View File

@ -34,6 +34,7 @@ import com.ux.video.file.filerecovery.utils.ExtendFunctions.kbToBytes
import com.ux.video.file.filerecovery.utils.ExtendFunctions.mbToBytes
import com.ux.video.file.filerecovery.utils.ExtendFunctions.minutesToMillisecond
import com.ux.video.file.filerecovery.utils.ExtendFunctions.removeItem
import com.ux.video.file.filerecovery.utils.ExtendFunctions.safeShow
import com.ux.video.file.filerecovery.utils.FileType
import com.ux.video.file.filerecovery.utils.GridSpacingItemDecoration
import com.ux.video.file.filerecovery.utils.ScanType
@ -250,8 +251,7 @@ class SortingActivity : BaseActivity<ActivityPhotoSortingBinding>() {
}
tvRecover.setOnClickListener {
RecoverOrDeleteManager.showRecoveringDialog(
supportFragmentManager,
lifecycleScope,
this@SortingActivity,
filterSelectedSetList
) { count ->
complete(count, 0)
@ -260,8 +260,7 @@ class SortingActivity : BaseActivity<ActivityPhotoSortingBinding>() {
}
tvDelete.setOnClickListener {
RecoverOrDeleteManager.showConfirmDeleteDialog(
fragmentManager = supportFragmentManager,
scope = lifecycleScope,
activity = this@SortingActivity,
selectedSetList = filterSelectedSetList
) { count ->
complete(count, 1)
@ -269,7 +268,8 @@ class SortingActivity : BaseActivity<ActivityPhotoSortingBinding>() {
}
imSort.setOnClickListener {
sortDialogFragment = sortDialogFragment ?: SortDialogFragment {
sortDialogFragment = sortDialogFragment ?: SortDialogFragment()
sortDialogFragment?.onClickSort = {
when (it) {
SORT_ASC_DATE -> {
setDateAdapter()
@ -334,7 +334,7 @@ class SortingActivity : BaseActivity<ActivityPhotoSortingBinding>() {
}
}
}
sortDialogFragment?.show(supportFragmentManager, "")
sortDialogFragment?.safeShow(supportFragmentManager, Common.TAG_DIALOG_SORT)
}
//全选按钮 只对当前显示的数据有效
@ -806,7 +806,7 @@ class SortingActivity : BaseActivity<ActivityPhotoSortingBinding>() {
onClickCancel = {
}
show(supportFragmentManager, "")
safeShow(supportFragmentManager, Common.TAG_DIALOG_DATE_START)
}
@ -842,9 +842,9 @@ class SortingActivity : BaseActivity<ActivityPhotoSortingBinding>() {
}
onClickCancel = {
// filterDatePopupWindows?.dismiss()
}
show(supportFragmentManager, "")
safeShow(supportFragmentManager, Common.TAG_DIALOG_DATE_END)
}
}

View File

@ -3,6 +3,7 @@ package com.ux.video.file.filerecovery.success
import android.content.Intent
import android.view.LayoutInflater
import androidx.core.view.isVisible
import com.bumptech.glide.Glide
import com.ux.video.file.filerecovery.R
import com.ux.video.file.filerecovery.base.BaseActivity
import com.ux.video.file.filerecovery.databinding.ActivityRecoverOrDeletedSuccessBinding
@ -55,7 +56,10 @@ class RecoverySuccessActivity : BaseActivity<ActivityRecoverOrDeletedSuccessBind
}
when (successType) {
0 -> {
imageCenter.setImageResource(R.drawable.image_recover_success)
// imageCenter.setImageResource(R.drawable.image_recover_success)
Glide.with(this@RecoverySuccessActivity)
.load(R.drawable.image_recover_success)
.into(imageCenter)
tvNumber.setTextColor(
Common.getColorInt(
this@RecoverySuccessActivity,
@ -80,7 +84,10 @@ class RecoverySuccessActivity : BaseActivity<ActivityRecoverOrDeletedSuccessBind
}
1 -> {
imageCenter.setImageResource(R.drawable.image_deleted_success)
// imageCenter.setImageResource(R.drawable.image_deleted_success)
Glide.with(this@RecoverySuccessActivity)
.load(R.drawable.image_deleted_success)
.into(imageCenter)
tvNumber.setTextColor(
Common.getColorInt(
this@RecoverySuccessActivity,

View File

@ -32,6 +32,29 @@ object Common {
val KEY_FILE_TYPE = "key_file_type"
//恢复中弹窗tag
val TAG_DIALOG_RECOVERING = "Dialog_Recovering"
//删除中弹窗tag
val TAG_DIALOG_DELETEING = "Dialog_Deleting"
//确认删除弹窗tag
val TAG_DIALOG_CONFIRM_DELETE = "Dialog_Confirm_Delete"
//请求管理所有文件弹窗tag
val TAG_DIALOG_PERMISSION = "Dialog_Permission"
//推出扫描结果弹窗tag
val TAG_DIALOG_EXIT = "Dialog_Exit"
//排序弹窗tag
val TAG_DIALOG_SORT = "Dialog_Sort"
//筛选开始日期弹窗tag
val TAG_DIALOG_DATE_START = "Dialog_start_date"
//筛选结束日期弹窗tag
val TAG_DIALOG_DATE_END = "Dialog_end_date"
val rootDir = Environment.getExternalStorageDirectory()

View File

@ -6,6 +6,8 @@ import android.icu.util.Calendar
import android.os.Build
import android.os.Parcelable
import android.util.TypedValue
import androidx.fragment.app.DialogFragment
import androidx.fragment.app.FragmentManager
import androidx.recyclerview.widget.RecyclerView
import com.ux.video.file.filerecovery.db.ResultDataFiles
import com.ux.video.file.filerecovery.db.duration
@ -80,9 +82,6 @@ object ExtendFunctions {
}
fun List<Pair<String, List<ResultDataFiles>>>.filterWithinDateRange(
months: Int = -1,
startDate: Date? = null,
@ -119,6 +118,7 @@ object ExtendFunctions {
}
}
}
/**
* 按文件大小筛选区间 [minSize, maxSize]
*/
@ -217,4 +217,21 @@ object ExtendFunctions {
}
fun DialogFragment.safeShow(fragmentManager: FragmentManager, tag: String) {
if (tag.isBlank()) throw IllegalArgumentException("Fragment tag cannot be blank")
val existingFragment = fragmentManager.findFragmentByTag(tag)
if (existingFragment != null) {
return
}
if (!this.isAdded && !this.isVisible) {
try {
this.show(fragmentManager, tag)
} catch (e: IllegalStateException) {
e.printStackTrace()
}
}
}
}

View File

@ -10,6 +10,9 @@ import android.provider.MediaStore
import android.provider.OpenableColumns
import android.text.format.Formatter
import android.util.Log
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.lifecycleScope
import com.ux.video.file.filerecovery.db.ResultData
import com.ux.video.file.filerecovery.db.ResultDataFiles
import kotlinx.coroutines.CoroutineScope
@ -269,7 +272,6 @@ object ScanManager {
}
private fun getFileSizeByMediaStore(context: Context, file: File): Long {
val uri = Uri.fromFile(file)
context.contentResolver.query(uri, arrayOf(OpenableColumns.SIZE), null, null, null)
@ -329,19 +331,25 @@ object ScanManager {
* 做批量恢复
* @param folder "AllRecovery/Photo"
*/
fun CoroutineScope.copySelectedFilesAsync(
fun LifecycleOwner.copySelectedFilesAsync(
selectedSet: Set<ResultDataFiles>,
rootDir: File = Common.rootDir,
folder: String,
onProgress: (currentCounts: Int, data: ResultDataFiles, fileName: String, success: Boolean) -> Unit,
onComplete: (currentCounts: Int) -> Unit
) {
launch(Dispatchers.IO) {
lifecycleScope.launch(Dispatchers.IO) {
var recoveryCount = 0
val targetDir = File(rootDir, folder)
if (!targetDir.exists()) targetDir.mkdirs()
selectedSet.forEachIndexed { index, resultPhotosFiles ->
val srcFile = File(resultPhotosFiles.path!!)
// 页面已销毁,直接停
if (!lifecycle.currentState.isAtLeast(Lifecycle.State.STARTED)) {
Common.showLog("----------------页面已销毁,直接停")
return@launch
}
Common.showLog("----------------resultPhotosFiles.path=${resultPhotosFiles.path}")
val srcFile = File(resultPhotosFiles.path)
if (srcFile.exists() && srcFile.isFile) {
val destFile = File(targetDir, srcFile.name)
var success = false
@ -351,12 +359,17 @@ object ScanManager {
input.copyTo(output)
}
}
success = destFile.exists() && destFile.length() > 0
Common.showLog("------------success------${success}")
success = true
recoveryCount++
withContext(Dispatchers.Main) {
if (lifecycle.currentState.isAtLeast(Lifecycle.State.STARTED))
onProgress(index + 1, resultPhotosFiles, srcFile.name, success)
}
} catch (e: Exception) {
Common.showLog("------------Exception------${e.message}")
e.printStackTrace()
}
@ -364,6 +377,7 @@ object ScanManager {
}
withContext(Dispatchers.Main) {
if (lifecycle.currentState.isAtLeast(Lifecycle.State.STARTED))
onComplete(recoveryCount)
}
}
@ -374,12 +388,12 @@ object ScanManager {
* 做批量删除文件
*
*/
fun CoroutineScope.deleteFilesAsync(
fun LifecycleOwner.deleteFilesAsync(
selectedSet: Set<ResultDataFiles>,
onProgress: (currentCounts: Int, data: ResultDataFiles, fileName: String, success: Boolean) -> Unit,
onComplete: (currentCounts: Int) -> Unit
) {
launch(Dispatchers.IO) {
lifecycleScope.launch(Dispatchers.IO) {
var deletedCount = 0
selectedSet.forEachIndexed { index, resultPhotosFiles ->
try {

View File

@ -69,8 +69,7 @@ class VideoPlayActivity : BaseActivity<ActivityVideoPlayBinding>() {
setOnClickListener {
RecoverOrDeleteManager.showConfirmDeleteDialog(
true,
supportFragmentManager,
lifecycleScope,
this@VideoPlayActivity,
setOf(resultPhotosFiles)
) { count ->
complete(count, 1)
@ -82,8 +81,7 @@ class VideoPlayActivity : BaseActivity<ActivityVideoPlayBinding>() {
text = resources.getString(R.string.recover)
setOnClickListener {
RecoverOrDeleteManager.showRecoveringDialog(
supportFragmentManager,
lifecycleScope,
this@VideoPlayActivity,
setOf(resultPhotosFiles)
) { count ->
complete(count, 0)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 84 KiB

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 86 KiB

After

Width:  |  Height:  |  Size: 25 KiB