V1.2(3)fragment的无参构造,dialogFragment的安全显示,恢复中和删除中的调用避免内存泄漏
This commit is contained in:
parent
0c1980da94
commit
0f0a3301d2
@ -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"
|
||||
}
|
||||
|
||||
6
app/proguard-rules.pro
vendored
6
app/proguard-rules.pro
vendored
@ -74,6 +74,12 @@
|
||||
-keep class kotlinx.android.parcel.Parcelize
|
||||
-keep class kotlin.Metadata { *; }
|
||||
|
||||
# 保留所有 Fragment 空构造函数
|
||||
-keep class * extends androidx.fragment.app.Fragment {
|
||||
public <init>();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@ -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"
|
||||
|
||||
@ -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()
|
||||
}
|
||||
}
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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(
|
||||
|
||||
@ -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() }
|
||||
|
||||
@ -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 =
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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
|
||||
|
||||
@ -70,7 +71,7 @@ class ScanResultDisplayActivity : BaseActivity<ActivityScanResultDisplayBinding>
|
||||
|
||||
}
|
||||
}
|
||||
viewModel.scanData.observe(this@ScanResultDisplayActivity){ data->
|
||||
viewModel.scanData.observe(this@ScanResultDisplayActivity) { data ->
|
||||
list = data
|
||||
list.let { data ->
|
||||
textDirCount.text = data.size.toString()
|
||||
@ -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) {
|
||||
@ -100,7 +105,7 @@ class ScanResultDisplayActivity : BaseActivity<ActivityScanResultDisplayBinding>
|
||||
textFileType.text = getString(R.string.text_photos)
|
||||
}
|
||||
|
||||
FileType.VIDEO-> {
|
||||
FileType.VIDEO -> {
|
||||
title.text = getString(R.string.video_title)
|
||||
textFileType.text = getString(R.string.text_videos)
|
||||
}
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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){
|
||||
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}")
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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)
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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()
|
||||
|
||||
@ -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()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -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
|
||||
@ -65,7 +68,7 @@ object ScanManager {
|
||||
if (file.isDirectory) {
|
||||
scanDocuments(file, depth + 1)
|
||||
} else {
|
||||
val fileCheckBoolean: Boolean = checkFileFormat(file,fileType)
|
||||
val fileCheckBoolean: Boolean = checkFileFormat(file, fileType)
|
||||
if (fileCheckBoolean) {
|
||||
val dirName = file.parentFile?.name ?: "Unknown"
|
||||
|
||||
@ -161,7 +164,7 @@ object ScanManager {
|
||||
val isHidden = file.name.startsWith(".")
|
||||
scanDir(file, depth + 1, insideHidden = insideHidden || isHidden)
|
||||
} else {
|
||||
val fileCheckBoolean: Boolean = checkFileFormat(file,fileType)
|
||||
val fileCheckBoolean: Boolean = checkFileFormat(file, fileType)
|
||||
if (insideHidden) {
|
||||
if (fileCheckBoolean) {
|
||||
val dirName = file.parentFile?.name ?: "Unknown"
|
||||
@ -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 {
|
||||
|
||||
@ -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 |
Loading…
Reference in New Issue
Block a user