Commit 9918d474 authored by wanglei's avatar wanglei

feat:白包修改

parents f14af91b 985eb386
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
<option name="linkedExternalProjectsSettings"> <option name="linkedExternalProjectsSettings">
<GradleProjectSettings> <GradleProjectSettings>
<option name="externalProjectPath" value="$PROJECT_DIR$" /> <option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="gradleJvm" value="#JAVA_HOME" /> <option name="gradleJvm" value="jbr-17" />
<option name="modules"> <option name="modules">
<set> <set>
<option value="$PROJECT_DIR$" /> <option value="$PROJECT_DIR$" />
......
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<project version="4"> <project version="4">
<component name="ExternalStorageConfigurationManager" enabled="true" /> <component name="ExternalStorageConfigurationManager" enabled="true" />
<component name="ProjectRootManager" version="2" languageLevel="JDK_17" default="true" project-jdk-name="17" project-jdk-type="JavaSDK"> <component name="ProjectRootManager" version="2" languageLevel="JDK_17" default="true" project-jdk-name="jbr-17" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/build/classes" /> <output url="file://$PROJECT_DIR$/build/classes" />
</component> </component>
<component name="ProjectType"> <component name="ProjectType">
......
...@@ -50,6 +50,7 @@ dependencies { ...@@ -50,6 +50,7 @@ dependencies {
implementation(libs.coil) implementation(libs.coil)
implementation(libs.coil.video) implementation(libs.coil.video)
implementation(libs.coil.gif) implementation(libs.coil.gif)
implementation(libs.androidx.datastore.preferences)
testImplementation(libs.junit) testImplementation(libs.junit)
androidTestImplementation(libs.androidx.junit) androidTestImplementation(libs.androidx.junit)
androidTestImplementation(libs.androidx.espresso.core) androidTestImplementation(libs.androidx.espresso.core)
......
...@@ -19,26 +19,36 @@ ...@@ -19,26 +19,36 @@
android:theme="@style/Theme.SolarMasterAce" android:theme="@style/Theme.SolarMasterAce"
tools:targetApi="31"> tools:targetApi="31">
<activity <activity
android:screenOrientation="portrait"
android:launchMode="singleTop"
android:name=".LaunchActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:screenOrientation="portrait"
android:name=".internalstorage.InternalStorageActivity" android:name=".internalstorage.InternalStorageActivity"
android:exported="false" /> android:exported="false" />
<activity <activity
android:screenOrientation="portrait"
android:name=".filedetails.FileDetailActivity" android:name=".filedetails.FileDetailActivity"
android:exported="false" android:exported="false"
android:launchMode="singleTop" /> android:launchMode="singleTop" />
<activity <activity
android:launchMode="singleTop" android:screenOrientation="portrait"
android:name=".filebrowser.FileBrowserActivity" android:name=".filebrowser.FileBrowserActivity"
android:exported="false" /> android:exported="false"
android:launchMode="singleTop" />
<activity <activity
android:name=".MainActivity" android:name=".MainActivity"
android:exported="true" android:exported="true"
android:screenOrientation="portrait" android:screenOrientation="portrait"
tools:ignore="DiscouragedApi,LockedOrientationActivity"> tools:ignore="DiscouragedApi,LockedOrientationActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity> </activity>
</application> </application>
......
package com.zxhy.solarmasterace
import android.content.Intent
import android.os.Bundle
import androidx.activity.enableEdgeToEdge
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import androidx.lifecycle.lifecycleScope
import com.zxhy.solarmasterace.databinding.ActivityLaunchBinding
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
class LaunchActivity : AppCompatActivity() {
private lateinit var binding: ActivityLaunchBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enableEdgeToEdge()
binding = ActivityLaunchBinding.inflate(layoutInflater)
setContentView(binding.root)
ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main)) { v, insets ->
val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars())
v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom)
insets
}
lifecycleScope.launch(Dispatchers.Main) {
var process = 0
while (process != 100) {
process += 10
binding.progressH.setProgress(process, true)
delay(200)
}
startActivity(Intent(this@LaunchActivity, MainActivity::class.java))
finish()
}
}
}
\ No newline at end of file
package com.zxhy.solarmasterace package com.zxhy.solarmasterace
import android.os.Bundle import android.os.Bundle
import android.util.Log
import android.view.MenuItem import android.view.MenuItem
import android.view.View import android.view.View
import android.widget.AdapterView import android.widget.AdapterView
...@@ -77,6 +78,5 @@ class MainActivity : AppCompatActivity() { ...@@ -77,6 +78,5 @@ class MainActivity : AppCompatActivity() {
}) })
requestStoreFollow(launcher, disAgreeAction = {}, agreeAction = {}) requestStoreFollow(launcher, disAgreeAction = {}, agreeAction = {})
} }
} }
\ No newline at end of file
...@@ -6,7 +6,6 @@ interface AdapterCommonDataFunction { ...@@ -6,7 +6,6 @@ interface AdapterCommonDataFunction {
abstract fun setData(data: List<FileBean>) abstract fun setData(data: List<FileBean>)
abstract fun addData(data: List<FileBean>) abstract fun addData(data: List<FileBean>)
abstract fun addDataFinish(data: List<FileBean>)
abstract fun clearData() abstract fun clearData()
abstract fun removeData(data: List<FileBean>) abstract fun removeData(data: List<FileBean>)
abstract fun getSelectData(): List<FileBean> abstract fun getSelectData(): List<FileBean>
......
...@@ -20,19 +20,11 @@ abstract class CommonAdapter<T : ViewHolder?>() : RecyclerView.Adapter<T>(), ...@@ -20,19 +20,11 @@ abstract class CommonAdapter<T : ViewHolder?>() : RecyclerView.Adapter<T>(),
@SuppressLint("NotifyDataSetChanged") @SuppressLint("NotifyDataSetChanged")
override fun addData(data: List<FileBean>) { override fun addData(data: List<FileBean>) {
fileList.addAll(data)
if (firstRefresh) {
notifyDataSetChanged()
firstRefresh = false
}
}
@SuppressLint("NotifyDataSetChanged")
override fun addDataFinish(data: List<FileBean>) {
fileList.addAll(data) fileList.addAll(data)
notifyDataSetChanged() notifyDataSetChanged()
} }
@SuppressLint("NotifyDataSetChanged") @SuppressLint("NotifyDataSetChanged")
override fun clearData() { override fun clearData() {
if (fileList.size == 0) return if (fileList.size == 0) return
...@@ -61,12 +53,11 @@ abstract class CommonAdapter<T : ViewHolder?>() : RecyclerView.Adapter<T>(), ...@@ -61,12 +53,11 @@ abstract class CommonAdapter<T : ViewHolder?>() : RecyclerView.Adapter<T>(),
@SuppressLint("NotifyDataSetChanged") @SuppressLint("NotifyDataSetChanged")
override fun toggleSelect(select: Boolean) { override fun toggleSelect(select: Boolean) {
fileList.mapIndexed { index, fileBean -> fileList.forEach {
if (fileBean.isSelect != select) { fileBean ->
fileBean.isSelect = select fileBean.isSelect=select
notifyItemChanged(index, "单条刷新")
}
} }
notifyDataSetChanged()
} }
......
...@@ -174,9 +174,10 @@ fun File.isDocument(): Boolean { ...@@ -174,9 +174,10 @@ fun File.isDocument(): Boolean {
return isWord() or isExcel() or isPPt() or isPdf() or isTxt() return isWord() or isExcel() or isPPt() or isPdf() or isTxt()
} }
fun File.toFileBean(): FileBean { fun File.toFileBean(id: Long = 0): FileBean {
val timeE = SimpleDateFormat("MMM dd, yyyy", Locale.ENGLISH).format(lastModified()) val timeE = SimpleDateFormat("MMM dd, yyyy", Locale.ENGLISH).format(lastModified())
return FileBean( return FileBean(
id = id,
name = name, name = name,
path = absolutePath, path = absolutePath,
size = length(), size = length(),
......
package com.zxhy.solarmasterace.datastore
import android.content.Context
import androidx.datastore.core.DataStore
import androidx.datastore.preferences.core.Preferences
import androidx.datastore.preferences.core.edit
import androidx.datastore.preferences.core.intPreferencesKey
import androidx.datastore.preferences.preferencesDataStore
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.map
val Context.dataStore: DataStore<Preferences> by preferencesDataStore(name = "file_count")
val DUP_IMAGE_COUNTER_KEY = intPreferencesKey("dup_image_counter")
val LARGE_FILES_COUNTER_KEY = intPreferencesKey("large_files_counter")
val EMPTY_FILE_COUNTER_KEY = intPreferencesKey("empty_file_counter")
suspend fun Context.saveFileCount(key: Preferences.Key<Int>, count: Int) {
dataStore.edit {
when (key) {
DUP_IMAGE_COUNTER_KEY -> it[DUP_IMAGE_COUNTER_KEY] = count
LARGE_FILES_COUNTER_KEY -> it[LARGE_FILES_COUNTER_KEY] = count
EMPTY_FILE_COUNTER_KEY -> it[EMPTY_FILE_COUNTER_KEY] = count
}
}
}
suspend fun Context.queryFileCount(key: Preferences.Key<Int>, action: (count: Int) -> Unit) {
val flow = when (key) {
DUP_IMAGE_COUNTER_KEY -> dataStore.data.map { it[DUP_IMAGE_COUNTER_KEY] }
LARGE_FILES_COUNTER_KEY -> dataStore.data.map { it[LARGE_FILES_COUNTER_KEY] }
EMPTY_FILE_COUNTER_KEY -> {
dataStore.data.map { it[EMPTY_FILE_COUNTER_KEY] }
}
else -> null
}
flow?.collect {
if (it != null) {
action.invoke(it)
}
}
}
\ No newline at end of file
...@@ -3,6 +3,7 @@ package com.zxhy.solarmasterace.filebrowser ...@@ -3,6 +3,7 @@ package com.zxhy.solarmasterace.filebrowser
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.content.Intent import android.content.Intent
import android.os.Bundle import android.os.Bundle
import android.util.Log
import android.view.View import android.view.View
import androidx.activity.enableEdgeToEdge import androidx.activity.enableEdgeToEdge
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
...@@ -14,6 +15,10 @@ import androidx.recyclerview.widget.GridLayoutManager ...@@ -14,6 +15,10 @@ import androidx.recyclerview.widget.GridLayoutManager
import com.zxhy.solarmasterace.R import com.zxhy.solarmasterace.R
import com.zxhy.solarmasterace.data.FileBean import com.zxhy.solarmasterace.data.FileBean
import com.zxhy.solarmasterace.databinding.ActivityFileBrowserBinding import com.zxhy.solarmasterace.databinding.ActivityFileBrowserBinding
import com.zxhy.solarmasterace.datastore.DUP_IMAGE_COUNTER_KEY
import com.zxhy.solarmasterace.datastore.EMPTY_FILE_COUNTER_KEY
import com.zxhy.solarmasterace.datastore.LARGE_FILES_COUNTER_KEY
import com.zxhy.solarmasterace.datastore.saveFileCount
import com.zxhy.solarmasterace.dialog.showLoadingDialog import com.zxhy.solarmasterace.dialog.showLoadingDialog
import com.zxhy.solarmasterace.filedetails.FileDetailActivity import com.zxhy.solarmasterace.filedetails.FileDetailActivity
import com.zxhy.solarmasterace.permission.requestStoreFollow import com.zxhy.solarmasterace.permission.requestStoreFollow
...@@ -72,25 +77,61 @@ class FileBrowserActivity : AppCompatActivity() { ...@@ -72,25 +77,61 @@ class FileBrowserActivity : AppCompatActivity() {
private fun showBrowser() { private fun showBrowser() {
when (title) { when (title) {
"Duplicate picture" -> dupImageMode()
"Scan large files" -> largeFileMode()
"Scan empty file" -> emptyFileMode()
"Image" -> imageMode() "Image" -> imageMode()
"Video" -> videoMode() "Video" -> videoMode()
"Audio" -> audioMode()
"Apk" -> apkMode() "Audio" -> audioMode()//
"Zip" -> zipMode() "Apk" -> apkMode()//
"Log file" -> logFileMode() "Zip" -> zipMode()//
"Word" -> wordMode() "Log file" -> logFileMode()//
"Excel" -> excelMode() "Word" -> wordMode()//
"PPT" -> pptMode() "Excel" -> excelMode()//
"PDF" -> pdfMode() "PPT" -> pptMode()//
"TXT" -> txtMode() "PDF" -> pdfMode()//
"Documents" -> documentMode() "TXT" -> txtMode()//
"Documents" -> documentMode()//
"Scan large files" -> largeFileMode()//
"Scan empty file" -> emptyFileMode()//
"Duplicate picture" -> dupImageMode()
} }
} }
@SuppressLint("SetTextI18n")
private fun loadImageFile() {
val dialog = showLoadingDialog()
fileGridAdapter.clearData()
var doLaunch = false
val waitList = ArrayList<FileBean>()
imageFile(lifecycleScope,
onDo = { data ->
if (doLaunch) {
doLaunch = true
lifecycleScope.launch(Dispatchers.Main) {
dialog.dismiss()
fileGridAdapter.addData(data)
}
} else {
waitList.addAll(data)
}
},
onFinish = { data, count ->
lifecycleScope.launch(Dispatchers.Main) {
dialog.dismiss()
waitList.addAll(data)
fileGridAdapter.addData(waitList)
binding.tvTip1.text = "$count items"
binding.ivAll.isSelected = false
showEmptyUi()
}
}
)
}
private fun documentMode() { private fun documentMode() {
cardUi() cardUi()
loadDocumentFile() loadDocumentFile()
...@@ -99,18 +140,26 @@ class FileBrowserActivity : AppCompatActivity() { ...@@ -99,18 +140,26 @@ class FileBrowserActivity : AppCompatActivity() {
private fun loadDocumentFile() { private fun loadDocumentFile() {
val dialog = showLoadingDialog() val dialog = showLoadingDialog()
cardFileAdapter.clearData() cardFileAdapter.clearData()
var doLaunch = false
val waitList = ArrayList<FileBean>()
lifecycleScope.launch(Dispatchers.IO) { lifecycleScope.launch(Dispatchers.IO) {
documentFile( documentFile(
onDo = { data -> onDo = { data ->
launch(Dispatchers.Main) { if (doLaunch) {
dialog.dismiss() doLaunch = true
cardFileAdapter.addData(data) lifecycleScope.launch(Dispatchers.Main) {
dialog.dismiss()
cardFileAdapter.addData(data)
}
} else {
waitList.addAll(data)
} }
}, },
onFinish = { data, count -> onFinish = { data, count ->
launch(Dispatchers.Main) { lifecycleScope.launch(Dispatchers.Main) {
dialog.dismiss() dialog.dismiss()
cardFileAdapter.addDataFinish(data) waitList.addAll(data)
cardFileAdapter.addData(waitList)
binding.tvTip1.text = "$count items" binding.tvTip1.text = "$count items"
binding.ivAll.isSelected = false binding.ivAll.isSelected = false
showEmptyUi() showEmptyUi()
...@@ -128,18 +177,26 @@ class FileBrowserActivity : AppCompatActivity() { ...@@ -128,18 +177,26 @@ class FileBrowserActivity : AppCompatActivity() {
private fun loadTxtFile() { private fun loadTxtFile() {
val dialog = showLoadingDialog() val dialog = showLoadingDialog()
cardFileAdapter.clearData() cardFileAdapter.clearData()
var doLaunch = false
val waitList = ArrayList<FileBean>()
lifecycleScope.launch(Dispatchers.IO) { lifecycleScope.launch(Dispatchers.IO) {
txtFile( txtFile(
onDo = { data -> onDo = { data ->
launch(Dispatchers.Main) { if (doLaunch) {
dialog.dismiss() doLaunch = true
cardFileAdapter.addData(data) lifecycleScope.launch(Dispatchers.Main) {
dialog.dismiss()
cardFileAdapter.addData(data)
}
} else {
waitList.addAll(data)
} }
}, },
onFinish = { data, count -> onFinish = { data, count ->
launch(Dispatchers.Main) { lifecycleScope.launch(Dispatchers.Main) {
dialog.dismiss() dialog.dismiss()
cardFileAdapter.addDataFinish(data) waitList.addAll(data)
cardFileAdapter.addData(waitList)
binding.tvTip1.text = "$count items" binding.tvTip1.text = "$count items"
binding.ivAll.isSelected = false binding.ivAll.isSelected = false
showEmptyUi() showEmptyUi()
...@@ -157,18 +214,26 @@ class FileBrowserActivity : AppCompatActivity() { ...@@ -157,18 +214,26 @@ class FileBrowserActivity : AppCompatActivity() {
private fun loadPdfFile() { private fun loadPdfFile() {
val dialog = showLoadingDialog() val dialog = showLoadingDialog()
cardFileAdapter.clearData() cardFileAdapter.clearData()
var doLaunch = false
val waitList = ArrayList<FileBean>()
lifecycleScope.launch(Dispatchers.IO) { lifecycleScope.launch(Dispatchers.IO) {
pdfFile( pdfFile(
onDo = { data -> onDo = { data ->
launch(Dispatchers.Main) { if (doLaunch) {
dialog.dismiss() doLaunch = true
cardFileAdapter.addData(data) lifecycleScope.launch(Dispatchers.Main) {
dialog.dismiss()
cardFileAdapter.addData(data)
}
} else {
waitList.addAll(data)
} }
}, },
onFinish = { data, count -> onFinish = { data, count ->
launch(Dispatchers.Main) { lifecycleScope.launch(Dispatchers.Main) {
dialog.dismiss() dialog.dismiss()
cardFileAdapter.addDataFinish(data) waitList.addAll(data)
cardFileAdapter.addData(waitList)
binding.tvTip1.text = "$count items" binding.tvTip1.text = "$count items"
binding.ivAll.isSelected = false binding.ivAll.isSelected = false
showEmptyUi() showEmptyUi()
...@@ -187,18 +252,26 @@ class FileBrowserActivity : AppCompatActivity() { ...@@ -187,18 +252,26 @@ class FileBrowserActivity : AppCompatActivity() {
private fun loadPptFile() { private fun loadPptFile() {
val dialog = showLoadingDialog() val dialog = showLoadingDialog()
cardFileAdapter.clearData() cardFileAdapter.clearData()
var doLaunch = false
val waitList = ArrayList<FileBean>()
lifecycleScope.launch(Dispatchers.IO) { lifecycleScope.launch(Dispatchers.IO) {
pptFile( pptFile(
onDo = { data -> onDo = { data ->
launch(Dispatchers.Main) { if (doLaunch) {
dialog.dismiss() doLaunch = true
cardFileAdapter.addData(data) lifecycleScope.launch(Dispatchers.Main) {
dialog.dismiss()
cardFileAdapter.addData(data)
}
} else {
waitList.addAll(data)
} }
}, },
onFinish = { data, count -> onFinish = { data, count ->
launch(Dispatchers.Main) { lifecycleScope.launch(Dispatchers.Main) {
dialog.dismiss() dialog.dismiss()
cardFileAdapter.addDataFinish(data) waitList.addAll(data)
cardFileAdapter.addData(waitList)
binding.tvTip1.text = "$count items" binding.tvTip1.text = "$count items"
binding.ivAll.isSelected = false binding.ivAll.isSelected = false
showEmptyUi() showEmptyUi()
...@@ -267,18 +340,26 @@ class FileBrowserActivity : AppCompatActivity() { ...@@ -267,18 +340,26 @@ class FileBrowserActivity : AppCompatActivity() {
private fun loadExcelFile() { private fun loadExcelFile() {
val dialog = showLoadingDialog() val dialog = showLoadingDialog()
cardFileAdapter.clearData() cardFileAdapter.clearData()
var doLaunch = false
val waitList = ArrayList<FileBean>()
lifecycleScope.launch(Dispatchers.IO) { lifecycleScope.launch(Dispatchers.IO) {
excelFile( excelFile(
onDo = { data -> onDo = { data ->
launch(Dispatchers.Main) { if (doLaunch) {
dialog.dismiss() doLaunch = true
cardFileAdapter.addData(data) lifecycleScope.launch(Dispatchers.Main) {
dialog.dismiss()
cardFileAdapter.addData(data)
}
} else {
waitList.addAll(data)
} }
}, },
onFinish = { data, count -> onFinish = { data, count ->
launch(Dispatchers.Main) { lifecycleScope.launch(Dispatchers.Main) {
dialog.dismiss() dialog.dismiss()
cardFileAdapter.addDataFinish(data) waitList.addAll(data)
cardFileAdapter.addData(waitList)
binding.tvTip1.text = "$count items" binding.tvTip1.text = "$count items"
binding.ivAll.isSelected = false binding.ivAll.isSelected = false
showEmptyUi() showEmptyUi()
...@@ -323,47 +404,65 @@ class FileBrowserActivity : AppCompatActivity() { ...@@ -323,47 +404,65 @@ class FileBrowserActivity : AppCompatActivity() {
loadImageFile() loadImageFile()
} }
@SuppressLint("SetTextI18n") @SuppressLint("SetTextI18n")
private fun loadWordFile() { private fun loadLargeFile() {
val dialog = showLoadingDialog() val dialog = showLoadingDialog()
cardFileAdapter.clearData() cardFileAdapter.clearData()
lifecycleScope.launch(Dispatchers.IO) { var doLaunch = false
wordFile( val waitList = ArrayList<FileBean>()
onDo = { data -> largeFile(
launch(Dispatchers.Main) { lifecycleScope,
onDo = { data ->
if (doLaunch) {
doLaunch = true
lifecycleScope.launch(Dispatchers.Main) {
dialog.dismiss() dialog.dismiss()
cardFileAdapter.addData(data) cardFileAdapter.addData(data)
} }
}, } else {
onFinish = { data, count -> waitList.addAll(data)
launch(Dispatchers.Main) {
dialog.dismiss()
cardFileAdapter.addDataFinish(data)
binding.tvTip1.text = "$count items"
binding.ivAll.isSelected = false
showEmptyUi()
}
} }
) },
} onFinish = { data, count ->
lifecycleScope.launch(Dispatchers.Main) {
dialog.dismiss()
waitList.addAll(data)
cardFileAdapter.addData(waitList)
binding.tvTip1.text = "$count items"
binding.ivAll.isSelected = false
showEmptyUi()
saveFileCount(LARGE_FILES_COUNTER_KEY, count)
}
}
)
} }
@SuppressLint("SetTextI18n") @SuppressLint("SetTextI18n")
private fun loadImageFile() { private fun loadWordFile() {
val dialog = showLoadingDialog() val dialog = showLoadingDialog()
fileGridAdapter.clearData() cardFileAdapter.clearData()
var doLaunch = false
val waitList = ArrayList<FileBean>()
lifecycleScope.launch(Dispatchers.IO) { lifecycleScope.launch(Dispatchers.IO) {
imageFile( wordFile(
onDo = { data -> onDo = { data ->
launch(Dispatchers.Main) { if (doLaunch) {
dialog.dismiss() doLaunch = true
fileGridAdapter.addData(data) lifecycleScope.launch(Dispatchers.Main) {
dialog.dismiss()
cardFileAdapter.addData(data)
}
} else {
waitList.addAll(data)
} }
}, },
onFinish = { data, count -> onFinish = { data, count ->
launch(Dispatchers.Main) { lifecycleScope.launch(Dispatchers.Main) {
dialog.dismiss() dialog.dismiss()
fileGridAdapter.addDataFinish(data) waitList.addAll(data)
cardFileAdapter.addData(waitList)
binding.tvTip1.text = "$count items" binding.tvTip1.text = "$count items"
binding.ivAll.isSelected = false binding.ivAll.isSelected = false
showEmptyUi() showEmptyUi()
...@@ -373,22 +472,31 @@ class FileBrowserActivity : AppCompatActivity() { ...@@ -373,22 +472,31 @@ class FileBrowserActivity : AppCompatActivity() {
} }
} }
@SuppressLint("SetTextI18n") @SuppressLint("SetTextI18n")
private fun loadVideoFile() { private fun loadVideoFile() {
val dialog = showLoadingDialog() val dialog = showLoadingDialog()
fileGridAdapter.clearData() fileGridAdapter.clearData()
var doLaunch = false
val waitList = ArrayList<FileBean>()
lifecycleScope.launch(Dispatchers.IO) { lifecycleScope.launch(Dispatchers.IO) {
videoFile( videoFile(
onDo = { data -> onDo = { data ->
launch(Dispatchers.Main) { if (doLaunch) {
dialog.dismiss() doLaunch = true
fileGridAdapter.addData(data) lifecycleScope.launch(Dispatchers.Main) {
dialog.dismiss()
fileGridAdapter.addData(data)
}
} else {
waitList.addAll(data)
} }
}, },
onFinish = { data, count -> onFinish = { data, count ->
launch(Dispatchers.Main) { lifecycleScope.launch(Dispatchers.Main) {
dialog.dismiss() dialog.dismiss()
fileGridAdapter.addDataFinish(data) waitList.addAll(data)
fileGridAdapter.addData(waitList)
binding.tvTip1.text = "$count items" binding.tvTip1.text = "$count items"
binding.ivAll.isSelected = false binding.ivAll.isSelected = false
showEmptyUi() showEmptyUi()
...@@ -399,23 +507,7 @@ class FileBrowserActivity : AppCompatActivity() { ...@@ -399,23 +507,7 @@ class FileBrowserActivity : AppCompatActivity() {
} }
private fun largeFileMode() { private fun largeFileMode() {
binding.tvTip1.visibility = View.VISIBLE cardUi()
binding.tvTip2.visibility = View.VISIBLE
cardFileAdapter = CardFileAdapter {
binding.ivAll.isSelected = it
}
binding.rv.adapter = cardFileAdapter
binding.ivAll.setOnClickListener {
it.isSelected = !it.isSelected
cardFileAdapter.toggleSelect(it.isSelected)
}
binding.tvDelete.background =
ContextCompat.getDrawable(this, R.drawable.bg_ff5c67e5_corners)
binding.tvDelete.text = "删除"
binding.tvDelete.setTextColor(ContextCompat.getColor(this, R.color.white))
binding.tvDelete.setOnClickListener {
deleteCardFile(cardFileAdapter.getSelectData())
}
loadLargeFile() loadLargeFile()
} }
...@@ -438,47 +530,31 @@ class FileBrowserActivity : AppCompatActivity() { ...@@ -438,47 +530,31 @@ class FileBrowserActivity : AppCompatActivity() {
deleteFiles(files.map { it.file() }) deleteFiles(files.map { it.file() })
} }
@SuppressLint("SetTextI18n")
private fun loadLargeFile() {
val dialog = showLoadingDialog()
cardFileAdapter.clearData()
lifecycleScope.launch(Dispatchers.IO) {
largeFile(
onDo = { data ->
launch(Dispatchers.Main) {
dialog.dismiss()
cardFileAdapter.addData(data)
}
},
onFinish = { data, count ->
launch(Dispatchers.Main) {
dialog.dismiss()
cardFileAdapter.addDataFinish(data)
binding.tvTip1.text = "$count items"
binding.ivAll.isSelected = false
showEmptyUi()
}
}
)
}
}
@SuppressLint("SetTextI18n") @SuppressLint("SetTextI18n")
private fun loadAudioFile() { private fun loadAudioFile() {
val dialog = showLoadingDialog() val dialog = showLoadingDialog()
cardFileAdapter.clearData() cardFileAdapter.clearData()
var doLaunch = false
val waitList = ArrayList<FileBean>()
lifecycleScope.launch(Dispatchers.IO) { lifecycleScope.launch(Dispatchers.IO) {
audioFile( audioFile(
onDo = { data -> onDo = { data ->
launch(Dispatchers.Main) { if (doLaunch) {
dialog.dismiss() doLaunch = true
cardFileAdapter.addData(data) lifecycleScope.launch(Dispatchers.Main) {
dialog.dismiss()
cardFileAdapter.addData(data)
}
} else {
waitList.addAll(data)
} }
}, },
onFinish = { data, count -> onFinish = { data, count ->
launch(Dispatchers.Main) { lifecycleScope.launch(Dispatchers.Main) {
dialog.dismiss() dialog.dismiss()
cardFileAdapter.addDataFinish(data) waitList.addAll(data)
cardFileAdapter.addData(waitList)
binding.tvTip1.text = "$count items" binding.tvTip1.text = "$count items"
binding.ivAll.isSelected = false binding.ivAll.isSelected = false
showEmptyUi() showEmptyUi()
...@@ -492,18 +568,26 @@ class FileBrowserActivity : AppCompatActivity() { ...@@ -492,18 +568,26 @@ class FileBrowserActivity : AppCompatActivity() {
private fun loadApkFile() { private fun loadApkFile() {
val dialog = showLoadingDialog() val dialog = showLoadingDialog()
cardFileAdapter.clearData() cardFileAdapter.clearData()
var doLaunch = false
val waitList = ArrayList<FileBean>()
lifecycleScope.launch(Dispatchers.IO) { lifecycleScope.launch(Dispatchers.IO) {
apkFile( apkFile(
onDo = { data -> onDo = { data ->
launch(Dispatchers.Main) { if (doLaunch) {
dialog.dismiss() doLaunch = true
cardFileAdapter.addData(data) lifecycleScope.launch(Dispatchers.Main) {
dialog.dismiss()
cardFileAdapter.addData(data)
}
} else {
waitList.addAll(data)
} }
}, },
onFinish = { data, count -> onFinish = { data, count ->
launch(Dispatchers.Main) { lifecycleScope.launch(Dispatchers.Main) {
dialog.dismiss() dialog.dismiss()
cardFileAdapter.addDataFinish(data) waitList.addAll(data)
cardFileAdapter.addData(waitList)
binding.tvTip1.text = "$count items" binding.tvTip1.text = "$count items"
binding.ivAll.isSelected = false binding.ivAll.isSelected = false
showEmptyUi() showEmptyUi()
...@@ -517,18 +601,26 @@ class FileBrowserActivity : AppCompatActivity() { ...@@ -517,18 +601,26 @@ class FileBrowserActivity : AppCompatActivity() {
private fun loadZipFile() { private fun loadZipFile() {
val dialog = showLoadingDialog() val dialog = showLoadingDialog()
cardFileAdapter.clearData() cardFileAdapter.clearData()
var doLaunch = false
val waitList = ArrayList<FileBean>()
lifecycleScope.launch(Dispatchers.IO) { lifecycleScope.launch(Dispatchers.IO) {
zipFile( zipFile(
onDo = { data -> onDo = { data ->
launch(Dispatchers.Main) { if (doLaunch) {
dialog.dismiss() doLaunch = true
cardFileAdapter.addData(data) lifecycleScope.launch(Dispatchers.Main) {
dialog.dismiss()
cardFileAdapter.addData(data)
}
} else {
waitList.addAll(data)
} }
}, },
onFinish = { data, count -> onFinish = { data, count ->
launch(Dispatchers.Main) { lifecycleScope.launch(Dispatchers.Main) {
dialog.dismiss() dialog.dismiss()
cardFileAdapter.addDataFinish(data) waitList.addAll(data)
cardFileAdapter.addData(waitList)
binding.tvTip1.text = "$count items" binding.tvTip1.text = "$count items"
binding.ivAll.isSelected = false binding.ivAll.isSelected = false
showEmptyUi() showEmptyUi()
...@@ -542,18 +634,27 @@ class FileBrowserActivity : AppCompatActivity() { ...@@ -542,18 +634,27 @@ class FileBrowserActivity : AppCompatActivity() {
private fun loadLogFile() { private fun loadLogFile() {
val dialog = showLoadingDialog() val dialog = showLoadingDialog()
cardFileAdapter.clearData() cardFileAdapter.clearData()
var doLaunch = false
val waitList = ArrayList<FileBean>()
lifecycleScope.launch(Dispatchers.IO) { lifecycleScope.launch(Dispatchers.IO) {
logFile( logFile(
onDo = { data -> onDo = { data ->
launch(Dispatchers.Main) { if (doLaunch) {
dialog.dismiss() doLaunch = true
cardFileAdapter.addData(data) lifecycleScope.launch(Dispatchers.Main) {
dialog.dismiss()
Log.e("TAG", data.toString())
cardFileAdapter.addData(data)
}
} else {
waitList.addAll(data)
} }
}, },
onFinish = { data, count -> onFinish = { data, count ->
launch(Dispatchers.Main) { lifecycleScope.launch(Dispatchers.Main) {
dialog.dismiss() dialog.dismiss()
cardFileAdapter.addDataFinish(data) waitList.addAll(data)
cardFileAdapter.addData(waitList)
binding.tvTip1.text = "$count items" binding.tvTip1.text = "$count items"
binding.ivAll.isSelected = false binding.ivAll.isSelected = false
showEmptyUi() showEmptyUi()
...@@ -572,21 +673,30 @@ class FileBrowserActivity : AppCompatActivity() { ...@@ -572,21 +673,30 @@ class FileBrowserActivity : AppCompatActivity() {
private fun loadEmptyFile() { private fun loadEmptyFile() {
val dialog = showLoadingDialog() val dialog = showLoadingDialog()
cardFileAdapter.clearData() cardFileAdapter.clearData()
var doLaunch = false
val waitList = ArrayList<FileBean>()
lifecycleScope.launch(Dispatchers.IO) { lifecycleScope.launch(Dispatchers.IO) {
emptyFile( emptyFile(
onDo = { data -> onDo = { data ->
launch(Dispatchers.Main) { if (doLaunch) {
dialog.dismiss() doLaunch = true
cardFileAdapter.addData(data) lifecycleScope.launch(Dispatchers.Main) {
dialog.dismiss()
cardFileAdapter.addData(data)
}
} else {
waitList.addAll(data)
} }
}, },
onFinish = { data, count -> onFinish = { data, count ->
launch(Dispatchers.Main) { lifecycleScope.launch(Dispatchers.Main) {
dialog.dismiss() dialog.dismiss()
cardFileAdapter.addDataFinish(data) waitList.addAll(data)
cardFileAdapter.addData(waitList)
binding.tvTip1.text = "$count items" binding.tvTip1.text = "$count items"
binding.ivAll.isSelected = false binding.ivAll.isSelected = false
showEmptyUi() showEmptyUi()
saveFileCount(EMPTY_FILE_COUNTER_KEY, count)
} }
} }
) )
...@@ -635,6 +745,8 @@ class FileBrowserActivity : AppCompatActivity() { ...@@ -635,6 +745,8 @@ class FileBrowserActivity : AppCompatActivity() {
dupImageAdapter.setData(data) dupImageAdapter.setData(data)
binding.ivAll.isSelected = false binding.ivAll.isSelected = false
showEmptyUi() showEmptyUi()
saveFileCount(DUP_IMAGE_COUNTER_KEY, data.sumOf { it.dupData.size })
} }
} }
} }
......
package com.zxhy.solarmasterace.internalstorage package com.zxhy.solarmasterace.internalstorage
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.content.Context
import android.os.Environment import android.os.Environment
import android.util.Log import android.util.Log
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.core.content.ContextCompat
import com.zxhy.solarmasterace.R import com.zxhy.solarmasterace.R
import com.zxhy.solarmasterace.adapter.CommonAdapter import com.zxhy.solarmasterace.adapter.CommonAdapter
import com.zxhy.solarmasterace.adapter.ItemCardFileViewHolder import com.zxhy.solarmasterace.adapter.ItemCardFileViewHolder
...@@ -21,6 +23,7 @@ class FileDirectoryAdapter( ...@@ -21,6 +23,7 @@ class FileDirectoryAdapter(
private var currentDir = Environment.getExternalStorageDirectory() private var currentDir = Environment.getExternalStorageDirectory()
private var isSelectMode = false private var isSelectMode = false
private var pageTurn = true private var pageTurn = true
private var operationFile = arrayListOf<FileBean>()
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ItemCardFileViewHolder { override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ItemCardFileViewHolder {
return ItemCardFileViewHolder(R.layout.item_card_file.inflate(parent)) return ItemCardFileViewHolder(R.layout.item_card_file.inflate(parent))
...@@ -68,6 +71,18 @@ class FileDirectoryAdapter( ...@@ -68,6 +71,18 @@ class FileDirectoryAdapter(
if (!pageTurn) return@setOnClickListener if (!pageTurn) return@setOnClickListener
nextPage(data) nextPage(data)
} }
//该列表是选中列表
if (operationFile.map { it.path }.contains(data.path)) {
root.setOnClickListener { }
root.setCardBackgroundColor(
ContextCompat.getColor(
context, R.color.color_F4F4F4
)
)
} else {
root.setCardBackgroundColor(ContextCompat.getColor(context, R.color.white))
}
} }
} else { } else {
holder.binding.apply { holder.binding.apply {
...@@ -118,4 +133,16 @@ class FileDirectoryAdapter( ...@@ -118,4 +133,16 @@ class FileDirectoryAdapter(
return currentDir return currentDir
} }
//当选中选中的列表,无法复制 移动到自身
fun notifyCannotSelect(data: List<FileBean>) {
val selectList = arrayListOf<FileBean>()
selectList.addAll(data)
operationFile = selectList
notifyDataSetChanged()
}
fun clearCannotSelect() {
operationFile = arrayListOf()
}
} }
\ No newline at end of file
...@@ -31,8 +31,7 @@ class InternalStorageActivity : AppCompatActivity() { ...@@ -31,8 +31,7 @@ class InternalStorageActivity : AppCompatActivity() {
private val MODE_BROWSE = 0 private val MODE_BROWSE = 0
private val MODE_SELECT = 1 private val MODE_SELECT = 1
private val MODE_SELECTED_OPERATION = 2 private val MODE_SELECTED_OPERATION = 2
private val MODE_LOCK = -1 private var currentMode = MODE_BROWSE //0普通浏览模式 1可选模式 2选中操作模式
private var currentMode = MODE_BROWSE //0普通浏览模式 1可选模式 2选中操作模式 -1无权限锁功能模式
private lateinit var activityLauncher: ActivityLauncher private lateinit var activityLauncher: ActivityLauncher
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
...@@ -53,9 +52,11 @@ class InternalStorageActivity : AppCompatActivity() { ...@@ -53,9 +52,11 @@ class InternalStorageActivity : AppCompatActivity() {
} }
binding.clArrow.setOnClickListener { binding.clArrow.setOnClickListener {
val flag = fileDirectoryAdapter.beforePage() if (this::fileDirectoryAdapter.isInitialized) {
if (flag) val flag = fileDirectoryAdapter.beforePage()
finish() if (flag)
finish()
}
} }
} }
...@@ -88,6 +89,20 @@ class InternalStorageActivity : AppCompatActivity() { ...@@ -88,6 +89,20 @@ class InternalStorageActivity : AppCompatActivity() {
binding.llAll.visibility = View.GONE binding.llAll.visibility = View.GONE
binding.ivWrite.visibility = View.VISIBLE binding.ivWrite.visibility = View.VISIBLE
binding.ivWrite.setOnClickListener { binding.ivWrite.setOnClickListener {
// showFolderDialog(tittle = "New Folder", newFolder = { name ->
// val dir = fileDirectoryAdapter.getCurrentDir()
// val file = File(dir, name)
// if (!file.exists()) {
// file.mkdir()
// }
// fileDirectoryAdapter.notifyCurrentDir()
// })
switchSelectMode()
}
binding.ivAdd.setOnClickListener {
// switchSelectMode()
showFolderDialog(tittle = "New Folder", newFolder = { name -> showFolderDialog(tittle = "New Folder", newFolder = { name ->
val dir = fileDirectoryAdapter.getCurrentDir() val dir = fileDirectoryAdapter.getCurrentDir()
val file = File(dir, name) val file = File(dir, name)
...@@ -97,9 +112,6 @@ class InternalStorageActivity : AppCompatActivity() { ...@@ -97,9 +112,6 @@ class InternalStorageActivity : AppCompatActivity() {
fileDirectoryAdapter.notifyCurrentDir() fileDirectoryAdapter.notifyCurrentDir()
}) })
} }
binding.ivAdd.setOnClickListener {
switchSelectMode()
}
binding.ivMore.setOnClickListener { binding.ivMore.setOnClickListener {
val fileBeanList = fileDirectoryAdapter.getSelectData() val fileBeanList = fileDirectoryAdapter.getSelectData()
val fileList = fileBeanList.map { it.file() } val fileList = fileBeanList.map { it.file() }
...@@ -148,16 +160,21 @@ class InternalStorageActivity : AppCompatActivity() { ...@@ -148,16 +160,21 @@ class InternalStorageActivity : AppCompatActivity() {
val files = fileDirectoryAdapter.getSelectData().map { it.file() } val files = fileDirectoryAdapter.getSelectData().map { it.file() }
deleteFiles(files) { deleteFiles(files) {
showCardTip("Successfully deleted!") showCardTip("Successfully deleted!")
switchBrowseMode()
} }
} }
binding.ivMove.setOnClickListener { binding.ivMove.setOnClickListener {
val moveFile = arrayListOf<File>() val moveFile = arrayListOf<File>()
fileDirectoryAdapter.getSelectData().map { moveFile.add(it.file()) } val selectList = fileDirectoryAdapter.getSelectData()
selectList.map { moveFile.add(it.file()) }
fileDirectoryAdapter.notifyCannotSelect(selectList)
switchSelectedOperationMode("Motion", moveFile) switchSelectedOperationMode("Motion", moveFile)
} }
binding.ivCopy.setOnClickListener { binding.ivCopy.setOnClickListener {
val copyFile = arrayListOf<File>() val copyFile = arrayListOf<File>()
fileDirectoryAdapter.getSelectData().map { copyFile.add(it.file()) } val selectList = fileDirectoryAdapter.getSelectData()
selectList.map { copyFile.add(it.file()) }
fileDirectoryAdapter.notifyCannotSelect(selectList)
switchSelectedOperationMode("Copy", copyFile) switchSelectedOperationMode("Copy", copyFile)
} }
} }
...@@ -185,6 +202,7 @@ class InternalStorageActivity : AppCompatActivity() { ...@@ -185,6 +202,7 @@ class InternalStorageActivity : AppCompatActivity() {
binding.tvDefine.setOnClickListener { binding.tvDefine.setOnClickListener {
moveFiles(files) { moveFiles(files) {
showCardTip("Successfully moved!") showCardTip("Successfully moved!")
fileDirectoryAdapter.clearCannotSelect()
switchBrowseMode() switchBrowseMode()
} }
} }
...@@ -193,6 +211,7 @@ class InternalStorageActivity : AppCompatActivity() { ...@@ -193,6 +211,7 @@ class InternalStorageActivity : AppCompatActivity() {
"Copy" -> { "Copy" -> {
binding.tvDefine.setOnClickListener { binding.tvDefine.setOnClickListener {
copyFiles(files) { copyFiles(files) {
fileDirectoryAdapter.clearCannotSelect()
showCardTip("Successfully copied!") showCardTip("Successfully copied!")
switchBrowseMode() switchBrowseMode()
} }
...@@ -200,6 +219,7 @@ class InternalStorageActivity : AppCompatActivity() { ...@@ -200,6 +219,7 @@ class InternalStorageActivity : AppCompatActivity() {
} }
} }
binding.tvCancel.setOnClickListener { binding.tvCancel.setOnClickListener {
fileDirectoryAdapter.clearCannotSelect()
switchBrowseMode() switchBrowseMode()
} }
} }
...@@ -210,7 +230,10 @@ class InternalStorageActivity : AppCompatActivity() { ...@@ -210,7 +230,10 @@ class InternalStorageActivity : AppCompatActivity() {
val dir = fileDirectoryAdapter.getCurrentDir() ?: File("") val dir = fileDirectoryAdapter.getCurrentDir() ?: File("")
files.forEach { files.forEach {
if (it.isFile) { if (it.isFile) {
it.copyTo(File(dir, it.name)) val destFile = File(dir, it.name)
if (!destFile.exists()) {
it.copyTo(destFile)
}
} else { } else {
FileHelper.copyDirectory(it, File(dir, it.name)) FileHelper.copyDirectory(it, File(dir, it.name))
} }
...@@ -265,7 +288,10 @@ class InternalStorageActivity : AppCompatActivity() { ...@@ -265,7 +288,10 @@ class InternalStorageActivity : AppCompatActivity() {
if (event.keyCode == KeyEvent.KEYCODE_BACK && event.action == KeyEvent.ACTION_UP) { if (event.keyCode == KeyEvent.KEYCODE_BACK && event.action == KeyEvent.ACTION_UP) {
when (currentMode) { when (currentMode) {
MODE_BROWSE -> { MODE_BROWSE -> {
val flag = fileDirectoryAdapter.beforePage() var flag = true
if (this::fileDirectoryAdapter.isInitialized) {
flag = fileDirectoryAdapter.beforePage()
}
return if (flag) super.dispatchKeyEvent(event) else false return if (flag) super.dispatchKeyEvent(event) else false
} }
......
package com.zxhy.solarmasterace.quicktools package com.zxhy.solarmasterace.quicktools
import android.os.Environment import android.os.Environment
import androidx.lifecycle.LifecycleCoroutineScope
import androidx.lifecycle.lifecycleScope
import com.zxhy.solarmasterace.data.DupFileBean import com.zxhy.solarmasterace.data.DupFileBean
import com.zxhy.solarmasterace.data.FileBean import com.zxhy.solarmasterace.data.FileBean
import com.zxhy.solarmasterace.data.isApk import com.zxhy.solarmasterace.data.isApk
...@@ -16,6 +18,8 @@ import com.zxhy.solarmasterace.data.isVideo ...@@ -16,6 +18,8 @@ import com.zxhy.solarmasterace.data.isVideo
import com.zxhy.solarmasterace.data.isWord import com.zxhy.solarmasterace.data.isWord
import com.zxhy.solarmasterace.data.isZip import com.zxhy.solarmasterace.data.isZip
import com.zxhy.solarmasterace.data.toFileBean import com.zxhy.solarmasterace.data.toFileBean
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import java.io.File import java.io.File
import java.util.Stack import java.util.Stack
...@@ -52,23 +56,28 @@ fun dupImage(): List<DupFileBean> { ...@@ -52,23 +56,28 @@ fun dupImage(): List<DupFileBean> {
} }
fun largeFile( fun largeFile(
lifecycleScope: LifecycleCoroutineScope,
onDo: ((file: List<FileBean>) -> Unit)? = null, onDo: ((file: List<FileBean>) -> Unit)? = null,
onFinish: ((file: List<FileBean>, count: Int) -> Unit)? = null onFinish: ((file: List<FileBean>, count: Int) -> Unit)? = null
) { ) {
val rootDir = Environment.getExternalStorageDirectory() lifecycleScope.launch(Dispatchers.IO) {
val tempList = arrayListOf<FileBean>() val rootDir = Environment.getExternalStorageDirectory()
var count = 0 val tempList = arrayListOf<FileBean>()
FileHelper.linkedLisTraverseFolder(rootDir) { var count = 0
if (it.length() > 10 * 1024 * 1024) { FileHelper.linkedLisTraverseFolder(rootDir) {
tempList.add(it.toFileBean()) if (it.length() > 10 * 1024 * 1024) {
count++ tempList.add(it.toFileBean())
if (tempList.size == 10) { count++
onDo?.invoke(tempList) if (tempList.size == 10) {
tempList.clear() onDo?.invoke(tempList)
tempList.clear()
}
} }
} }
onFinish?.invoke(tempList, count)
} }
onFinish?.invoke(tempList, count)
} }
fun audioFile( fun audioFile(
...@@ -295,25 +304,29 @@ fun emptyFile( ...@@ -295,25 +304,29 @@ fun emptyFile(
} }
fun imageFile( fun imageFile(
lifecycleCoroutineScope: LifecycleCoroutineScope,
onDo: ((file: List<FileBean>) -> Unit)? = null, onDo: ((file: List<FileBean>) -> Unit)? = null,
onFinish: ((file: List<FileBean>, count: Int) -> Unit)? = null onFinish: ((file: List<FileBean>, count: Long) -> Unit)? = null
) { ) {
val rootDir = Environment.getExternalStorageDirectory() lifecycleCoroutineScope.launch(Dispatchers.IO) {
val tempList = arrayListOf<FileBean>() val rootDir = Environment.getExternalStorageDirectory()
var count = 0 val tempList = arrayListOf<FileBean>()
FileHelper.linkedLisTraverseFolder(rootDir) { var count = 0L
if (it.isImage()) { FileHelper.linkedLisTraverseFolder(rootDir) {
tempList.add(it.toFileBean()) if (it.isImage()) {
count++ tempList.add(it.toFileBean(count))
if (tempList.size == 10) { count++
onDo?.invoke(tempList) if (tempList.size == 10) {
tempList.clear() onDo?.invoke(tempList)
tempList.clear()
}
} }
} }
onFinish?.invoke(tempList, count)
} }
onFinish?.invoke(tempList, count)
} }
fun videoFile( fun videoFile(
onDo: ((file: List<FileBean>) -> Unit)? = null, onDo: ((file: List<FileBean>) -> Unit)? = null,
onFinish: ((file: List<FileBean>, count: Int) -> Unit)? = null onFinish: ((file: List<FileBean>, count: Int) -> Unit)? = null
......
...@@ -83,13 +83,15 @@ object FileHelper { ...@@ -83,13 +83,15 @@ object FileHelper {
val currentFile = stackFiles.peek() val currentFile = stackFiles.peek()
val subFiles = currentFile.listFiles() val subFiles = currentFile.listFiles()
for (i in subFiles!!.indices) { if (subFiles != null) {
if (subFiles[i].isFile) { for (i in subFiles.indices) {
if (!subFiles[i].delete()) { if (subFiles[i].isFile) {
return false if (!subFiles[i].delete()) {
return false
}
} else {
stackFiles.push(subFiles[i])
} }
} else {
stackFiles.push(subFiles[i])
} }
} }
if (currentFile === stackFiles.peek()) { if (currentFile === stackFiles.peek()) {
...@@ -108,15 +110,22 @@ object FileHelper { ...@@ -108,15 +110,22 @@ object FileHelper {
* @param target 目标文件夹 * @param target 目标文件夹
*/ */
fun copyDirectory(source: File, target: File) { fun copyDirectory(source: File, target: File) {
if (source.isDirectory) { try {
if (!target.exists()) target.mkdir() if (source.isDirectory) {
if (!target.exists()) target.mkdir()
source.list()?.map { sub -> source.list()?.map { sub ->
copyDirectory(File(source, sub), File(target, sub)) copyDirectory(File(source, sub), File(target, sub))
}
} else {
if (!target.exists()) {
source.copyTo(target)
}
} }
} else { } catch (e: Exception) {
source.copyTo(target) e.printStackTrace()
} }
} }
} }
\ No newline at end of file
package com.zxhy.solarmasterace.tools package com.zxhy.solarmasterace.tools
import android.annotation.SuppressLint
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.os.Bundle import android.os.Bundle
...@@ -11,6 +12,11 @@ import androidx.lifecycle.lifecycleScope ...@@ -11,6 +12,11 @@ import androidx.lifecycle.lifecycleScope
import androidx.navigation.fragment.findNavController import androidx.navigation.fragment.findNavController
import com.zxhy.solarmasterace.R import com.zxhy.solarmasterace.R
import com.zxhy.solarmasterace.databinding.FragmentToolsBinding import com.zxhy.solarmasterace.databinding.FragmentToolsBinding
import com.zxhy.solarmasterace.datastore.DUP_IMAGE_COUNTER_KEY
import com.zxhy.solarmasterace.datastore.EMPTY_FILE_COUNTER_KEY
import com.zxhy.solarmasterace.datastore.LARGE_FILES_COUNTER_KEY
import com.zxhy.solarmasterace.datastore.queryFileCount
import com.zxhy.solarmasterace.datastore.saveFileCount
import com.zxhy.solarmasterace.filedetails.FileDetailActivity import com.zxhy.solarmasterace.filedetails.FileDetailActivity
import com.zxhy.solarmasterace.quicktools.getFilePathByUri import com.zxhy.solarmasterace.quicktools.getFilePathByUri
import com.zxhy.solarmasterace.quicktools.recentImage import com.zxhy.solarmasterace.quicktools.recentImage
...@@ -80,6 +86,44 @@ class ToolsFragment : Fragment() { ...@@ -80,6 +86,44 @@ class ToolsFragment : Fragment() {
} }
loadRecentImage() loadRecentImage()
queryFileCounts()
}
@SuppressLint("SetTextI18n")
private fun queryFileCounts() {
lifecycleScope.launch(Dispatchers.Main) {
// context.saveFileCount(DUP_IMAGE_COUNTER_KEY, 100)
context.queryFileCount(DUP_IMAGE_COUNTER_KEY) { count ->
if (count == 0) {
binding.tvDupCout.visibility = View.GONE
} else {
binding.tvDupCout.text = "$count items"
}
}
}
lifecycleScope.launch(Dispatchers.Main) {
// context.saveFileCount(LARGE_FILES_COUNTER_KEY, 200)
context.queryFileCount(LARGE_FILES_COUNTER_KEY) { count ->
if (count == 0) {
binding.tvLargeCount.visibility = View.GONE
} else {
binding.tvLargeCount.text = "$count items"
}
}
}
lifecycleScope.launch(Dispatchers.Main) {
// context.saveFileCount(EMPTY_FILE_COUNTER_KEY, 300)
context.queryFileCount(EMPTY_FILE_COUNTER_KEY) { dupCount ->
if (dupCount == 0) {
binding.tvEmptyCount.visibility = View.GONE
} else {
binding.tvEmptyCount.text = "$dupCount items"
}
}
}
} }
override fun onResume() { override fun onResume() {
......
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".LaunchActivity">
<ImageView
android:id="@+id/iv"
android:layout_width="140dp"
android:layout_height="150dp"
android:layout_marginTop="150dp"
android:src="@mipmap/zsd_589878"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:ignore="ContentDescription" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="18dp"
android:text="Solar Master Ace"
android:textColor="@color/black"
android:textSize="17sp"
android:textStyle="bold"
app:layout_constraintLeft_toLeftOf="@id/iv"
app:layout_constraintRight_toRightOf="@id/iv"
app:layout_constraintTop_toBottomOf="@id/iv"
tools:ignore="HardcodedText" />
<ProgressBar
android:id="@+id/progress_h"
style="@android:style/Widget.ProgressBar.Horizontal"
android:layout_width="match_parent"
android:layout_height="8dp"
android:layout_marginHorizontal="50dp"
android:layout_marginBottom="36dp"
android:max="100"
android:progress="0"
android:progressTint="@color/black"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:text="loading..."
android:textColor="@android:color/background_dark"
android:textSize="15sp"
app:layout_constraintBottom_toTopOf="@id/progress_h"
app:layout_constraintLeft_toLeftOf="@id/progress_h"
app:layout_constraintRight_toRightOf="@id/progress_h"
tools:ignore="HardcodedText" />
</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
...@@ -65,6 +65,7 @@ ...@@ -65,6 +65,7 @@
tools:ignore="HardcodedText" /> tools:ignore="HardcodedText" />
<TextView <TextView
android:id="@+id/tv_dup_cout"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="8dp" android:layout_marginTop="8dp"
...@@ -132,6 +133,7 @@ ...@@ -132,6 +133,7 @@
tools:ignore="HardcodedText" /> tools:ignore="HardcodedText" />
<TextView <TextView
android:id="@+id/tv_large_count"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="8dp" android:layout_marginTop="8dp"
...@@ -200,6 +202,7 @@ ...@@ -200,6 +202,7 @@
tools:ignore="HardcodedText" /> tools:ignore="HardcodedText" />
<TextView <TextView
android:id="@+id/tv_empty_count"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="8dp" android:layout_marginTop="8dp"
......
...@@ -6,4 +6,6 @@ ...@@ -6,4 +6,6 @@
<color name="color_FF4CE0AB">#FF4CE0AB</color> <color name="color_FF4CE0AB">#FF4CE0AB</color>
<color name="color_FF333333">#FF333333</color> <color name="color_FF333333">#FF333333</color>
<color name="color_FF999999">#FF999999</color> <color name="color_FF999999">#FF999999</color>
<color name="color_999999">#999999</color>
<color name="color_F4F4F4">#F4F4F4</color>
</resources> </resources>
\ No newline at end of file
...@@ -12,6 +12,7 @@ constraintlayout = "2.1.4" ...@@ -12,6 +12,7 @@ constraintlayout = "2.1.4"
navigationFragmentKtx = "2.7.7" navigationFragmentKtx = "2.7.7"
navigationUiKtx = "2.7.7" navigationUiKtx = "2.7.7"
coil = "2.6.0" coil = "2.6.0"
datastorePreferences = "1.0.0"
[libraries] [libraries]
androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" } androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" }
...@@ -27,6 +28,7 @@ androidx-navigation-ui-ktx = { group = "androidx.navigation", name = "navigation ...@@ -27,6 +28,7 @@ androidx-navigation-ui-ktx = { group = "androidx.navigation", name = "navigation
coil = { group = "io.coil-kt", name = "coil", version.ref = "coil" } coil = { group = "io.coil-kt", name = "coil", version.ref = "coil" }
coil-video = { group = "io.coil-kt", name = "coil-video", version.ref = "coil" } coil-video = { group = "io.coil-kt", name = "coil-video", version.ref = "coil" }
coil-gif = { group = "io.coil-kt", name = "coil-gif", version.ref = "coil" } coil-gif = { group = "io.coil-kt", name = "coil-gif", version.ref = "coil" }
androidx-datastore-preferences = { group = "androidx.datastore", name = "datastore-preferences", version.ref = "datastorePreferences" }
[plugins] [plugins]
androidApplication = { id = "com.android.application", version.ref = "agp" } androidApplication = { id = "com.android.application", version.ref = "agp" }
......
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