Commit c947439c authored by wanglei's avatar wanglei

...

parent c3a71894
...@@ -30,8 +30,7 @@ class MainActivity : BaseActivity<ActivityMainBinding>() { ...@@ -30,8 +30,7 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
override fun initView() { override fun initView() {
BarUtils.setStatusBarLightMode(this, true) BarUtils.setStatusBarLightMode(this, true)
BarUtils.setStatusBarColor(this, Color.TRANSPARENT) BarUtils.setStatusBarColor(this, Color.TRANSPARENT)
binding.root.updatePadding(top = BarUtils.getStatusBarHeight()) // binding.root.updatePadding(top = BarUtils.getStatusBarHeight())
// showRateStarPopDialog() // showRateStarPopDialog()
// showExitFunctionDialog() // showExitFunctionDialog()
} }
......
package com.base.datarecovery.activity.recovery package com.base.datarecovery.activity.recovery
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.content.Intent
import android.graphics.Color import android.graphics.Color
import android.os.Environment import android.os.Environment
import android.view.View
import androidx.activity.addCallback import androidx.activity.addCallback
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
import com.base.datarecovery.R import com.base.datarecovery.R
import com.base.datarecovery.ads.AdmobInterstitialUtils import com.base.datarecovery.ads.AdmobInterstitialUtils
import com.base.datarecovery.ads.AdmobNativeUtils
import com.base.datarecovery.ads.AdmobOpenUtils
import com.base.datarecovery.bean.ConstObject
import com.base.datarecovery.bean.ConstObject.SCAN_DOCUMENTS import com.base.datarecovery.bean.ConstObject.SCAN_DOCUMENTS
import com.base.datarecovery.bean.ConstObject.SCAN_PHOTOS import com.base.datarecovery.bean.ConstObject.SCAN_PHOTOS
import com.base.datarecovery.bean.ConstObject.SCAN_VIDEOS import com.base.datarecovery.bean.ConstObject.SCAN_VIDEOS
...@@ -27,12 +22,10 @@ import com.base.datarecovery.utils.FileHexEx.isVideo ...@@ -27,12 +22,10 @@ import com.base.datarecovery.utils.FileHexEx.isVideo
import com.base.datarecovery.utils.LogEx import com.base.datarecovery.utils.LogEx
import com.base.datarecovery.view.DialogViews.showExitFunctionDialog import com.base.datarecovery.view.DialogViews.showExitFunctionDialog
import com.base.datarecovery.view.DialogViews.showGerPermission import com.base.datarecovery.view.DialogViews.showGerPermission
import kotlinx.coroutines.Dispatchers import com.base.datarecovery.view.FileScanDialog
import kotlinx.coroutines.channels.BufferOverflow import kotlinx.coroutines.channels.BufferOverflow
import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.SharedFlow import kotlinx.coroutines.flow.SharedFlow
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.launch
/** /**
* 文件扫描,遍历文件夹的方式进行 * 文件扫描,遍历文件夹的方式进行
...@@ -69,6 +62,11 @@ class FileScanActivity : BaseActivity<ActivityFileScanBinding>() { ...@@ -69,6 +62,11 @@ class FileScanActivity : BaseActivity<ActivityFileScanBinding>() {
binding.ivIcon.setImageResource(R.mipmap.tu_videos_scan) binding.ivIcon.setImageResource(R.mipmap.tu_videos_scan)
} }
} }
if (checkStorePermission()) {
beginScan()
} else {
requestPermission()
}
} }
override fun initListener() { override fun initListener() {
...@@ -82,26 +80,37 @@ class FileScanActivity : BaseActivity<ActivityFileScanBinding>() { ...@@ -82,26 +80,37 @@ class FileScanActivity : BaseActivity<ActivityFileScanBinding>() {
binding.flFanhui.setOnClickListener { binding.flFanhui.setOnClickListener {
onBackPressedDispatcher.onBackPressed() onBackPressedDispatcher.onBackPressed()
} }
binding.tvScan.setOnClickListener { // binding.tvScan.setOnClickListener {
if (checkStorePermission()) { // if (checkStorePermission()) {
binding.llFile.visibility = View.VISIBLE // binding.llFile.visibility = View.VISIBLE
beginScan() // beginScan()
} else { // } else {
requestPermission() // requestPermission()
} // }
} // }
} }
private fun beginScan() { private fun beginScan() {
if (scanOnce) if (scanOnce)
return return
scanOnce = true scanOnce = true
val mutableSharedFlow = MutableSharedFlow<String>( val mPathFlow = MutableSharedFlow<String>(
replay = 5,//当新的订阅者Collect时,发送几个已经发送过的数据给它
extraBufferCapacity = 5,//减去replay,MutableSharedFlow还缓存多少数据,缓冲池容量 = replay + extraBufferCapacity
onBufferOverflow = BufferOverflow.SUSPEND//缓存策略,三种 丢掉最新值、丢掉最旧值和挂起
)
val pathFlow: SharedFlow<String> = mPathFlow
val mFoundFlow = MutableSharedFlow<Int>(
replay = 5,//当新的订阅者Collect时,发送几个已经发送过的数据给它 replay = 5,//当新的订阅者Collect时,发送几个已经发送过的数据给它
extraBufferCapacity = 5,//减去replay,MutableSharedFlow还缓存多少数据,缓冲池容量 = replay + extraBufferCapacity extraBufferCapacity = 5,//减去replay,MutableSharedFlow还缓存多少数据,缓冲池容量 = replay + extraBufferCapacity
onBufferOverflow = BufferOverflow.SUSPEND//缓存策略,三种 丢掉最新值、丢掉最旧值和挂起 onBufferOverflow = BufferOverflow.SUSPEND//缓存策略,三种 丢掉最新值、丢掉最旧值和挂起
) )
val sharedFlow: SharedFlow<String> = mutableSharedFlow val foundFlow: SharedFlow<Int> = mFoundFlow
val dialogClass = FileScanDialog(this)
val scanDialog = dialogClass.showFileScanDialog(pathFlow, foundFlow)
val filter = when (scanType) { val filter = when (scanType) {
SCAN_PHOTOS -> ::isImage SCAN_PHOTOS -> ::isImage
...@@ -112,25 +121,24 @@ class FileScanActivity : BaseActivity<ActivityFileScanBinding>() { ...@@ -112,25 +121,24 @@ class FileScanActivity : BaseActivity<ActivityFileScanBinding>() {
val root = Environment.getExternalStorageDirectory() val root = Environment.getExternalStorageDirectory()
val pathList = arrayListOf<String>() val pathList = arrayListOf<String>()
lifecycleScope.loadFileByFilter( lifecycleScope.loadFileByFilter(
mutableSharedFlow, mPathFlow,
mFoundFlow,
root, filter = filter, root, filter = filter,
onDo = { file -> onDo = { file ->
LogEx.logDebug(TAG, "file =${file.absolutePath}") LogEx.logDebug(TAG, "file =${file.absolutePath}")
pathList.add(file.absolutePath) pathList.add(file.absolutePath)
}, },
onFinish = { onFinish = {
startActivity(Intent(this@FileScanActivity, FileScanResultActivity::class.java).apply {
putExtra("ScanType", scanType) if (pathList.isEmpty()) {
putExtra("PathList", pathList.toTypedArray()) scanDialog.dismiss()
}) } else {
finish() dialogClass.stopScan(scanType, pathList)
}
} }
) )
lifecycleScope.launch(Dispatchers.Main) {
sharedFlow.collectLatest {
binding.tvPath.text = it
}
}
} }
...@@ -139,7 +147,7 @@ class FileScanActivity : BaseActivity<ActivityFileScanBinding>() { ...@@ -139,7 +147,7 @@ class FileScanActivity : BaseActivity<ActivityFileScanBinding>() {
showGerPermission(tittle = "Storage Permission Required", showGerPermission(tittle = "Storage Permission Required",
desc = "This feature requires access to your storage to scan your photos, videos, and documents and recover any accidentally deleted data. We will not transmit your data to any third-party service. Please grant permission so that we can provide you with better service.", desc = "This feature requires access to your storage to scan your photos, videos, and documents and recover any accidentally deleted data. We will not transmit your data to any third-party service. Please grant permission so that we can provide you with better service.",
deny = { }, deny = { finishToMain() },
allow = { allow = {
requestStorePermission(launcher, jumpAction = {}, result = { flag -> requestStorePermission(launcher, jumpAction = {}, result = { flag ->
......
...@@ -18,13 +18,16 @@ object FileHelp { ...@@ -18,13 +18,16 @@ object FileHelp {
private val TAG = "FileHelp" private val TAG = "FileHelp"
fun CoroutineScope.loadFileByFilter( fun CoroutineScope.loadFileByFilter(
mutableSharedFlow: MutableSharedFlow<String>? = null, flow1: MutableSharedFlow<String>? = null,
flow2: MutableSharedFlow<Int>? = null,
folder: File, folder: File,
filter: (file: File) -> Boolean, filter: (file: File) -> Boolean,
onDo: ((file: File) -> Unit)? = null, onDo: ((file: File) -> Unit)? = null,
onFinish: (() -> Unit)? = null onFinish: (() -> Unit)? = null
) = launch(Dispatchers.IO) { ) = launch(Dispatchers.IO) {
var size = 0
//添加第一层文件到链表 //添加第一层文件到链表
val linkList = LinkedList<File>() val linkList = LinkedList<File>()
val fileList = folder.listFiles() val fileList = folder.listFiles()
...@@ -36,8 +39,10 @@ object FileHelp { ...@@ -36,8 +39,10 @@ object FileHelp {
LogEx.logDebug(TAG, "$it flag=$flag") LogEx.logDebug(TAG, "$it flag=$flag")
if (flag) { if (flag) {
onDo?.invoke(it) onDo?.invoke(it)
size++
flow2?.emit(size)
} }
mutableSharedFlow?.emit(it.absolutePath) flow1?.emit(it.absolutePath)
} }
} }
...@@ -54,8 +59,10 @@ object FileHelp { ...@@ -54,8 +59,10 @@ object FileHelp {
// LogEx.logDebug(TAG, "$it flag=$flag") // LogEx.logDebug(TAG, "$it flag=$flag")
if (flag) { if (flag) {
onDo?.invoke(it) onDo?.invoke(it)
size++
flow2?.emit(size)
} }
mutableSharedFlow?.emit(it.absolutePath) flow1?.emit(it.absolutePath)
} }
} }
} }
......
package com.base.datarecovery.view package com.base.datarecovery.view
import android.animation.ValueAnimator
import android.annotation.SuppressLint
import android.app.AlertDialog import android.app.AlertDialog
import android.content.Context import android.content.Intent
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View
import android.view.animation.LinearInterpolator
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.lifecycleScope
import com.base.datarecovery.R import com.base.datarecovery.R
import com.base.datarecovery.activity.recovery.FileScanResultActivity
import com.base.datarecovery.ads.AdmobNativeUtils
import com.base.datarecovery.databinding.DialogFileScanBinding import com.base.datarecovery.databinding.DialogFileScanBinding
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.SharedFlow
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.launch
object FileScanDialog { class FileScanDialog(
fun Context.showFileScanDialog() { val activity: AppCompatActivity,
val binding = DialogFileScanBinding.inflate(LayoutInflater.from(this)) ) {
val dialog = AlertDialog.Builder(this).create() private val TAG = "FileScanDialog"
dialog.setView(binding.root) private val a1 = ValueAnimator.ofFloat(0f, -360f)
dialog.setCanceledOnTouchOutside(false) private val dialog = AlertDialog.Builder(activity).create()
dialog.show() private lateinit var btn: TextView
dialog.window?.setBackgroundDrawableResource(android.R.color.transparent) @SuppressLint("SetTextI18n")
val params = dialog.window?.attributes fun showFileScanDialog(
params?.width = resources.getDimensionPixelOffset(R.dimen.dp_345) sharedFlow: SharedFlow<String>,
dialog.window?.attributes = params foundFlow: SharedFlow<Int>
): AlertDialog {
val binding = DialogFileScanBinding.inflate(LayoutInflater.from(activity))
dialog?.setView(binding.root)
dialog?.setCanceledOnTouchOutside(false)
dialog?.setCancelable(false)
dialog?.show()
dialog?.window?.setBackgroundDrawableResource(android.R.color.transparent)
val params = dialog?.window?.attributes
params?.width = activity.resources.getDimensionPixelOffset(R.dimen.dp_300)
dialog?.window?.attributes = params
a1.run {
duration = 1000
repeatMode = ValueAnimator.RESTART
repeatCount = ValueAnimator.INFINITE
interpolator = LinearInterpolator()
addUpdateListener {
binding.iv.rotation = it.animatedValue as Float
}
start()
}
dialog?.setOnDismissListener {
a1.cancel()
}
AdmobNativeUtils.showNativeAd(activity, binding.flAd)
activity.lifecycleScope.launch(Dispatchers.Main) {
sharedFlow.collectLatest { path ->
binding.tvPath.text = path
}
}
activity.lifecycleScope.launch {
foundFlow.collectLatest {
binding.tvFoundNumber.text = "Found $it files"
}
}
btn = binding.tvBtn
return dialog
}
fun stopScan(scanType: Int, pathList: ArrayList<String>) {
a1.cancel()
btn.visibility = View.VISIBLE
btn.setOnClickListener {
activity.startActivity(Intent(activity, FileScanResultActivity::class.java).apply {
putExtra("ScanType", scanType)
putExtra("PathList", pathList.toTypedArray())
})
activity.finish()
}
} }
} }
\ No newline at end of file
...@@ -66,69 +66,69 @@ ...@@ -66,69 +66,69 @@
tools:ignore="ContentDescription" tools:ignore="ContentDescription"
tools:src="@mipmap/tu_photos_scan" /> tools:src="@mipmap/tu_photos_scan" />
<TextView <!-- <TextView-->
android:id="@+id/tv_scan" <!-- android:id="@+id/tv_scan"-->
android:layout_width="240dp" <!-- android:layout_width="240dp"-->
android:layout_height="35dp" <!-- android:layout_height="35dp"-->
android:layout_gravity="center" <!-- android:layout_gravity="center"-->
android:layout_marginTop="40dp" <!-- android:layout_marginTop="40dp"-->
android:background="@drawable/bg_567dfd_15" <!-- android:background="@drawable/bg_567dfd_15"-->
android:elevation="5dp" <!-- android:elevation="5dp"-->
android:gravity="center" <!-- android:gravity="center"-->
android:text="SCAN" <!-- android:text="SCAN"-->
android:textColor="@color/white" <!-- android:textColor="@color/white"-->
tools:ignore="HardcodedText" /> <!-- tools:ignore="HardcodedText" />-->
<TextView <!-- <TextView-->
android:id="@+id/tv_tip" <!-- 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_gravity="center_horizontal" <!-- android:layout_gravity="center_horizontal"-->
android:layout_marginTop="20dp" <!-- android:layout_marginTop="20dp"-->
android:text="Tap to start scanning" <!-- android:text="Tap to start scanning"-->
android:textColor="#999999" <!-- android:textColor="#999999"-->
tools:ignore="HardcodedText" /> <!-- tools:ignore="HardcodedText" />-->
<LinearLayout <!-- <LinearLayout-->
android:id="@+id/ll_file" <!-- android:id="@+id/ll_file"-->
android:layout_width="match_parent" <!-- android:layout_width="match_parent"-->
android:layout_height="wrap_content" <!-- android:layout_height="wrap_content"-->
android:layout_marginHorizontal="16dp" <!-- android:layout_marginHorizontal="16dp"-->
android:layout_marginTop="20dp" <!-- android:layout_marginTop="20dp"-->
android:orientation="vertical" <!-- android:orientation="vertical"-->
android:visibility="gone"> <!-- android:visibility="gone">-->
<LinearLayout <!-- <LinearLayout-->
android:layout_width="wrap_content" <!-- android:layout_width="wrap_content"-->
android:layout_height="wrap_content"> <!-- android:layout_height="wrap_content">-->
<ProgressBar <!-- <ProgressBar-->
android:layout_width="35dp" <!-- android:layout_width="35dp"-->
android:layout_height="35dp" /> <!-- android:layout_height="35dp" />-->
<TextView <!-- <TextView-->
android:layout_width="wrap_content" <!-- android:layout_width="wrap_content"-->
android:layout_height="wrap_content" <!-- android:layout_height="wrap_content"-->
android:layout_gravity="center_vertical" <!-- android:layout_gravity="center_vertical"-->
android:layout_marginStart="8dp" <!-- android:layout_marginStart="8dp"-->
android:text="Scanning..." <!-- android:text="Scanning..."-->
android:textColor="@color/black" <!-- android:textColor="@color/black"-->
android:textSize="16sp" <!-- android:textSize="16sp"-->
android:textStyle="bold" <!-- android:textStyle="bold"-->
tools:ignore="HardcodedText" /> <!-- tools:ignore="HardcodedText" />-->
</LinearLayout> <!-- </LinearLayout>-->
<TextView <!-- <TextView-->
android:id="@+id/tv_path" <!-- android:id="@+id/tv_path"-->
android:layout_width="match_parent" <!-- android:layout_width="match_parent"-->
android:layout_height="wrap_content" <!-- android:layout_height="wrap_content"-->
android:ellipsize="middle" <!-- android:ellipsize="middle"-->
android:singleLine="true" <!-- android:singleLine="true"-->
android:textSize="14sp" <!-- android:textSize="14sp"-->
tools:text="............." /> <!-- tools:text="............." />-->
</LinearLayout> <!-- </LinearLayout>-->
</LinearLayout> </LinearLayout>
......
...@@ -220,48 +220,48 @@ ...@@ -220,48 +220,48 @@
</LinearLayout> </LinearLayout>
<View <!-- <View-->
android:layout_width="match_parent" <!-- android:layout_width="match_parent"-->
android:layout_height="1px" <!-- android:layout_height="1px"-->
android:background="#EEEEEE" /> <!-- android:background="#EEEEEE" />-->
<LinearLayout <!-- <LinearLayout-->
android:id="@+id/ll_user_agreement" <!-- android:id="@+id/ll_user_agreement"-->
android:layout_width="match_parent" <!-- android:layout_width="match_parent"-->
android:layout_height="60dp" <!-- android:layout_height="60dp"-->
android:background="?attr/selectableItemBackground" <!-- android:background="?attr/selectableItemBackground"-->
android:clickable="true" <!-- android:clickable="true"-->
android:focusable="true" <!-- android:focusable="true"-->
android:orientation="horizontal"> <!-- android:orientation="horizontal">-->
<ImageView <!-- <ImageView-->
android:layout_width="wrap_content" <!-- android:layout_width="wrap_content"-->
android:layout_height="wrap_content" <!-- android:layout_height="wrap_content"-->
android:layout_gravity="center_vertical" <!-- android:layout_gravity="center_vertical"-->
android:layout_marginStart="18dp" <!-- android:layout_marginStart="18dp"-->
android:layout_marginEnd="10dp" <!-- android:layout_marginEnd="10dp"-->
android:importantForAccessibility="no" <!-- android:importantForAccessibility="no"-->
android:src="@mipmap/privacy" <!-- android:src="@mipmap/privacy"-->
tools:ignore="ContentDescription" /> <!-- tools:ignore="ContentDescription" />-->
<TextView <!-- <TextView-->
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"-->
android:layout_weight="1" <!-- android:layout_weight="1"-->
android:text="User Agreement" <!-- android:text="User Agreement"-->
android:textColor="@color/black" <!-- android:textColor="@color/black"-->
android:textSize="16sp" <!-- android:textSize="16sp"-->
android:textStyle="bold" <!-- android:textStyle="bold"-->
tools:ignore="HardcodedText" /> <!-- tools:ignore="HardcodedText" />-->
<androidx.appcompat.widget.AppCompatImageView <!-- <androidx.appcompat.widget.AppCompatImageView-->
android:layout_width="wrap_content" <!-- android:layout_width="wrap_content"-->
android:layout_height="wrap_content" <!-- android:layout_height="wrap_content"-->
android:layout_gravity="center_vertical" <!-- android:layout_gravity="center_vertical"-->
android:layout_marginEnd="18dp" <!-- android:layout_marginEnd="18dp"-->
android:src="@mipmap/jianotu" /> <!-- android:src="@mipmap/jianotu" />-->
</LinearLayout> <!-- </LinearLayout>-->
</LinearLayout> </LinearLayout>
......
...@@ -2,6 +2,9 @@ ...@@ -2,6 +2,9 @@
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android" <androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="300dp" android:layout_width="300dp"
xmlns:app="http://schemas.android.com/apk/res-auto"
app:cardCornerRadius="10dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="vertical"> android:orientation="vertical">
...@@ -14,7 +17,8 @@ ...@@ -14,7 +17,8 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center_horizontal" android:layout_gravity="center_horizontal"
android:layout_marginTop="13dp"> android:layout_marginTop="13dp"
tools:ignore="UseCompoundDrawables">
<ImageView <ImageView
android:id="@+id/iv" android:id="@+id/iv"
...@@ -35,12 +39,45 @@ ...@@ -35,12 +39,45 @@
</LinearLayout> </LinearLayout>
<TextView
android:id="@+id/tv_found_number"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="5dp"
android:textSize="15sp"
tools:text="Found 100 files" />
<TextView
android:id="@+id/tv_path"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="15dp"
android:layout_marginTop="5dp"
android:ellipsize="middle"
android:singleLine="true"
android:textSize="12sp" />
<FrameLayout <FrameLayout
android:id="@+id/fl_ad" android:id="@+id/fl_ad"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginVertical="25dp" /> android:layout_marginVertical="25dp" />
<TextView
android:id="@+id/tv_btn"
android:layout_width="251dp"
android:layout_height="45dp"
android:layout_gravity="center_horizontal"
android:layout_marginBottom="25dp"
android:background="@drawable/bg_577dfd_22"
android:gravity="center"
android:text="Scan Completed"
android:textColor="@color/white"
android:textSize="17sp"
android:textStyle="bold"
tools:ignore="HardcodedText" />
</LinearLayout> </LinearLayout>
......
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