Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Sign in / Register
Toggle navigation
F
File Recovery RecycleBin
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Packages
Packages
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wanglei
File Recovery RecycleBin
Commits
3d47efc0
Commit
3d47efc0
authored
Jul 30, 2024
by
wanglei
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
...
parent
2f50b157
Hide whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
127 additions
and
38 deletions
+127
-38
build.gradle
app/build.gradle
+1
-0
MainActivity.kt
.../com/base/filerecoveryrecyclebin/activity/MainActivity.kt
+3
-2
SplashActivity.kt
...om/base/filerecoveryrecyclebin/activity/SplashActivity.kt
+1
-0
RepeatActivity.kt
.../filerecoveryrecyclebin/activity/repeat/RepeatActivity.kt
+32
-12
MediaAdapter.kt
...a/com/base/filerecoveryrecyclebin/adapter/MediaAdapter.kt
+1
-1
MediaTimeBean.kt
...ava/com/base/filerecoveryrecyclebin/bean/MediaTimeBean.kt
+1
-0
OpencvImageHelp.kt
.../com/base/filerecoveryrecyclebin/utils/OpencvImageHelp.kt
+45
-0
SimilarHelper.kt
...va/com/base/filerecoveryrecyclebin/utils/SimilarHelper.kt
+33
-19
bg_clean_tab.xml
app/src/main/res/drawable/bg_clean_tab.xml
+6
-0
activity_main.xml
app/src/main/res/layout/activity_main.xml
+2
-2
item_time_media2.xml
app/src/main/res/layout/item_time_media2.xml
+2
-2
tab_clean_n.png
app/src/main/res/mipmap-xxhdpi/tab_clean_n.png
+0
-0
tab_clean_s.png
app/src/main/res/mipmap-xxhdpi/tab_clean_s.png
+0
-0
No files found.
app/build.gradle
View file @
3d47efc0
...
...
@@ -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'
...
...
app/src/main/java/com/base/filerecoveryrecyclebin/activity/MainActivity.kt
View file @
3d47efc0
...
...
@@ -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
{
...
...
app/src/main/java/com/base/filerecoveryrecyclebin/activity/SplashActivity.kt
View file @
3d47efc0
...
...
@@ -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
...
...
app/src/main/java/com/base/filerecoveryrecyclebin/activity/repeat/RepeatActivity.kt
View file @
3d47efc0
...
...
@@ -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
)
...
...
app/src/main/java/com/base/filerecoveryrecyclebin/adapter/MediaAdapter.kt
View file @
3d47efc0
...
...
@@ -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
...
...
app/src/main/java/com/base/filerecoveryrecyclebin/bean/MediaTimeBean.kt
View file @
3d47efc0
...
...
@@ -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
...
...
app/src/main/java/com/base/filerecoveryrecyclebin/utils/OpencvImageHelp.kt
0 → 100644
View file @
3d47efc0
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
app/src/main/java/com/base/filerecoveryrecyclebin/utils/SimilarHelper.kt
View file @
3d47efc0
...
...
@@ -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
)
...
...
app/src/main/res/drawable/bg_clean_tab.xml
0 → 100644
View file @
3d47efc0
<?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
app/src/main/res/layout/activity_main.xml
View file @
3d47efc0
...
...
@@ -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_rec
yclebin
_tab"
android:background=
"@drawable/bg_rec
overy
_tab"
tools:ignore=
"ContentDescription"
/>
<TextView
...
...
app/src/main/res/layout/item_time_media2.xml
View file @
3d47efc0
...
...
@@ -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:padding
Horizontal=
"1
5dp"
>
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"
...
...
app/src/main/res/mipmap-xxhdpi/tab_clean_n.png
0 → 100644
View file @
3d47efc0
1.79 KB
app/src/main/res/mipmap-xxhdpi/tab_clean_s.png
0 → 100644
View file @
3d47efc0
1.7 KB
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment