Commit 3d47efc0 authored by wanglei's avatar wanglei

...

parent 2f50b157
......@@ -82,6 +82,7 @@ dependencies {
//图片处理
implementation 'org.opencv:opencv:4.10.0'
implementation("org.opencv:opencv:4.10.0")
//网络
implementation group: 'com.google.code.gson', name: 'gson', version: '2.10.1'
......
......@@ -9,6 +9,7 @@ import androidx.fragment.app.Fragment
import androidx.lifecycle.lifecycleScope
import androidx.viewpager2.adapter.FragmentStateAdapter
import androidx.viewpager2.widget.ViewPager2
import com.base.filerecoveryrecyclebin.ads.admob.AdmobBannerUtils
import com.base.filerecoveryrecyclebin.bean.MediaBean
import com.base.filerecoveryrecyclebin.databinding.ActivityMainBinding
import com.base.filerecoveryrecyclebin.fragment.HomeFragment
......@@ -60,11 +61,11 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
if (!checkStorePermission()) {
if (dialog == null) {
dialog = showPermissionBottomSheet(launcher) {
// AdmobBannerUtils.showCollapsibleBannerAd(this, binding.flBanner)
AdmobBannerUtils.showCollapsibleBannerAd(this, binding.flBanner)
}
}
} else {
// AdmobBannerUtils.showCollapsibleBannerAd(this, binding.flBanner)
AdmobBannerUtils.showCollapsibleBannerAd(this, binding.flBanner)
}
binding.viewpager2.run {
......
......@@ -15,6 +15,7 @@ import com.base.filerecoveryrecyclebin.activity.guide.GuideActivity
import com.base.filerecoveryrecyclebin.activity.junkclean.ScanJunkActivity
import com.base.filerecoveryrecyclebin.activity.photomanager.PhotoManagerAnimationActivity
import com.base.filerecoveryrecyclebin.activity.recovery.FileScanResultActivity
import com.base.filerecoveryrecyclebin.activity.repeat.RepeatActivity
import com.base.filerecoveryrecyclebin.activity.whatsapp.WhatsAppCleanerAnimationActivity
import com.base.filerecoveryrecyclebin.ads.AdmobMaxHelper
import com.base.filerecoveryrecyclebin.bean.ConstObject
......
......@@ -16,9 +16,12 @@ import com.base.filerecoveryrecyclebin.help.ConfigHelper
import com.base.filerecoveryrecyclebin.help.KotlinExt.toFormatSize
import com.base.filerecoveryrecyclebin.help.KotlinExt.toFormatTime
import com.base.filerecoveryrecyclebin.help.MediaStoreHelp.getImageMedia
import com.base.filerecoveryrecyclebin.help.MediaStoreHelp.updateMediaStore
import com.base.filerecoveryrecyclebin.help.PermissionHelp.checkStorePermission
import com.base.filerecoveryrecyclebin.help.PermissionHelp.requestStorePermission
import com.base.filerecoveryrecyclebin.utils.BarUtils
import com.base.filerecoveryrecyclebin.utils.LogEx
import com.base.filerecoveryrecyclebin.utils.SimilarHelper.calculateSimilar
import com.base.filerecoveryrecyclebin.view.DialogViews.showDeletePermanentlyDialog
import com.base.filerecoveryrecyclebin.view.DialogViews.showExitFunctionDialog
import com.base.filerecoveryrecyclebin.view.DialogViews.showGerPermission
......@@ -28,6 +31,7 @@ import java.io.File
class RepeatActivity : BaseActivity<ActivityRepeatBinding>() {
private val TAG = "RepeatActivity"
override val binding: ActivityRepeatBinding by lazy {
ActivityRepeatBinding.inflate(layoutInflater)
......@@ -39,6 +43,9 @@ class RepeatActivity : BaseActivity<ActivityRepeatBinding>() {
BarUtils.setStatusBarLightMode(this, true)
BarUtils.setStatusBarColor(this, Color.TRANSPARENT)
binding.root.updatePadding(top = BarUtils.getStatusBarHeight())
System.loadLibrary("opencv_java4")
mediaAdapter = MediaAdapter {
binding.ivSelectAll.isSelected = it.first
binding.tvClean.isEnabled = it.second.isNotEmpty()
......@@ -66,13 +73,17 @@ class RepeatActivity : BaseActivity<ActivityRepeatBinding>() {
})
})
}
// val s = opencvCompareSimilar("/storage/emulated/0/DCIM/1.jpg","/storage/emulated/0/DCIM/22.jpg")
// LogEx.logDebug(TAG,"s=$s")
// Toast.makeText(this, s.toString(), Toast.LENGTH_SHORT).show()
}
override fun initListener() {
onBackPressedDispatcher.addCallback {
showExitFunctionDialog {
if (it) {
AdmobMaxHelper.admobMaxShowInterstitialAd(this@RepeatActivity){
AdmobMaxHelper.admobMaxShowInterstitialAd(this@RepeatActivity) {
finishToMain()
}
} else {
......@@ -91,7 +102,7 @@ class RepeatActivity : BaseActivity<ActivityRepeatBinding>() {
binding.tvClean.setOnClickListener {
showDeletePermanentlyDialog {
if (showInterAdSp()) {
AdmobMaxHelper.admobMaxShowInterstitialAd(this){
AdmobMaxHelper.admobMaxShowInterstitialAd(this) {
cleanFile()
}
} else {
......@@ -115,20 +126,29 @@ class RepeatActivity : BaseActivity<ActivityRepeatBinding>() {
}
private fun initData() {
lifecycleScope.launch(Dispatchers.IO) {
this@RepeatActivity.updateMediaStore()
val list = arrayListOf<MediaBean>()
getImageMedia(list)
val hashMap = HashMap<String, ArrayList<MediaBean>>()
list.forEach {
val time = it.time.toFormatTime()
if (hashMap[time] == null) {
hashMap[time] = arrayListOf()
}
hashMap[time]?.add(it)
LogEx.logDebug(TAG, "list=${list.size}")
val similarList = calculateSimilar(list)
// similarList.forEach { t, u ->
// LogEx.logDebug(TAG, "t=$t u=$u")
// }
// val hashMap = HashMap<String, ArrayList<MediaBean>>()
// list.forEach {
// val time = it.time.toFormatTime()
// if (hashMap[time] == null) {
// hashMap[time] = arrayListOf()
// }
// hashMap[time]?.add(it)
// }
val beanList = similarList.map { map ->
val time = File(map.key).lastModified().toFormatTime()
MediaTimeBean(time = time, beans = map.value)
}
val beanList = hashMap.map { MediaTimeBean(it.key, it.value) }
launch(Dispatchers.Main) {
binding.progressBar.visibility = View.GONE
mediaAdapter.setData(beanList)
......
......@@ -37,7 +37,7 @@ class MediaAdapter(private val clickAction: (Pair<Boolean, List<MediaBean>>) ->
if (payloads.isEmpty()) {
binding.tvTime.text = bean.time + " (${bean.beans.size})"
binding.tvTime.text = "${bean.beans.size} items " + bean.time
binding.ivSelector.isSelected = bean.isSelect
......
......@@ -3,6 +3,7 @@ package com.base.filerecoveryrecyclebin.bean
data class MediaTimeBean(
val time: String = "",
val name:String="",
val beans: List<MediaBean> = listOf()
) {
var isSelect: Boolean = false
......
package com.base.filerecoveryrecyclebin.utils
import org.opencv.core.Core
import org.opencv.core.Mat
import org.opencv.core.MatOfFloat
import org.opencv.core.MatOfInt
import org.opencv.imgcodecs.Imgcodecs
import org.opencv.imgproc.Imgproc
object OpencvImageHelp {
fun opencvCompareSimilar(path1: String, path2: String): Double {
// 将File对象转换为Mat对象
val image1 = Imgcodecs.imread(path1)
val image2 = Imgcodecs.imread(path2)
// 转换为灰度图
val grayImage1 = Mat()
val grayImage2 = Mat()
Imgproc.cvtColor(image1, grayImage1, Imgproc.COLOR_BGR2GRAY)
Imgproc.cvtColor(image2, grayImage2, Imgproc.COLOR_BGR2GRAY)
// 计算直方图
val histSize = MatOfInt(256)
val range = MatOfFloat(0f, 256f)
val hist1 = Mat()
val hist2 = Mat()
Imgproc.calcHist(mutableListOf(grayImage1), MatOfInt(0), Mat(), hist1, histSize, range)
Imgproc.calcHist(mutableListOf(grayImage2), MatOfInt(0), Mat(), hist2, histSize, range)
// 归一化直方图
Core.normalize(hist1, hist1, 0.0, 1.0, Core.NORM_MINMAX, -1, Mat())
Core.normalize(hist2, hist2, 0.0, 1.0, Core.NORM_MINMAX, -1, Mat())
// 使用相关性方法比较直方图
//HISTCMP_CORREL 相关性
//HISTCMP_INTERSECT 交集
val similarity: Double = Imgproc.compareHist(hist1, hist2, Imgproc.HISTCMP_CORREL)
// 将相似度转换为百分比
val similarityPercentage = similarity * 100.0
return similarityPercentage
}
}
\ No newline at end of file
......@@ -2,54 +2,68 @@ package com.base.filerecoveryrecyclebin.utils
import android.graphics.BitmapFactory
import android.provider.MediaStore.Audio.Radio
import com.base.filerecoveryrecyclebin.bean.MediaBean
import com.base.filerecoveryrecyclebin.utils.OpencvImageHelp.opencvCompareSimilar
import java.io.File
import kotlin.random.Random
object SimilarHelper {
private val TAG = "SimilarHelper"
fun calculate(list: ArrayList<File>) {
val result = HashMap<String, ArrayList<File>>()
val eachArrayList = arrayListOf<File>().apply {
fun calculateSimilar(list: List<MediaBean>): HashMap<String, ArrayList<MediaBean>> {
val result = HashMap<String, ArrayList<MediaBean>>()
val eachArrayList = arrayListOf<MediaBean>().apply {
addAll(list)
}
val comparedFile = arrayListOf<File>()
val haveComperedList: ArrayList<String> = arrayListOf()
val iterator = list.iterator()
val compareIterator = eachArrayList.iterator()
while (iterator.hasNext()) {
val item = iterator.next()
LogEx.logDebug(TAG, "next item=$item")
if (!comparedFile.contains(item)) {
LogEx.logDebug(TAG, "eachArrayList=${eachArrayList.size}")
if (!haveComperedList.contains(item.path)) {
val compareIterator = eachArrayList.iterator()
while (compareIterator.hasNext()) {
val compareItem = compareIterator.next()
if (item.absoluteFile != compareItem.absoluteFile) {
val percent = similarPercent(item, compareItem)
if (percent > 80) {
if (result[item.absolutePath] == null) {
result[item.absolutePath] = arrayListOf()
// LogEx.logDebug(TAG, "compareItem=$compareItem")
if (item.path != compareItem.path) {
val percent = opencvCompareSimilar(item.path, compareItem.path)
if (percent > 96) {
if (result[item.path] == null) {
LogEx.logDebug(TAG, "item=$item")
result[item.path] = arrayListOf()
}
if (result[item.path]?.isEmpty() == true) {
result[item.path]?.add(item)
}
result[item.absolutePath]?.add(item)
result[item.absolutePath]?.add(compareItem)
comparedFile.add(compareItem)
result[item.path]?.add(compareItem)
LogEx.logDebug(TAG, "percent=$percent $item $compareItem")
LogEx.logDebug(TAG, "compareItem=$compareItem")
haveComperedList.add(compareItem.path)
compareIterator.remove()
}
} else {
compareIterator.remove()
}
}
}
}
return result
}
private fun similarPercent(srcFile: File, compareFile: File): Int {
var similarityScore:Double = 0.00
var similarityScore: Double = 0.00
try {
val bitmap1 = BitmapFactory.decodeFile(srcFile.absolutePath)
val bitmap2 = BitmapFactory.decodeFile(compareFile.absolutePath)
......
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@mipmap/tab_clean_n" android:state_selected="false" />
<item android:drawable="@mipmap/tab_clean_s" android:state_enabled="true" />
</selector>
\ No newline at end of file
......@@ -39,7 +39,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:background="@drawable/bg_recovery_tab"
android:background="@drawable/bg_clean_tab"
tools:ignore="ContentDescription" />
<TextView
......@@ -70,7 +70,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:background="@drawable/bg_recyclebin_tab"
android:background="@drawable/bg_recovery_tab"
tools:ignore="ContentDescription" />
<TextView
......
......@@ -17,10 +17,11 @@
tools:ignore="UseCompoundDrawables">
<FrameLayout
android:layout_marginStart="10dp"
android:id="@+id/fl_select"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingHorizontal="15dp">
android:padding="5dp">
<ImageView
android:id="@+id/iv_selector"
......@@ -38,7 +39,6 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginStart="16dp"
android:textColor="#666666"
android:textSize="16sp"
android:textStyle="bold"
......
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