Commit fe26db10 authored by wanglei's avatar wanglei

feat:白包版本

parents 904f996d 719c4908
...@@ -3,7 +3,20 @@ ...@@ -3,7 +3,20 @@
<component name="deploymentTargetDropDown"> <component name="deploymentTargetDropDown">
<value> <value>
<entry key="app"> <entry key="app">
<State /> <State>
<runningDeviceTargetSelectedWithDropDown>
<Target>
<type value="RUNNING_DEVICE_TARGET" />
<deviceKey>
<Key>
<type value="SERIAL_NUMBER" />
<value value="adb-RF9N8045MAW-sXXAeN._adb-tls-connect._tcp" />
</Key>
</deviceKey>
</Target>
</runningDeviceTargetSelectedWithDropDown>
<timeTargetWasSelectedWithDropDown value="2024-03-18T05:10:08.056979Z" />
</State>
</entry> </entry>
</value> </value>
</component> </component>
......
<?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" project-jdk-name="17" project-jdk-type="JavaSDK"> <component name="ProjectRootManager" version="2" languageLevel="JDK_17" default="true" project-jdk-name="17" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/out" /> <output url="file://$PROJECT_DIR$/out" />
</component> </component>
</project> </project>
\ No newline at end of file
...@@ -7,6 +7,7 @@ android { ...@@ -7,6 +7,7 @@ android {
namespace = "com.example.hfilemanagermaster" namespace = "com.example.hfilemanagermaster"
compileSdk = 34 compileSdk = 34
defaultConfig { defaultConfig {
applicationId = "com.example.hfilemanagermaster" applicationId = "com.example.hfilemanagermaster"
minSdk = 24 minSdk = 24
...@@ -17,13 +18,30 @@ android { ...@@ -17,13 +18,30 @@ android {
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
} }
lint {
//https://blog.csdn.net/destiny1507/article/details/104329583
checkReleaseBuilds = false
abortOnError = false
}
signingConfigs {
create("keyStore") {
storeFile = file("../kokoAndroidConfigure.jks")
storePassword = "wenlu1796"
keyAlias = "Smilekoko"
keyPassword = "wanglei1796"
}
}
buildTypes { buildTypes {
val signConfig = signingConfigs.getByName("keyStore")
release { release {
isMinifyEnabled = false isMinifyEnabled = true
proguardFiles( proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"), getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro" "proguard-rules.pro"
) )
signingConfig = signConfig
} }
} }
buildFeatures { buildFeatures {
...@@ -36,6 +54,7 @@ android { ...@@ -36,6 +54,7 @@ android {
kotlinOptions { kotlinOptions {
jvmTarget = "1.8" jvmTarget = "1.8"
} }
} }
dependencies { dependencies {
......
...@@ -2,16 +2,13 @@ ...@@ -2,16 +2,13 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"> xmlns:tools="http://schemas.android.com/tools">
<uses-permission <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
android:name="android.permission.READ_EXTERNAL_STORAGE" <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
android:maxSdkVersion="32" />
<uses-permission
android:name="android.permission.WRITE_EXTERNAL_STORAGE"
android:maxSdkVersion="32"
tools:ignore="ScopedStorage" />
<uses-permission <uses-permission
android:name="android.permission.MANAGE_EXTERNAL_STORAGE" android:name="android.permission.MANAGE_EXTERNAL_STORAGE"
tools:ignore="ScopedStorage" /> <!-- https://developer.android.com/about/versions/14/changes/partial-photo-video-access?hl=zh-cn --> tools:ignore="ScopedStorage" />
<!-- https://developer.android.com/about/versions/14/changes/partial-photo-video-access?hl=zh-cn -->
<uses-permission android:name="android.permission.READ_MEDIA_VISUAL_USER_SELECTED" /> <uses-permission android:name="android.permission.READ_MEDIA_VISUAL_USER_SELECTED" />
<uses-permission <uses-permission
android:name="android.permission.READ_MEDIA_IMAGES" android:name="android.permission.READ_MEDIA_IMAGES"
...@@ -26,6 +23,7 @@ ...@@ -26,6 +23,7 @@
android:fullBackupContent="@xml/backup_rules" android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/ic_launcher" android:icon="@mipmap/ic_launcher"
android:label="@string/app_name" android:label="@string/app_name"
android:requestLegacyExternalStorage="true"
android:roundIcon="@mipmap/ic_launcher_round" android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true" android:supportsRtl="true"
android:theme="@style/Theme.HFileManagerMaster" android:theme="@style/Theme.HFileManagerMaster"
...@@ -88,6 +86,16 @@ ...@@ -88,6 +86,16 @@
<!-- <category android:name="android.intent.category.LAUNCHER" /> --> <!-- <category android:name="android.intent.category.LAUNCHER" /> -->
<!-- </intent-filter> --> <!-- </intent-filter> -->
</activity> </activity>
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.fileProvider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths" />
</provider>
</application> </application>
</manifest> </manifest>
\ No newline at end of file
...@@ -34,7 +34,7 @@ class HLaunchActivity : AppCompatActivity() { ...@@ -34,7 +34,7 @@ class HLaunchActivity : AppCompatActivity() {
while (i <= 100) { while (i <= 100) {
binding.progressH.progress = i binding.progressH.progress = i
i++ i++
delay(50) delay(10)
} }
val intent = Intent(this@HLaunchActivity, OverviewActivity::class.java) val intent = Intent(this@HLaunchActivity, OverviewActivity::class.java)
startActivity(intent) startActivity(intent)
......
package com.zxhy.hfilemanagermaster
import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import com.example.hfilemanagermaster.R
import com.example.hfilemanagermaster.databinding.FragmentManagerBinding
// TODO: Rename parameter arguments, choose names that match
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
private const val ARG_PARAM1 = "param1"
private const val ARG_PARAM2 = "param2"
/**
* A simple [Fragment] subclass.
* Use the [ManagerFragment.newInstance] factory method to
* create an instance of this fragment.
*/
class ManagerFragment : Fragment() {
private lateinit var binding: FragmentManagerBinding
private var param1: String? = null
private var param2: String? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
arguments?.let {
param1 = it.getString(ARG_PARAM1)
param2 = it.getString(ARG_PARAM2)
}
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
val view = inflater.inflate(R.layout.fragment_manager, container, false)
binding = FragmentManagerBinding.bind(view.rootView)
return view
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding.tvUse.text = "25%"
binding.tvFree.text = "75GB"
binding.cardView1.setOnClickListener { }
binding.cardView2.setOnClickListener { }
binding.cardView3.setOnClickListener { }
binding.ivFile.setOnClickListener { }
binding.ivWord.setOnClickListener { }
binding.ivExcel.setOnClickListener { }
binding.ivPdf.setOnClickListener { }
binding.ivPpt.setOnClickListener { }
}
companion object {
/**
* Use this factory method to create a new instance of
* this fragment using the provided parameters.
*
* @param param1 Parameter 1.
* @param param2 Parameter 2.
* @return A new instance of fragment ManageFragment.
*/
// TODO: Rename and change types and number of parameters
@JvmStatic
fun newInstance(param1: String, param2: String) =
ManagerFragment().apply {
arguments = Bundle().apply {
putString(ARG_PARAM1, param1)
putString(ARG_PARAM2, param2)
}
}
}
}
\ No newline at end of file
...@@ -15,6 +15,7 @@ import com.example.hfilemanagermaster.R ...@@ -15,6 +15,7 @@ import com.example.hfilemanagermaster.R
import com.example.hfilemanagermaster.databinding.ActivityOverviewBinding import com.example.hfilemanagermaster.databinding.ActivityOverviewBinding
import com.zxhy.hfilemanagermaster.permission.IntentLauncher import com.zxhy.hfilemanagermaster.permission.IntentLauncher
import com.zxhy.hfilemanagermaster.permission.PermissionLauncher import com.zxhy.hfilemanagermaster.permission.PermissionLauncher
import com.zxhy.hfilemanagermaster.permission.requestStoreFollow
class OverviewActivity : AppCompatActivity() { class OverviewActivity : AppCompatActivity() {
private lateinit var binding: ActivityOverviewBinding private lateinit var binding: ActivityOverviewBinding
...@@ -70,4 +71,5 @@ class OverviewActivity : AppCompatActivity() { ...@@ -70,4 +71,5 @@ class OverviewActivity : AppCompatActivity() {
binding.ivManager.isSelected = false binding.ivManager.isSelected = false
window.statusBarColor = ContextCompat.getColor(this, R.color.white) window.statusBarColor = ContextCompat.getColor(this, R.color.white)
} }
} }
\ No newline at end of file
...@@ -19,9 +19,11 @@ data class MediaDataC( ...@@ -19,9 +19,11 @@ data class MediaDataC(
val path: String = "", val path: String = "",
val md5: String = "", val md5: String = "",
var select: Boolean = false, var select: Boolean = false,
) var index: Int = 0
) {
}
fun File.file2MediaDataC(context: Context): MediaDataC { fun File.file2MediaDataC(context: Context, md5: String = ""): MediaDataC {
return try { return try {
val sizeS = Formatter.formatFileSize(context, length()) val sizeS = Formatter.formatFileSize(context, length())
val timeE = SimpleDateFormat("MMM dd, yyyy", Locale.ENGLISH).format(lastModified()) val timeE = SimpleDateFormat("MMM dd, yyyy", Locale.ENGLISH).format(lastModified())
...@@ -29,7 +31,8 @@ fun File.file2MediaDataC(context: Context): MediaDataC { ...@@ -29,7 +31,8 @@ fun File.file2MediaDataC(context: Context): MediaDataC {
name = name, name = name,
size = sizeS, size = sizeS,
time = timeE, time = timeE,
path = absolutePath path = absolutePath,
md5 = md5
) )
} catch (e: Exception) { } catch (e: Exception) {
MediaDataC() MediaDataC()
......
package com.zxhy.hfilemanagermaster.dialog package com.zxhy.hfilemanagermaster.dialog
import android.annotation.SuppressLint
import android.content.Context import android.content.Context
import android.text.format.Formatter
import android.view.LayoutInflater import android.view.LayoutInflater
import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AlertDialog
import com.example.hfilemanagermaster.R import com.example.hfilemanagermaster.R
import com.example.hfilemanagermaster.databinding.DialogFileDetailsBinding
import com.example.hfilemanagermaster.databinding.DialogFileNameBinding import com.example.hfilemanagermaster.databinding.DialogFileNameBinding
import com.zxhy.hfilemanagermaster.glide.loadIntoImageView
import java.io.File
import java.text.SimpleDateFormat
import java.util.Locale
fun Context.showFileNameDialog( fun Context.showFileNameDialog(
tittle: String = "", tittle: String = "",
...@@ -26,6 +33,7 @@ fun Context.showFileNameDialog( ...@@ -26,6 +33,7 @@ fun Context.showFileNameDialog(
binding.tvTittle.text = tittle binding.tvTittle.text = tittle
binding.tvSure.setOnClickListener { binding.tvSure.setOnClickListener {
dialog.dismiss()
sureAction.invoke(binding.etName.text.toString()) sureAction.invoke(binding.etName.text.toString())
} }
binding.ivCancel.setOnClickListener { binding.ivCancel.setOnClickListener {
...@@ -34,3 +42,72 @@ fun Context.showFileNameDialog( ...@@ -34,3 +42,72 @@ fun Context.showFileNameDialog(
dialog.setOnCancelListener { dismissAction.invoke() } dialog.setOnCancelListener { dismissAction.invoke() }
} }
@SuppressLint("SetTextI18n")
fun Context.showFileDetailsDialog(
tittle: String = "",
file: File,
cancelAction: () -> Unit,
dismissAction: () -> Unit
) {
val binding = DialogFileDetailsBinding.inflate(LayoutInflater.from(this))
val dialog = AlertDialog.Builder(this).setView(binding.root).create()
dialog.show()
dialog.setCanceledOnTouchOutside(false)
//修改dialog的尺寸
val lp = dialog.window?.attributes
lp?.width = this.resources.getDimensionPixelOffset(R.dimen.dp_255)
lp?.height = this.resources.getDimensionPixelOffset(R.dimen.dp_233)
dialog.window?.attributes = lp
dialog.window?.setBackgroundDrawableResource(android.R.color.transparent)
dialog.window?.setDimAmount(0f)
binding.apply {
tvTittle.text = tittle
if (file.name.contains(".jpg")
or
file.name.contains(".mp4")
or
file.name.contains(".png")
) {
loadIntoImageView(this@showFileDetailsDialog, file.absoluteFile, binding.ivFile)
} else if (file.name.contains(".txt")) {
ivFile.setImageResource(R.mipmap.io_002)
} else if (file.name.contains(".xlsx") or file.name.contains(".xls")) {
ivFile.setImageResource(R.mipmap.as_85230)
} else if (file.name.contains(".pdf")) {
ivFile.setImageResource(R.mipmap.io_0012)
} else if (file.name.contains(".ppt") or file.name.contains(".pptx")) {
ivFile.setImageResource(R.mipmap.io_002223)
} else if (file.name.contains(".apk")) {
ivFile.setImageResource(R.mipmap.fe_98856)
} else if (file.name.contains(".zip")) {
ivFile.setImageResource(R.mipmap.qwett_98959)
} else if (file.name.contains("log") && file.isFile) {
ivFile.setImageResource(R.mipmap.rqwr_875)
} else if (file.isDirectory) {
ivFile.setImageResource(R.mipmap.tt_695)
} else {
ivFile.setImageResource(R.drawable.icon_file_unknown)
}
tvName.text = file.name
val sizeS = Formatter.formatFileSize(this@showFileDetailsDialog, file.length())
tvSize.text = sizeS
val timeE = SimpleDateFormat("MMM dd, yyyy", Locale.ENGLISH).format(file.lastModified())
tvTime.text = "Time:$timeE"
tvPosition.text = "Position:${file.absoluteFile}"
tvCancel.setOnClickListener {
cancelAction.invoke()
dialog.dismiss()
}
ivCancel.setOnClickListener {
cancelAction.invoke()
dialog.dismiss()
}
}
dialog.setOnCancelListener { dismissAction.invoke() }
}
\ No newline at end of file
...@@ -30,4 +30,5 @@ fun Context.showOperationDialog( ...@@ -30,4 +30,5 @@ fun Context.showOperationDialog(
binding.tv.text = tips binding.tv.text = tips
dialog.setOnCancelListener { dismissAction.invoke() } dialog.setOnCancelListener { dismissAction.invoke() }
return dialog return dialog
} }
\ No newline at end of file
...@@ -12,6 +12,7 @@ import com.zxhy.hfilemanagermaster.data.DupImageData ...@@ -12,6 +12,7 @@ import com.zxhy.hfilemanagermaster.data.DupImageData
import com.zxhy.hfilemanagermaster.data.MediaDataC import com.zxhy.hfilemanagermaster.data.MediaDataC
import com.zxhy.hfilemanagermaster.glide.loadIntoImageView import com.zxhy.hfilemanagermaster.glide.loadIntoImageView
import com.zxhy.hfilemanagermaster.knife.inflate import com.zxhy.hfilemanagermaster.knife.inflate
import java.io.File
class DupImageAdapter( class DupImageAdapter(
private val selectAction: ((flag: Boolean) -> Unit)? = null private val selectAction: ((flag: Boolean) -> Unit)? = null
...@@ -34,7 +35,7 @@ class DupImageAdapter( ...@@ -34,7 +35,7 @@ class DupImageAdapter(
@SuppressLint("SetTextI18n") @SuppressLint("SetTextI18n")
override fun onBindViewHolder(holder: DupImageVideHolder, position: Int) { override fun onBindViewHolder(holder: DupImageVideHolder, position: Int) {
val context = holder.binding.root.context // val context = holder.binding.root.context
val data = dupImageList[position] val data = dupImageList[position]
holder.binding.apply { holder.binding.apply {
...@@ -73,7 +74,7 @@ class DupImageAdapter( ...@@ -73,7 +74,7 @@ class DupImageAdapter(
payloads: MutableList<Any> payloads: MutableList<Any>
) { ) {
val context = holder.binding.root.context // val context = holder.binding.root.context
val data = dupImageList[position] val data = dupImageList[position]
//判断是做局部刷新还是单条刷新 //判断是做局部刷新还是单条刷新
if (payloads.isEmpty()) {//局部刷新 if (payloads.isEmpty()) {//局部刷新
...@@ -179,7 +180,7 @@ private class DupImageItemAdapter( ...@@ -179,7 +180,7 @@ private class DupImageItemAdapter(
val context = holder.binding.root.context val context = holder.binding.root.context
val data = mediaList[position] val data = mediaList[position]
holder.binding.apply { holder.binding.apply {
loadIntoImageView(context, data.uri, ivImage) loadIntoImageView(context, File(data.path), ivImage)
ivSelector.isSelected = data.select ivSelector.isSelected = data.select
ivSelector.setOnClickListener { ivSelector.setOnClickListener {
data.select = !data.select data.select = !data.select
...@@ -201,7 +202,7 @@ private class DupImageItemAdapter( ...@@ -201,7 +202,7 @@ private class DupImageItemAdapter(
//判断是做局部刷新还是单条刷新 //判断是做局部刷新还是单条刷新
if (payloads.isEmpty()) {//局部刷新 if (payloads.isEmpty()) {//局部刷新
holder.binding.apply { holder.binding.apply {
loadIntoImageView(context, data.uri, ivImage) loadIntoImageView(context, File(data.path), ivImage)
ivSelector.isSelected = data.select ivSelector.isSelected = data.select
ivSelector.setOnClickListener { ivSelector.setOnClickListener {
data.select = !data.select data.select = !data.select
......
package com.zxhy.hfilemanagermaster.duplicate package com.zxhy.hfilemanagermaster.duplicate
import android.app.AlertDialog
import android.app.Dialog import android.app.Dialog
import android.os.Bundle import android.os.Bundle
import android.view.View
import androidx.activity.enableEdgeToEdge import androidx.activity.enableEdgeToEdge
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
...@@ -12,12 +12,18 @@ import androidx.lifecycle.lifecycleScope ...@@ -12,12 +12,18 @@ import androidx.lifecycle.lifecycleScope
import com.example.hfilemanagermaster.R import com.example.hfilemanagermaster.R
import com.example.hfilemanagermaster.databinding.ActivityDupPictureBinding import com.example.hfilemanagermaster.databinding.ActivityDupPictureBinding
import com.zxhy.hfilemanagermaster.data.DupImageData import com.zxhy.hfilemanagermaster.data.DupImageData
import com.zxhy.hfilemanagermaster.dialog.showLoadingDialog
import com.zxhy.hfilemanagermaster.dialog.showOperationDialog import com.zxhy.hfilemanagermaster.dialog.showOperationDialog
import com.zxhy.hfilemanagermaster.knife.deleteDirectory import com.zxhy.hfilemanagermaster.knife.deleteDirectory
import com.zxhy.hfilemanagermaster.knife.dupImage import com.zxhy.hfilemanagermaster.knife.dupImageMedia
import com.zxhy.hfilemanagermaster.knife.dupImageStore
import com.zxhy.hfilemanagermaster.knife.getDupImageList import com.zxhy.hfilemanagermaster.knife.getDupImageList
import com.zxhy.hfilemanagermaster.knife.toast import com.zxhy.hfilemanagermaster.knife.toast
import com.zxhy.hfilemanagermaster.permission.IntentLauncher
import com.zxhy.hfilemanagermaster.permission.PermissionLauncher
import com.zxhy.hfilemanagermaster.permission.alert import com.zxhy.hfilemanagermaster.permission.alert
import com.zxhy.hfilemanagermaster.permission.requestStoreFollow
import com.zxhy.hfilemanagermaster.permission.storePermissionCheck
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay import kotlinx.coroutines.delay
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
...@@ -26,9 +32,14 @@ import java.io.File ...@@ -26,9 +32,14 @@ import java.io.File
class DupPictureActivity : AppCompatActivity() { class DupPictureActivity : AppCompatActivity() {
private lateinit var binding: ActivityDupPictureBinding private lateinit var binding: ActivityDupPictureBinding
private lateinit var adapter: DupImageAdapter private lateinit var adapter: DupImageAdapter
private lateinit var dialog: Dialog
private lateinit var intentLauncher: IntentLauncher
private lateinit var permissionLauncher: PermissionLauncher
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
enableEdgeToEdge() enableEdgeToEdge()
intentLauncher = IntentLauncher(this)
permissionLauncher = PermissionLauncher(this)
binding = ActivityDupPictureBinding.inflate(layoutInflater) binding = ActivityDupPictureBinding.inflate(layoutInflater)
setContentView(binding.root) setContentView(binding.root)
ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main)) { v, insets -> ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main)) { v, insets ->
...@@ -67,7 +78,41 @@ class DupPictureActivity : AppCompatActivity() { ...@@ -67,7 +78,41 @@ class DupPictureActivity : AppCompatActivity() {
} }
} }
if (storePermissionCheck()) {
fileMode()
} else {
lockMode()
}
}
private fun lockMode() {
binding.clLock.visibility = View.VISIBLE
binding.rv.visibility = View.INVISIBLE
binding.ivAll.visibility = View.GONE
binding.tvAll.visibility = View.GONE
binding.tvDelete.visibility = View.GONE
binding.tvSet.setOnClickListener {
this.requestStoreFollow(
permissionLauncher,
intentLauncher,
disAgreeAction = {
lockMode()
},
agreeAction = {
fileMode()
})
}
}
private fun fileMode() {
binding.clLock.visibility = View.GONE
binding.rv.visibility = View.VISIBLE
binding.ivAll.visibility = View.VISIBLE
binding.tvAll.visibility = View.VISIBLE
binding.tvDelete.visibility = View.VISIBLE
dialog = showLoadingDialog()
loadData() loadData()
} }
...@@ -95,16 +140,34 @@ class DupPictureActivity : AppCompatActivity() { ...@@ -95,16 +140,34 @@ class DupPictureActivity : AppCompatActivity() {
}.start() }.start()
private fun loadData() { private fun loadData() {
dialog.show()
lifecycleScope.launch(Dispatchers.IO) { lifecycleScope.launch(Dispatchers.IO) {
val list = dupImage() val list = dupImageStore()
val dupDataList = arrayListOf<DupImageData>() val dupDataList = arrayListOf<DupImageData>()
val dupList = getDupImageList(list) val dupList = getDupImageList(list)
dupList.forEach { dupList.forEach {
dupDataList.add(DupImageData(dupList = it)) dupDataList.add(DupImageData(dupList = it))
} }
lifecycleScope.launch(Dispatchers.Main) { lifecycleScope.launch(Dispatchers.Main) {
dialog.dismiss()
adapter.setData(dupDataList) adapter.setData(dupDataList)
isEmptyUi()
} }
} }
} }
private fun isEmptyUi() {
val count = adapter.itemCount
if (count == 0) {
binding.rv.visibility = View.GONE
binding.tvDelete.visibility = View.GONE
binding.ivEmpty.visibility = View.VISIBLE
} else {
binding.rv.visibility = View.VISIBLE
binding.tvDelete.visibility = View.VISIBLE
binding.ivEmpty.visibility = View.GONE
}
}
} }
\ No newline at end of file
package com.zxhy.hfilemanagermaster.emptyfile package com.zxhy.hfilemanagermaster.emptyfile
import android.Manifest
import android.app.Dialog
import android.net.Uri import android.net.Uri
import android.os.Build import android.os.Build
import android.os.Bundle import android.os.Bundle
...@@ -13,6 +15,8 @@ import androidx.core.view.WindowInsetsCompat ...@@ -13,6 +15,8 @@ import androidx.core.view.WindowInsetsCompat
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
import com.example.hfilemanagermaster.R import com.example.hfilemanagermaster.R
import com.example.hfilemanagermaster.databinding.ActivityEmptyFileBinding import com.example.hfilemanagermaster.databinding.ActivityEmptyFileBinding
import com.zxhy.hfilemanagermaster.data.MediaDataC
import com.zxhy.hfilemanagermaster.dialog.showLoadingDialog
import com.zxhy.hfilemanagermaster.dialog.showOperationDialog import com.zxhy.hfilemanagermaster.dialog.showOperationDialog
import com.zxhy.hfilemanagermaster.knife.deleteDirectory import com.zxhy.hfilemanagermaster.knife.deleteDirectory
import com.zxhy.hfilemanagermaster.knife.emptyFile import com.zxhy.hfilemanagermaster.knife.emptyFile
...@@ -21,7 +25,7 @@ import com.zxhy.hfilemanagermaster.permission.IntentLauncher ...@@ -21,7 +25,7 @@ import com.zxhy.hfilemanagermaster.permission.IntentLauncher
import com.zxhy.hfilemanagermaster.permission.PermissionLauncher import com.zxhy.hfilemanagermaster.permission.PermissionLauncher
import com.zxhy.hfilemanagermaster.permission.alert import com.zxhy.hfilemanagermaster.permission.alert
import com.zxhy.hfilemanagermaster.permission.requestStoreFollow import com.zxhy.hfilemanagermaster.permission.requestStoreFollow
import com.zxhy.hfilemanagermaster.permission.settingManageExternalStorage import com.zxhy.hfilemanagermaster.permission.storePermissionCheck
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay import kotlinx.coroutines.delay
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
...@@ -33,6 +37,7 @@ class EmptyFileActivity : AppCompatActivity() { ...@@ -33,6 +37,7 @@ class EmptyFileActivity : AppCompatActivity() {
private lateinit var intentLauncher: IntentLauncher private lateinit var intentLauncher: IntentLauncher
private lateinit var permissionLauncher: PermissionLauncher private lateinit var permissionLauncher: PermissionLauncher
private lateinit var emptyFileAdapter: EmptyFileAdapter private lateinit var emptyFileAdapter: EmptyFileAdapter
private lateinit var loadDialog: Dialog
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
enableEdgeToEdge() enableEdgeToEdge()
...@@ -50,65 +55,47 @@ class EmptyFileActivity : AppCompatActivity() { ...@@ -50,65 +55,47 @@ class EmptyFileActivity : AppCompatActivity() {
finish() finish()
} }
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { if (storePermissionCheck()) {
if (Environment.isExternalStorageManager()) {
fileMode()
} else {
lockMode()
}
} else {
fileMode() fileMode()
} else {
lockMode()
} }
} }
private fun loadEmptyFile() = Thread { private fun loadEmptyFile() {
val list = emptyFile(this) loadDialog.show()
runOnUiThread { emptyFile(
emptyFileAdapter.setData(list) this,
} onDoAction = { list ->
}.start() runOnUiThread {
loadDialog.dismiss()
emptyFileAdapter.addData(list)
}
})
}
private fun lockMode() { private fun lockMode() {
binding.clLock.visibility = View.VISIBLE binding.clLock.visibility = View.VISIBLE
binding.rv.visibility = View.INVISIBLE binding.clShow.visibility = View.GONE
binding.ivAll.visibility = View.GONE
binding.tvAll.visibility = View.GONE
binding.tvSet.setOnClickListener { binding.tvSet.setOnClickListener {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { this.requestStoreFollow(
if (!Environment.isExternalStorageManager()) { permissionLauncher,
val uri = Uri.parse("package:$packageName") intentLauncher,
val intent = settingManageExternalStorage(uri) disAgreeAction = {
intentLauncher.launch(intent) { lockMode()
val flag = Environment.isExternalStorageManager() },
if (flag) { agreeAction = {
fileMode()
// toast("已设置额外储存管理")
} else {
// toast("未设置额外储存管理")
lockMode()
}
}
} else {
// toast("已设置额外储存管理")
fileMode() fileMode()
} })
} else {
requestStoreFollow(permissionLauncher, intentLauncher) { fileMode() }
}
} }
} }
private fun fileMode() { private fun fileMode() {
binding.clLock.visibility = View.GONE binding.clLock.visibility = View.GONE
binding.rv.visibility = View.VISIBLE binding.clShow.visibility = View.VISIBLE
binding.ivAll.visibility = View.VISIBLE
binding.tvAll.visibility = View.VISIBLE
emptyFileAdapter = EmptyFileAdapter { emptyFileAdapter = EmptyFileAdapter {
binding.ivAll.isSelected = it binding.ivAll.isSelected = it
...@@ -125,8 +112,7 @@ class EmptyFileActivity : AppCompatActivity() { ...@@ -125,8 +112,7 @@ class EmptyFileActivity : AppCompatActivity() {
"Delete Confirm" "Delete Confirm"
) { ) {
positiveButton("confirm") { dialog -> positiveButton("confirm") { dialog ->
val fileList = list.map { File(it.path) } deleteFiles(list)
deleteFiles(fileList)
dialog.dismiss() dialog.dismiss()
} }
negativeButton("cancel") { dialog -> negativeButton("cancel") { dialog ->
...@@ -136,24 +122,25 @@ class EmptyFileActivity : AppCompatActivity() { ...@@ -136,24 +122,25 @@ class EmptyFileActivity : AppCompatActivity() {
isCancel(false) isCancel(false)
} }
} }
loadDialog = showLoadingDialog()
loadEmptyFile() loadEmptyFile()
} }
private fun deleteFiles(files: List<File>) = Thread { private fun deleteFiles(files: List<MediaDataC>) = Thread {
try { try {
files.forEach { files.forEach {
if (it.exists()) { val file = File(it.path)
if (it.isFile) it.delete() else deleteDirectory(it) if (file.exists()) {
if (file.isFile) file.delete() else deleteDirectory(file)
} }
} }
runOnUiThread { lifecycleScope.launch(Dispatchers.Main) {
lifecycleScope.launch(Dispatchers.Main) { val dialog = showOperationDialog(R.mipmap.dads_889562, "delete success!") {}
val dialog = showOperationDialog(R.mipmap.dads_889562, "delete success!") {} delay(200)
delay(200) dialog.dismiss()
dialog.dismiss() emptyFileAdapter.removeData(files)
}
} }
loadEmptyFile()
} catch (e: Exception) { } catch (e: Exception) {
e.printStackTrace() e.printStackTrace()
runOnUiThread { runOnUiThread {
......
package com.zxhy.hfilemanagermaster.emptyfile package com.zxhy.hfilemanagermaster.emptyfile
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.util.Log
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
...@@ -9,6 +10,7 @@ import com.example.hfilemanagermaster.databinding.ItemMediaSelectBinding ...@@ -9,6 +10,7 @@ import com.example.hfilemanagermaster.databinding.ItemMediaSelectBinding
import com.zxhy.hfilemanagermaster.data.MediaDataC import com.zxhy.hfilemanagermaster.data.MediaDataC
import com.zxhy.hfilemanagermaster.glide.loadIntoImageView import com.zxhy.hfilemanagermaster.glide.loadIntoImageView
import com.zxhy.hfilemanagermaster.knife.inflate import com.zxhy.hfilemanagermaster.knife.inflate
import java.io.File
class EmptyFileAdapter( class EmptyFileAdapter(
private val selectAction: ((flag: Boolean) -> Unit)? = null private val selectAction: ((flag: Boolean) -> Unit)? = null
...@@ -34,7 +36,32 @@ class EmptyFileAdapter( ...@@ -34,7 +36,32 @@ class EmptyFileAdapter(
val data = mediaList[position] val data = mediaList[position]
holder.binding.apply { holder.binding.apply {
loadIntoImageView(context, data.uri, iv) if (data.path.contains(".jpg")
or
data.path.contains(".mp4")
or
data.path.contains(".png")
) {
loadIntoImageView(context, File(data.path), iv)
} else if (data.path.contains(".txt")) {
iv.setImageResource(R.mipmap.io_002)
} else if (data.path.contains(".xlsx") or data.path.contains(".xls")) {
iv.setImageResource(R.mipmap.as_85230)
} else if (data.path.contains(".pdf")) {
iv.setImageResource(R.mipmap.io_0012)
} else if (data.path.contains(".ppt") or data.path.contains(".pptx")) {
iv.setImageResource(R.mipmap.io_002223)
} else if (data.path.contains(".apk")) {
iv.setImageResource(R.mipmap.fe_98856)
} else if (data.path.contains(".zip")) {
iv.setImageResource(R.mipmap.qwett_98959)
} else if (data.path.contains("log") && File(data.path).isFile) {
iv.setImageResource(R.mipmap.rqwr_875)
} else if (File(data.path).isDirectory) {
iv.setImageResource(R.mipmap.tt_695)
} else {
iv.setImageResource(R.drawable.icon_file_unknown)
}
tvName.text = data.name tvName.text = data.name
tvSize.text = data.size tvSize.text = data.size
...@@ -60,7 +87,34 @@ class EmptyFileAdapter( ...@@ -60,7 +87,34 @@ class EmptyFileAdapter(
//判断是做局部刷新还是单条刷新 //判断是做局部刷新还是单条刷新
if (payloads.isEmpty()) {//局部刷新 if (payloads.isEmpty()) {//局部刷新
holder.binding.apply { holder.binding.apply {
loadIntoImageView(context, data.uri, iv) holder.binding.apply {
if (data.path.contains(".jpg")
or
data.path.contains(".mp4")
or
data.path.contains(".png")
) {
loadIntoImageView(context, File(data.path), iv)
} else if (data.path.contains(".txt")) {
iv.setImageResource(R.mipmap.io_002)
} else if (data.path.contains(".xlsx") or data.path.contains(".xls")) {
iv.setImageResource(R.mipmap.as_85230)
} else if (data.path.contains(".pdf")) {
iv.setImageResource(R.mipmap.io_0012)
} else if (data.path.contains(".ppt") or data.path.contains(".pptx")) {
iv.setImageResource(R.mipmap.io_002223)
} else if (data.path.contains(".apk")) {
iv.setImageResource(R.mipmap.fe_98856)
} else if (data.path.contains(".zip")) {
iv.setImageResource(R.mipmap.qwett_98959)
} else if (data.path.contains("log") && File(data.path).isFile) {
iv.setImageResource(R.mipmap.rqwr_875)
} else if (File(data.path).isDirectory) {
iv.setImageResource(R.mipmap.tt_695)
} else {
iv.setImageResource(R.drawable.icon_file_unknown)
}
}
tvName.text = data.name tvName.text = data.name
tvSize.text = data.size tvSize.text = data.size
...@@ -107,4 +161,22 @@ class EmptyFileAdapter( ...@@ -107,4 +161,22 @@ class EmptyFileAdapter(
fun getSelectFile(): List<MediaDataC> { fun getSelectFile(): List<MediaDataC> {
return mediaList.filter { it.select } return mediaList.filter { it.select }
} }
@SuppressLint("NotifyDataSetChanged")
fun addData(data: List<MediaDataC>) {
val index = mediaList.size
mediaList.addAll(data)
notifyItemRangeChanged(index, data.size)
// Log.e("FileSelectorAdapter", mediaList.size.toString())
}
@SuppressLint("NotifyDataSetChanged")
fun removeData(file: List<MediaDataC>) {
mediaList.removeAll(file.toSet())
// file.forEachIndexed { _, _ ->
// Log.e("removeData", "index=$index $mediaDataC")
// }
notifyDataSetChanged()
}
} }
\ No newline at end of file
...@@ -17,6 +17,7 @@ import com.zxhy.hfilemanagermaster.dialog.showOperationDialog ...@@ -17,6 +17,7 @@ import com.zxhy.hfilemanagermaster.dialog.showOperationDialog
import com.zxhy.hfilemanagermaster.knife.apkFile import com.zxhy.hfilemanagermaster.knife.apkFile
import com.zxhy.hfilemanagermaster.knife.audioFile import com.zxhy.hfilemanagermaster.knife.audioFile
import com.zxhy.hfilemanagermaster.knife.deleteDirectory import com.zxhy.hfilemanagermaster.knife.deleteDirectory
import com.zxhy.hfilemanagermaster.knife.documentFile
import com.zxhy.hfilemanagermaster.knife.excelFile import com.zxhy.hfilemanagermaster.knife.excelFile
import com.zxhy.hfilemanagermaster.knife.logFile import com.zxhy.hfilemanagermaster.knife.logFile
import com.zxhy.hfilemanagermaster.knife.pdfFile import com.zxhy.hfilemanagermaster.knife.pdfFile
...@@ -24,7 +25,11 @@ import com.zxhy.hfilemanagermaster.knife.pptFile ...@@ -24,7 +25,11 @@ import com.zxhy.hfilemanagermaster.knife.pptFile
import com.zxhy.hfilemanagermaster.knife.toast import com.zxhy.hfilemanagermaster.knife.toast
import com.zxhy.hfilemanagermaster.knife.wordFile import com.zxhy.hfilemanagermaster.knife.wordFile
import com.zxhy.hfilemanagermaster.knife.zipFile import com.zxhy.hfilemanagermaster.knife.zipFile
import com.zxhy.hfilemanagermaster.permission.IntentLauncher
import com.zxhy.hfilemanagermaster.permission.PermissionLauncher
import com.zxhy.hfilemanagermaster.permission.alert import com.zxhy.hfilemanagermaster.permission.alert
import com.zxhy.hfilemanagermaster.permission.requestStoreFollow
import com.zxhy.hfilemanagermaster.permission.storePermissionCheck
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay import kotlinx.coroutines.delay
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
...@@ -35,9 +40,14 @@ class FileBrowseActivity : AppCompatActivity() { ...@@ -35,9 +40,14 @@ class FileBrowseActivity : AppCompatActivity() {
private var tittle = "" private var tittle = ""
private lateinit var fileSelectAdapter: FileSelectorAdapter private lateinit var fileSelectAdapter: FileSelectorAdapter
private lateinit var loadDialog: Dialog private lateinit var loadDialog: Dialog
private lateinit var intentLauncher: IntentLauncher
private lateinit var permissionLauncher: PermissionLauncher
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
enableEdgeToEdge() enableEdgeToEdge()
intentLauncher = IntentLauncher(this)
permissionLauncher = PermissionLauncher(this)
binding = ActivityFileBrowseBinding.inflate(layoutInflater) binding = ActivityFileBrowseBinding.inflate(layoutInflater)
setContentView(binding.root) setContentView(binding.root)
ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main)) { v, insets -> ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main)) { v, insets ->
...@@ -78,9 +88,40 @@ class FileBrowseActivity : AppCompatActivity() { ...@@ -78,9 +88,40 @@ class FileBrowseActivity : AppCompatActivity() {
it.isSelected = fileSelectAdapter.setToggleSelect() it.isSelected = fileSelectAdapter.setToggleSelect()
} }
if (storePermissionCheck()) {
fileMode()
} else {
lockMode()
}
}
private fun lockMode() {
binding.clLock.visibility = View.VISIBLE
binding.clShow.visibility = View.GONE
binding.tvSet.setOnClickListener {
this.requestStoreFollow(
permissionLauncher,
intentLauncher,
disAgreeAction = {
lockMode()
},
agreeAction = {
fileMode()
})
}
}
private fun fileMode() {
binding.clLock.visibility = View.GONE
binding.clShow.visibility = View.VISIBLE
loadDialog = showLoadingDialog() loadDialog = showLoadingDialog()
loadData() loadData()
} }
private fun loadData() { private fun loadData() {
...@@ -191,13 +232,25 @@ class FileBrowseActivity : AppCompatActivity() { ...@@ -191,13 +232,25 @@ class FileBrowseActivity : AppCompatActivity() {
loadDialog.dismiss() loadDialog.dismiss()
runOnUiThread { isEmptyUi() } runOnUiThread { isEmptyUi() }
}) })
"Document" -> documentFile(this,
onDoAction = { list ->
runOnUiThread {
loadDialog.dismiss()
fileSelectAdapter.addData(list)
}
},
finishAction = {
loadDialog.dismiss()
runOnUiThread { isEmptyUi() }
})
} }
} }
private fun deleteFiles(files: List<MediaDataC>) = Thread { private fun deleteFiles(files: List<MediaDataC>) = Thread {
try { try {
files.forEach { files.forEach {
val file =File(it.path) val file = File(it.path)
if (file.exists()) { if (file.exists()) {
if (file.isFile) file.delete() else deleteDirectory(file) if (file.isFile) file.delete() else deleteDirectory(file)
} }
......
...@@ -55,12 +55,15 @@ class FileSelectorAdapter( ...@@ -55,12 +55,15 @@ class FileSelectorAdapter(
iv.setImageResource(R.mipmap.fe_98856) iv.setImageResource(R.mipmap.fe_98856)
} else if (data.path.contains(".zip")) { } else if (data.path.contains(".zip")) {
iv.setImageResource(R.mipmap.qwett_98959) iv.setImageResource(R.mipmap.qwett_98959)
} else if (data.path.contains("log")) { } else if (data.path.contains("log")&& File(data.path).isFile) {
iv.setImageResource(R.mipmap.rqwr_875) iv.setImageResource(R.mipmap.rqwr_875)
} else { } else if (File(data.path).isDirectory) {
iv.setImageResource(R.mipmap.tt_695) iv.setImageResource(R.mipmap.tt_695)
} else {
iv.setImageResource(R.drawable.icon_file_unknown)
} }
tvName.text = data.name tvName.text = data.name
tvSize.text = data.size tvSize.text = data.size
ivSelector.isSelected = data.select ivSelector.isSelected = data.select
...@@ -104,12 +107,15 @@ class FileSelectorAdapter( ...@@ -104,12 +107,15 @@ class FileSelectorAdapter(
iv.setImageResource(R.mipmap.fe_98856) iv.setImageResource(R.mipmap.fe_98856)
} else if (data.path.contains(".zip")) { } else if (data.path.contains(".zip")) {
iv.setImageResource(R.mipmap.qwett_98959) iv.setImageResource(R.mipmap.qwett_98959)
} else if (data.path.contains("log")) { } else if (data.path.contains("log")&& File(data.path).isFile) {
iv.setImageResource(R.mipmap.rqwr_875) iv.setImageResource(R.mipmap.rqwr_875)
} else { } else if (File(data.path).isDirectory) {
iv.setImageResource(R.mipmap.tt_695) iv.setImageResource(R.mipmap.tt_695)
} else {
iv.setImageResource(R.drawable.icon_file_unknown)
} }
tvName.text = data.name tvName.text = data.name
tvSize.text = data.size tvSize.text = data.size
ivSelector.isSelected = data.select ivSelector.isSelected = data.select
...@@ -142,9 +148,9 @@ class FileSelectorAdapter( ...@@ -142,9 +148,9 @@ class FileSelectorAdapter(
@SuppressLint("NotifyDataSetChanged") @SuppressLint("NotifyDataSetChanged")
fun removeData(file: List<MediaDataC>) { fun removeData(file: List<MediaDataC>) {
mediaList.removeAll(file.toSet()) mediaList.removeAll(file.toSet())
file.forEachIndexed { index, mediaDataC -> // file.forEachIndexed { index, mediaDataC ->
Log.e("removeData", "index=$index $mediaDataC") // Log.e("removeData", "index=$index $mediaDataC")
} // }
notifyDataSetChanged() notifyDataSetChanged()
} }
...@@ -153,7 +159,7 @@ class FileSelectorAdapter( ...@@ -153,7 +159,7 @@ class FileSelectorAdapter(
val index = mediaList.size val index = mediaList.size
mediaList.addAll(data) mediaList.addAll(data)
notifyItemRangeChanged(index, data.size) notifyItemRangeChanged(index, data.size)
Log.e("FileSelectorAdapter", mediaList.size.toString()) // Log.e("FileSelectorAdapter", mediaList.size.toString())
} }
......
...@@ -100,7 +100,7 @@ class FilesFragment : Fragment() { ...@@ -100,7 +100,7 @@ class FilesFragment : Fragment() {
companion object { companion object {
@JvmStatic @JvmStatic
fun newInstance(param1: String, param2: String) = fun newInstance() =
FilesFragment().apply { FilesFragment().apply {
arguments = Bundle().apply { arguments = Bundle().apply {
} }
......
...@@ -10,12 +10,14 @@ import java.net.URI ...@@ -10,12 +10,14 @@ import java.net.URI
fun loadIntoImageView(context: Context, uri: String, imageView: ImageView) { fun loadIntoImageView(context: Context, uri: String, imageView: ImageView) {
Glide.with(context) Glide.with(context)
.load(uri) .load(uri)
.centerCrop()
.into(imageView) .into(imageView)
} }
fun loadIntoImageView(context: Context, file: File, imageView: ImageView) { fun loadIntoImageView(context: Context, file: File, imageView: ImageView) {
Glide.with(context) Glide.with(context)
.load(file) .load(file)
.centerCrop()
.into(imageView) .into(imageView)
} }
......
...@@ -19,7 +19,11 @@ import com.zxhy.hfilemanagermaster.dialog.showOperationDialog ...@@ -19,7 +19,11 @@ import com.zxhy.hfilemanagermaster.dialog.showOperationDialog
import com.zxhy.hfilemanagermaster.knife.deleteDirectory import com.zxhy.hfilemanagermaster.knife.deleteDirectory
import com.zxhy.hfilemanagermaster.knife.imageFile import com.zxhy.hfilemanagermaster.knife.imageFile
import com.zxhy.hfilemanagermaster.knife.toast import com.zxhy.hfilemanagermaster.knife.toast
import com.zxhy.hfilemanagermaster.permission.IntentLauncher
import com.zxhy.hfilemanagermaster.permission.PermissionLauncher
import com.zxhy.hfilemanagermaster.permission.alert import com.zxhy.hfilemanagermaster.permission.alert
import com.zxhy.hfilemanagermaster.permission.requestStoreFollow
import com.zxhy.hfilemanagermaster.permission.storePermissionCheck
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay import kotlinx.coroutines.delay
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
...@@ -30,10 +34,14 @@ class ImageActivity : AppCompatActivity() { ...@@ -30,10 +34,14 @@ class ImageActivity : AppCompatActivity() {
private lateinit var binding: ActivityImageBinding private lateinit var binding: ActivityImageBinding
private lateinit var imageAdapter: ImageSelectAdapter2 private lateinit var imageAdapter: ImageSelectAdapter2
private lateinit var loadDialog: Dialog private lateinit var loadDialog: Dialog
private lateinit var intentLauncher: IntentLauncher
private lateinit var permissionLauncher: PermissionLauncher
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
enableEdgeToEdge() enableEdgeToEdge()
intentLauncher = IntentLauncher(this)
permissionLauncher = PermissionLauncher(this)
binding = ActivityImageBinding.inflate(layoutInflater) binding = ActivityImageBinding.inflate(layoutInflater)
setContentView(binding.root) setContentView(binding.root)
imageAdapter = ImageSelectAdapter2() imageAdapter = ImageSelectAdapter2()
...@@ -75,6 +83,35 @@ class ImageActivity : AppCompatActivity() { ...@@ -75,6 +83,35 @@ class ImageActivity : AppCompatActivity() {
} }
} }
if (storePermissionCheck()) {
fileMode()
} else {
lockMode()
}
}
private fun lockMode() {
binding.clLock.visibility = View.VISIBLE
binding.clShow.visibility = View.GONE
binding.tvSet.setOnClickListener {
this.requestStoreFollow(
permissionLauncher,
intentLauncher,
disAgreeAction = {
lockMode()
},
agreeAction = {
fileMode()
})
}
}
private fun fileMode() {
binding.clLock.visibility = View.GONE
binding.clShow.visibility = View.VISIBLE
loadDialog = showLoadingDialog() loadDialog = showLoadingDialog()
loadImageData() loadImageData()
} }
...@@ -96,7 +133,7 @@ class ImageActivity : AppCompatActivity() { ...@@ -96,7 +133,7 @@ class ImageActivity : AppCompatActivity() {
private fun deleteFiles(files: List<MediaDataC>) = Thread { private fun deleteFiles(files: List<MediaDataC>) = Thread {
try { try {
files.forEach { files.forEach {
val file =File(it.path) val file = File(it.path)
if (file.exists()) { if (file.exists()) {
if (file.isFile) file.delete() else deleteDirectory(file) if (file.isFile) file.delete() else deleteDirectory(file)
} }
......
...@@ -101,7 +101,7 @@ class ImageSelectAdapter2( ...@@ -101,7 +101,7 @@ class ImageSelectAdapter2(
val index = mediaList.size val index = mediaList.size
mediaList.addAll(data) mediaList.addAll(data)
notifyItemRangeChanged(index, data.size) notifyItemRangeChanged(index, data.size)
Log.e("FileSelectorAdapter", mediaList.size.toString()) // Log.e("FileSelectorAdapter", mediaList.size.toString())
} }
fun getSelectSize(): Int { fun getSelectSize(): Int {
...@@ -115,9 +115,9 @@ class ImageSelectAdapter2( ...@@ -115,9 +115,9 @@ class ImageSelectAdapter2(
@SuppressLint("NotifyDataSetChanged") @SuppressLint("NotifyDataSetChanged")
fun removeData(file: List<MediaDataC>) { fun removeData(file: List<MediaDataC>) {
mediaList.removeAll(file.toSet()) mediaList.removeAll(file.toSet())
file.forEachIndexed { index, mediaDataC -> // file.forEachIndexed { index, mediaDataC ->
Log.e("removeData", "index=$index $mediaDataC") // Log.e("removeData", "index=$index $mediaDataC")
} // }
notifyDataSetChanged() notifyDataSetChanged()
} }
} }
\ No newline at end of file
...@@ -2,6 +2,8 @@ package com.zxhy.hfilemanagermaster.internalstorage ...@@ -2,6 +2,8 @@ package com.zxhy.hfilemanagermaster.internalstorage
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.content.Context import android.content.Context
import android.os.Environment
import android.util.Log
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
...@@ -14,11 +16,13 @@ import com.zxhy.hfilemanagermaster.knife.inflate ...@@ -14,11 +16,13 @@ import com.zxhy.hfilemanagermaster.knife.inflate
import java.io.File import java.io.File
class FileAdapter( class FileAdapter(
private val selectAction: ((flag: Boolean) -> Unit)? = null private val selectAction: ((flag: Boolean) -> Unit)? = null,
private val nextPageAction: ((file: File) -> Unit)? = null,
private val beforePageAction: ((file: File) -> Unit)? = null
) : RecyclerView.Adapter<FileAdapter.FileSelectViewHolder>() { ) : RecyclerView.Adapter<FileAdapter.FileSelectViewHolder>() {
private val mediaList = arrayListOf<MediaDataC>() private val mediaList = arrayListOf<MediaDataC>()
private var isSelect = false private var isSelect = false
// private var currentDir: File? = null private var currentDir: File = Environment.getExternalStorageDirectory()
class FileSelectViewHolder(view: View) : RecyclerView.ViewHolder(view) { class FileSelectViewHolder(view: View) : RecyclerView.ViewHolder(view) {
val binding = ItemFileSelectBinding.bind(view) val binding = ItemFileSelectBinding.bind(view)
...@@ -56,8 +60,16 @@ class FileAdapter( ...@@ -56,8 +60,16 @@ class FileAdapter(
iv.setImageResource(R.mipmap.io_0012) iv.setImageResource(R.mipmap.io_0012)
} else if (data.path.contains(".ppt") or data.path.contains(".pptx")) { } else if (data.path.contains(".ppt") or data.path.contains(".pptx")) {
iv.setImageResource(R.mipmap.io_002223) iv.setImageResource(R.mipmap.io_002223)
} else { } else if (data.path.contains(".apk")) {
iv.setImageResource(R.mipmap.fe_98856)
} else if (data.path.contains(".zip")) {
iv.setImageResource(R.mipmap.qwett_98959)
} else if (data.path.contains("log") && File(data.path).isFile) {
iv.setImageResource(R.mipmap.rqwr_875)
} else if (File(data.path).isDirectory) {
iv.setImageResource(R.mipmap.tt_695) iv.setImageResource(R.mipmap.tt_695)
} else {
iv.setImageResource(R.drawable.icon_file_unknown)
} }
tvName.text = data.name tvName.text = data.name
...@@ -106,10 +118,17 @@ class FileAdapter( ...@@ -106,10 +118,17 @@ class FileAdapter(
iv.setImageResource(R.mipmap.io_0012) iv.setImageResource(R.mipmap.io_0012)
} else if (data.path.contains(".ppt") or data.path.contains(".pptx")) { } else if (data.path.contains(".ppt") or data.path.contains(".pptx")) {
iv.setImageResource(R.mipmap.io_002223) iv.setImageResource(R.mipmap.io_002223)
} else { } else if (data.path.contains(".apk")) {
iv.setImageResource(R.mipmap.fe_98856)
} else if (data.path.contains(".zip")) {
iv.setImageResource(R.mipmap.qwett_98959)
} else if (data.path.contains("log") && File(data.path).isFile) {
iv.setImageResource(R.mipmap.rqwr_875)
} else if (File(data.path).isDirectory) {
iv.setImageResource(R.mipmap.tt_695) iv.setImageResource(R.mipmap.tt_695)
} else {
iv.setImageResource(R.drawable.icon_file_unknown)
} }
tvName.text = data.name tvName.text = data.name
tvSize.text = data.size tvSize.text = data.size
ivSelector.isSelected = data.select ivSelector.isSelected = data.select
...@@ -162,18 +181,21 @@ class FileAdapter( ...@@ -162,18 +181,21 @@ class FileAdapter(
val subList = file.listFiles() val subList = file.listFiles()
val subData = subList?.map { it.file2MediaDataC(context) } ?: listOf() val subData = subList?.map { it.file2MediaDataC(context) } ?: listOf()
setData(subData) setData(subData)
nextPageAction?.invoke(file)
currentDir = file
} }
} }
fun beforePage(context: Context): Boolean { fun beforePage(context: Context): Boolean {
val file = File(mediaList.first().path).parentFile?.parentFile // Log.e("beforePage", "$currentDir")
if (file != null && file.exists()) { val parentDir = currentDir.parentFile ?: File("")
if (file.isDirectory) { if (parentDir.exists() && parentDir.isDirectory) {
val subList = file.listFiles() val subList = parentDir.listFiles()
if (subList.isNullOrEmpty()) return false if (subList.isNullOrEmpty()) return false
val subData = subList.map { it.file2MediaDataC(context) } val subData = subList.map { it.file2MediaDataC(context) }
setData(subData) setData(subData)
} beforePageAction?.invoke(parentDir)
currentDir = parentDir
return true return true
} else { } else {
return false return false
...@@ -196,15 +218,40 @@ class FileAdapter( ...@@ -196,15 +218,40 @@ class FileAdapter(
return mediaList.filter { it.select } return mediaList.filter { it.select }
} }
fun getSelectFileIndex(): List<MediaDataC> {
return mediaList.filterIndexed { index, mediaDataC ->
mediaDataC.index = index
mediaDataC.select
}
}
fun getCurrentDir(): File? { fun getCurrentDir(): File {
val dir = File(mediaList[0].path).parentFile return currentDir
return dir
} }
fun notifyCurrentDir(context: Context) { fun notifyCurrentDir(context: Context) {
val dir = File(mediaList[0].path).parentFile val data = currentDir.listFiles()?.map { it.file2MediaDataC(context) } ?: listOf()
val data = dir?.listFiles()?.map { it.file2MediaDataC(context) } ?: listOf()
setData(data) setData(data)
} }
@SuppressLint("NotifyDataSetChanged")
fun removeData(file: List<MediaDataC>) {
mediaList.removeAll(file.toSet())
// file.forEachIndexed { index, mediaDataC ->
// Log.e("removeData", "index=$index $mediaDataC")
// }
notifyDataSetChanged()
}
fun notifyItemIndex(data: MediaDataC) {
mediaList[data.index].select = false
notifyItemChanged(data.index, "单条刷洗")
}
@SuppressLint("NotifyDataSetChanged")
fun notifyItemNoSelect() {
mediaList.forEach { it.select = false }
notifyDataSetChanged()
}
} }
\ No newline at end of file
package com.zxhy.hfilemanagermaster.internalstorage package com.zxhy.hfilemanagermaster.internalstorage
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.content.Intent
import android.graphics.Color import android.graphics.Color
import android.graphics.drawable.ColorDrawable import android.graphics.drawable.ColorDrawable
import android.net.Uri import android.net.Uri
import android.os.Build import android.os.Build
import android.os.Bundle import android.os.Bundle
import android.os.Environment import android.os.Environment
import android.util.Log
import android.view.KeyEvent import android.view.KeyEvent
import android.view.KeyEvent.ACTION_UP import android.view.KeyEvent.ACTION_UP
import android.view.MotionEvent import android.view.MotionEvent
...@@ -17,22 +19,25 @@ import androidx.appcompat.app.AppCompatActivity ...@@ -17,22 +19,25 @@ import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import androidx.core.view.ViewCompat import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat import androidx.core.view.WindowInsetsCompat
import androidx.lifecycle.ReportFragment.Companion.reportFragment
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
import com.example.hfilemanagermaster.R import com.example.hfilemanagermaster.R
import com.example.hfilemanagermaster.databinding.ActivityInternalStorageBinding import com.example.hfilemanagermaster.databinding.ActivityInternalStorageBinding
import com.example.hfilemanagermaster.databinding.PopupwindowMoreOperationBinding import com.example.hfilemanagermaster.databinding.PopupwindowMoreOperationBinding
import com.zxhy.hfilemanagermaster.data.MediaDataC import com.zxhy.hfilemanagermaster.data.MediaDataC
import com.zxhy.hfilemanagermaster.data.file2MediaDataC import com.zxhy.hfilemanagermaster.data.file2MediaDataC
import com.zxhy.hfilemanagermaster.dialog.showFileDetailsDialog
import com.zxhy.hfilemanagermaster.dialog.showFileNameDialog import com.zxhy.hfilemanagermaster.dialog.showFileNameDialog
import com.zxhy.hfilemanagermaster.dialog.showOperationDialog import com.zxhy.hfilemanagermaster.dialog.showOperationDialog
import com.zxhy.hfilemanagermaster.knife.Saf import com.zxhy.hfilemanagermaster.knife.Saf
import com.zxhy.hfilemanagermaster.knife.deleteDirectory
import com.zxhy.hfilemanagermaster.knife.fileProviderUri
import com.zxhy.hfilemanagermaster.knife.toast import com.zxhy.hfilemanagermaster.knife.toast
import com.zxhy.hfilemanagermaster.permission.IntentLauncher import com.zxhy.hfilemanagermaster.permission.IntentLauncher
import com.zxhy.hfilemanagermaster.permission.PermissionLauncher import com.zxhy.hfilemanagermaster.permission.PermissionLauncher
import com.zxhy.hfilemanagermaster.permission.requestStoreFollow import com.zxhy.hfilemanagermaster.permission.requestStoreFollow
import com.zxhy.hfilemanagermaster.permission.settingManageExternalStorage import com.zxhy.hfilemanagermaster.permission.settingManageExternalStorage
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import java.io.File import java.io.File
...@@ -48,13 +53,15 @@ class InternalStorageActivity : AppCompatActivity() { ...@@ -48,13 +53,15 @@ class InternalStorageActivity : AppCompatActivity() {
private val browseMode = 0 private val browseMode = 0
private val selectMode = 1 private val selectMode = 1
private val selectedOperationMode = 2 private val selectedOperationMode = 2
private var currentMode = browseMode //0普通浏览模式 1可选模式 2选中操作模式 private val lockMode = -1
private var currentMode = lockMode //0普通浏览模式 1可选模式 2选中操作模式 -1无权限锁功能模式
private var popupWindow: PopupWindow? = null private var popupWindow: PopupWindow? = null
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
enableEdgeToEdge() enableEdgeToEdge()
saf = Saf(this) saf = Saf(this)
permissionLauncher = PermissionLauncher(this)
intentLauncher = IntentLauncher(this) intentLauncher = IntentLauncher(this)
binding = ActivityInternalStorageBinding.inflate(layoutInflater) binding = ActivityInternalStorageBinding.inflate(layoutInflater)
setContentView(binding.root) setContentView(binding.root)
...@@ -76,14 +83,11 @@ class InternalStorageActivity : AppCompatActivity() { ...@@ -76,14 +83,11 @@ class InternalStorageActivity : AppCompatActivity() {
val flag = Environment.isExternalStorageManager() val flag = Environment.isExternalStorageManager()
if (flag) { if (flag) {
fileMode() fileMode()
// toast("已设置额外储存管理")
} else { } else {
// toast("未设置额外储存管理")
lockMode() lockMode()
} }
} }
} else { } else {
// toast("已设置额外储存管理")
fileMode() fileMode()
} }
} else { } else {
...@@ -98,24 +102,59 @@ class InternalStorageActivity : AppCompatActivity() { ...@@ -98,24 +102,59 @@ class InternalStorageActivity : AppCompatActivity() {
lockMode() lockMode()
} }
} else { } else {
fileMode() requestStoreFollow(
permissionLauncher,
intentLauncher
) {
fileMode()
}
} }
} }
private fun fileMode() { private fun fileMode() {
binding.clLock.visibility = View.GONE binding.clLock.visibility = View.GONE
binding.clShow.visibility = View.VISIBLE binding.clShow.visibility = View.VISIBLE
fileAdapter = FileAdapter { fileAdapter =
binding.ivAll.isSelected = it FileAdapter(
} selectAction = { binding.ivAll.isSelected = it },
nextPageAction = {
binding.tvDir.text = it.absolutePath
isEmptyUi()
},
beforePageAction = {
binding.tvDir.text = it.absolutePath
isEmptyUi()
}
)
binding.ivAll.setOnClickListener { binding.ivAll.setOnClickListener {
it.isSelected = fileAdapter.setToggleSelect() if (currentMode == selectMode) {
it.isSelected = fileAdapter.setToggleSelect()
}
}
binding.ivNewFolder.setOnClickListener {
showFileNameDialog("New Folder",
sureAction = { name ->
val currentDir = fileAdapter.getCurrentDir()
val file = File(currentDir, name)
if (file.exists()) {
toast("can't create exists folder")
} else {
val flag = file.mkdirs()
if (flag) {
fileAdapter.notifyCurrentDir(this)
isEmptyUi()
} else {
toast("create folder failed!")
browseMode()
}
}
},
dismissAction = {})
} }
binding.rv.adapter = fileAdapter binding.rv.adapter = fileAdapter
File("").renameTo(File(""))
loadFile()
browseMode() browseMode()
loadFile()
} }
private fun loadFile() { private fun loadFile() {
...@@ -126,12 +165,17 @@ class InternalStorageActivity : AppCompatActivity() { ...@@ -126,12 +165,17 @@ class InternalStorageActivity : AppCompatActivity() {
} ?: listOf() } ?: listOf()
lifecycleScope.launch(Dispatchers.Main) { lifecycleScope.launch(Dispatchers.Main) {
val dir = File(list.first().path).parentFile ?: File("")
if (dir.exists() && dir.isDirectory) {
binding.tvDir.text = dir.absolutePath
}
fileAdapter.setData(list) fileAdapter.setData(list)
} }
} }
} }
private fun lockMode() { private fun lockMode() {
currentMode = lockMode
binding.clLock.visibility = View.VISIBLE binding.clLock.visibility = View.VISIBLE
binding.clShow.visibility = View.GONE binding.clShow.visibility = View.GONE
...@@ -139,10 +183,10 @@ class InternalStorageActivity : AppCompatActivity() { ...@@ -139,10 +183,10 @@ class InternalStorageActivity : AppCompatActivity() {
binding.tvAll.visibility = View.GONE binding.tvAll.visibility = View.GONE
binding.ivWrite.visibility = View.GONE binding.ivWrite.visibility = View.GONE
binding.ivNewFolder.visibility = View.GONE binding.ivNewFolder.visibility = View.GONE
} }
//可选择模式 //可选择模式
@SuppressLint("IntentReset")
private fun selectMode() { private fun selectMode() {
currentMode = selectMode currentMode = selectMode
binding.ivWrite.visibility = View.GONE binding.ivWrite.visibility = View.GONE
...@@ -167,7 +211,26 @@ class InternalStorageActivity : AppCompatActivity() { ...@@ -167,7 +211,26 @@ class InternalStorageActivity : AppCompatActivity() {
copyOperation(selectList) copyOperation(selectList)
} }
binding.ivShare.setOnClickListener { binding.ivShare.setOnClickListener {
this.toast("Stay tuned!") val selectList = fileAdapter.getSelectFile()
if (selectList.size == 1) {
Intent().apply {
val file = File(selectList.first().path)
if (file.exists()) {
if (file.isFile) {
action = Intent.ACTION_SEND
val uri = fileProviderUri(this@InternalStorageActivity, file)
setDataAndType(uri, "*/*")
startActivity(this)
} else {
toast("can't share Directory")
}
} else {
toast("share file don't exists")
}
}
} else {
toast("Please select only one file!")
}
} }
binding.ivMore.setOnClickListener { binding.ivMore.setOnClickListener {
showPopupMoreOperation() showPopupMoreOperation()
...@@ -184,46 +247,44 @@ class InternalStorageActivity : AppCompatActivity() { ...@@ -184,46 +247,44 @@ class InternalStorageActivity : AppCompatActivity() {
binding.tvAll.visibility = View.GONE binding.tvAll.visibility = View.GONE
binding.clOperation.visibility = View.GONE binding.clOperation.visibility = View.GONE
binding.clConfirm.visibility = View.GONE
binding.ivWrite.setOnClickListener { binding.ivWrite.setOnClickListener {
fileAdapter.showSelect() fileAdapter.showSelect()
selectMode() selectMode()
} }
fileAdapter.notifyItemNoSelect()
} }
private fun moveOperation(selectList: List<MediaDataC>) { private fun moveOperation(selectList: List<MediaDataC>) {
currentMode = selectedOperationMode currentMode = selectedOperationMode
binding.clOperation.visibility = View.INVISIBLE binding.clOperation.visibility = View.GONE
binding.clConfirm.visibility = View.VISIBLE binding.clConfirm.visibility = View.VISIBLE
binding.ivAll.visibility = View.GONE
binding.tvAll.visibility = View.GONE
binding.tvDefine.text = "Motion" binding.tvDefine.text = "Motion"
binding.tvCancel.setOnClickListener { binding.tvCancel.setOnClickListener {
selectMode() browseMode()
} }
binding.tvDefine.setOnClickListener { binding.tvDefine.setOnClickListener {
val dir = fileAdapter.getCurrentDir() val dir = fileAdapter.getCurrentDir()
if (dir == null) { moveFile(selectList, dir)
this.toast("motion failed ")
} else {
moveFile(selectList, dir)
}
} }
} }
private fun copyOperation(selectList: List<MediaDataC>) { private fun copyOperation(selectList: List<MediaDataC>) {
currentMode = selectedOperationMode currentMode = selectedOperationMode
binding.clOperation.visibility = View.INVISIBLE binding.clOperation.visibility = View.GONE
binding.clConfirm.visibility = View.VISIBLE binding.clConfirm.visibility = View.VISIBLE
binding.ivAll.visibility = View.GONE
binding.tvAll.visibility = View.GONE
binding.tvDefine.text = "Copy" binding.tvDefine.text = "Copy"
binding.tvCancel.setOnClickListener { binding.tvCancel.setOnClickListener {
selectMode() browseMode()
} }
binding.tvDefine.setOnClickListener { binding.tvDefine.setOnClickListener {
val dir = fileAdapter.getCurrentDir() val dir = fileAdapter.getCurrentDir()
if (dir == null) { copyFile(selectList, dir)
this.toast("copy failed ")
} else {
copyFile(selectList, dir)
}
} }
} }
...@@ -240,13 +301,18 @@ class InternalStorageActivity : AppCompatActivity() { ...@@ -240,13 +301,18 @@ class InternalStorageActivity : AppCompatActivity() {
} }
} }
runOnUiThread { runOnUiThread {
// this.toast("motion success!") lifecycleScope.launch(Dispatchers.Main) {
showOperationDialog(R.mipmap.er_89875, "motion success!") { val dialog = showOperationDialog(R.mipmap.er_89875, "motion success!") {}
fileAdapter.notifyCurrentDir(this) delay(200)
dialog.dismiss()
fileAdapter.notifyCurrentDir(this@InternalStorageActivity)
} }
} }
} catch (e: Exception) { } catch (e: Exception) {
runOnUiThread { this.toast("motion failed ") } runOnUiThread {
this.toast("motion failed ")
browseMode()
}
} finally { } finally {
runOnUiThread { browseMode() } runOnUiThread { browseMode() }
} }
...@@ -262,13 +328,18 @@ class InternalStorageActivity : AppCompatActivity() { ...@@ -262,13 +328,18 @@ class InternalStorageActivity : AppCompatActivity() {
} }
} }
runOnUiThread { runOnUiThread {
// this.toast("copy success! ") lifecycleScope.launch(Dispatchers.Main) {
showOperationDialog(R.mipmap.qw_8796, "copy success!") { val dialog = showOperationDialog(R.mipmap.qw_8796, "copy success!") {}
fileAdapter.notifyCurrentDir(this) delay(200)
dialog.dismiss()
fileAdapter.notifyCurrentDir(this@InternalStorageActivity)
} }
} }
} catch (e: Exception) { } catch (e: Exception) {
runOnUiThread { this.toast("copy failed ") } runOnUiThread {
this.toast("copy failed ")
browseMode()
}
} finally { } finally {
runOnUiThread { runOnUiThread {
browseMode() browseMode()
...@@ -276,8 +347,7 @@ class InternalStorageActivity : AppCompatActivity() { ...@@ -276,8 +347,7 @@ class InternalStorageActivity : AppCompatActivity() {
} }
}.start() }.start()
@SuppressLint("ClickableViewAccessibility", "InflateParams")
@SuppressLint("ClickableViewAccessibility")
private fun showPopupMoreOperation() { private fun showPopupMoreOperation() {
val yOff = resources.getDimensionPixelSize(R.dimen.dp_180) val yOff = resources.getDimensionPixelSize(R.dimen.dp_180)
...@@ -295,7 +365,7 @@ class InternalStorageActivity : AppCompatActivity() { ...@@ -295,7 +365,7 @@ class InternalStorageActivity : AppCompatActivity() {
popupWindow?.showAsDropDown(binding.ivPlaceholder, 0, -yOff) popupWindow?.showAsDropDown(binding.ivPlaceholder, 0, -yOff)
popupBinding.apply { popupBinding.apply {
tvRename.setOnTouchListener { v, event -> tvRename.setOnTouchListener { _, event ->
when (event.action) { when (event.action) {
MotionEvent.ACTION_DOWN -> { MotionEvent.ACTION_DOWN -> {
...@@ -314,13 +384,13 @@ class InternalStorageActivity : AppCompatActivity() { ...@@ -314,13 +384,13 @@ class InternalStorageActivity : AppCompatActivity() {
val list = fileAdapter.getSelectFile() val list = fileAdapter.getSelectFile()
if (list.size == 1) { if (list.size == 1) {
val file = File(list.first().path) val file = File(list.first().path)
renameFile(file)
popupWindow?.dismiss() popupWindow?.dismiss()
renameFile(file)
} else { } else {
toast("Please select only one file!") toast("Please select only one file!")
} }
} }
tvDelete.setOnTouchListener { v, event -> tvDelete.setOnTouchListener { _, event ->
when (event.action) { when (event.action) {
MotionEvent.ACTION_DOWN -> { MotionEvent.ACTION_DOWN -> {
popupBinding.ivDelete.isSelected = true popupBinding.ivDelete.isSelected = true
...@@ -334,7 +404,13 @@ class InternalStorageActivity : AppCompatActivity() { ...@@ -334,7 +404,13 @@ class InternalStorageActivity : AppCompatActivity() {
} }
false false
} }
tvDetails.setOnTouchListener { v, event -> tvDelete.setOnClickListener {
val list = fileAdapter.getSelectFile()
if (list.isEmpty()) return@setOnClickListener
popupWindow?.dismiss()
deleteFiles(list)
}
tvDetails.setOnTouchListener { _, event ->
when (event.action) { when (event.action) {
MotionEvent.ACTION_DOWN -> { MotionEvent.ACTION_DOWN -> {
popupBinding.ivDetails.isSelected = true popupBinding.ivDetails.isSelected = true
...@@ -348,6 +424,25 @@ class InternalStorageActivity : AppCompatActivity() { ...@@ -348,6 +424,25 @@ class InternalStorageActivity : AppCompatActivity() {
} }
false false
} }
tvDetails.setOnClickListener {
val list = fileAdapter.getSelectFileIndex()
if (list.size == 1) {
val data = list.first()
val file = File(data.path)
if (file.exists()) {
popupWindow?.dismiss()
showFileDetailsDialog("File details", file,
cancelAction = {
fileAdapter.notifyItemIndex(data)
}, dismissAction = {})
} else {
toast("file don't exist!")
}
} else {
toast("Please select only one file!")
}
}
} }
} else { } else {
popupWindow?.showAsDropDown(binding.ivPlaceholder, 0, -yOff) popupWindow?.showAsDropDown(binding.ivPlaceholder, 0, -yOff)
...@@ -355,6 +450,7 @@ class InternalStorageActivity : AppCompatActivity() { ...@@ -355,6 +450,7 @@ class InternalStorageActivity : AppCompatActivity() {
} }
private fun renameFile(file: File) { private fun renameFile(file: File) {
val dir = file.parentFile ?: File("") val dir = file.parentFile ?: File("")
if (file.exists() && dir.exists()) { if (file.exists() && dir.exists()) {
showFileNameDialog("Rename", sureAction = { showFileNameDialog("Rename", sureAction = {
...@@ -367,42 +463,69 @@ class InternalStorageActivity : AppCompatActivity() { ...@@ -367,42 +463,69 @@ class InternalStorageActivity : AppCompatActivity() {
fileAdapter.notifyCurrentDir(this) fileAdapter.notifyCurrentDir(this)
}, dismissAction = {}) }, dismissAction = {})
} else { } else {
toast("Can't rename file!") lifecycleScope.launch(Dispatchers.Main) {
toast("Can't rename file!")
}
} }
} }
override fun dispatchKeyEvent(event: KeyEvent): Boolean { private fun deleteFiles(files: List<MediaDataC>) = Thread {
try {
when (currentMode) { files.forEach {
selectedOperationMode -> { val file = File(it.path)
var flag = false if (file.exists()) {
if (event.keyCode == KeyEvent.KEYCODE_BACK && event.action == ACTION_UP) { if (file.isFile) file.delete() else deleteDirectory(file)
flag = fileAdapter.beforePage(this)
}
return if (flag) {
false
} else {
super.dispatchKeyEvent(event)
} }
} }
lifecycleScope.launch(Dispatchers.Main) {
selectMode -> { val dialog = showOperationDialog(R.mipmap.dads_889562, "delete success!") {}
browseMode() delay(200)
fileAdapter.showNoSelect() dialog.dismiss()
return false fileAdapter.removeData(files)
}
} catch (e: Exception) {
e.printStackTrace()
runOnUiThread {
toast("delete failed")
} }
}
}.start()
browseMode -> { override fun dispatchKeyEvent(event: KeyEvent): Boolean {
var flag = false
if (event.keyCode == KeyEvent.KEYCODE_BACK && event.action == ACTION_UP) { if (event.keyCode == KeyEvent.KEYCODE_BACK && event.action == ACTION_UP) {
flag = fileAdapter.beforePage(this) when (currentMode) {
browseMode -> {
Log.e("dispatchKeyEvent", "currentMode=$browseMode")
var flag = false
if (event.keyCode == KeyEvent.KEYCODE_BACK && event.action == ACTION_UP) {
flag = fileAdapter.beforePage(this)
}
return if (flag) {
false
} else {
super.dispatchKeyEvent(event)
}
} }
return if (flag) {
false selectMode -> {
} else { Log.e("dispatchKeyEvent", "currentMode=$selectMode")
super.dispatchKeyEvent(event) browseMode()
fileAdapter.showNoSelect()
return false
}
selectedOperationMode -> {
Log.e("dispatchKeyEvent", "currentMode=$selectedOperationMode")
val flag = fileAdapter.beforePage(this)
return if (flag) {
false
} else {
super.dispatchKeyEvent(event)
}
} }
lockMode -> {}
} }
} }
...@@ -410,4 +533,19 @@ class InternalStorageActivity : AppCompatActivity() { ...@@ -410,4 +533,19 @@ class InternalStorageActivity : AppCompatActivity() {
} }
private fun isEmptyUi() {
if (currentMode == selectedOperationMode) return
val count = fileAdapter.itemCount
if (count == 0) {
binding.ivEmpty.visibility = View.VISIBLE
binding.rv.visibility = View.INVISIBLE
binding.clOperation.visibility = View.GONE
binding.clConfirm.visibility = View.GONE
} else {
binding.ivEmpty.visibility = View.GONE
binding.rv.visibility = View.VISIBLE
}
}
} }
\ No newline at end of file
...@@ -4,13 +4,15 @@ import android.content.ContentResolver ...@@ -4,13 +4,15 @@ import android.content.ContentResolver
import android.content.ContentUris import android.content.ContentUris
import android.content.Context import android.content.Context
import android.database.Cursor import android.database.Cursor
import android.os.Environment
import android.provider.MediaStore import android.provider.MediaStore
import com.zxhy.hfilemanagermaster.data.MediaDataC import com.zxhy.hfilemanagermaster.data.MediaDataC
import com.zxhy.hfilemanagermaster.data.file2MediaDataC
import java.io.File import java.io.File
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
import java.util.Locale import java.util.Locale
fun Context.dupImage(): ArrayList<MediaDataC> { fun Context.dupImageMedia(): ArrayList<MediaDataC> {
val list = arrayListOf<MediaDataC>() val list = arrayListOf<MediaDataC>()
var cursor: Cursor? = null var cursor: Cursor? = null
// 查询照片的Uri和字段 // 查询照片的Uri和字段
...@@ -29,8 +31,8 @@ fun Context.dupImage(): ArrayList<MediaDataC> { ...@@ -29,8 +31,8 @@ fun Context.dupImage(): ArrayList<MediaDataC> {
do { do {
// 获取照片的ID和名称 // 获取照片的ID和名称
val id = cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.Images.Media._ID)) val id = cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.Images.Media._ID))
val name = // val name =
cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DISPLAY_NAME)) // cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DISPLAY_NAME))
// 根据ID构建照片的Uri // 根据ID构建照片的Uri
val photoUri = ContentUris.withAppendedId(uri, id) val photoUri = ContentUris.withAppendedId(uri, id)
...@@ -57,6 +59,20 @@ fun Context.dupImage(): ArrayList<MediaDataC> { ...@@ -57,6 +59,20 @@ fun Context.dupImage(): ArrayList<MediaDataC> {
return list return list
} }
fun Context.dupImageStore(): ArrayList<MediaDataC> {
val list = arrayListOf<MediaDataC>()
try {
val root = Environment.getExternalStorageDirectory()
traverseImageFolder(root) { file ->
val md5 = file.digestMd5().byteArrayToHexString()
list.add(file.file2MediaDataC(this, md5 = md5))
}
} catch (e: Exception) {
e.printStackTrace()
}
return list
}
//获取重复图片 //获取重复图片
fun getDupImageList(list: List<MediaDataC>): List<List<MediaDataC>> { fun getDupImageList(list: List<MediaDataC>): List<List<MediaDataC>> {
val dupList = arrayListOf<List<MediaDataC>>() val dupList = arrayListOf<List<MediaDataC>>()
......
...@@ -22,21 +22,68 @@ fun traverseFolder(folder: File): ArrayList<File> { ...@@ -22,21 +22,68 @@ fun traverseFolder(folder: File): ArrayList<File> {
return fileList return fileList
} }
fun traverseEmptyFolder(folder: File): ArrayList<File> { fun traverseLargeFolder(folder: File, onDo: ((file: File) -> Unit)? = null) {
val fileList = arrayListOf<File>()
val emptyFile = arrayListOf<File>()
folder.listFiles()?.forEach { folder.listFiles()?.forEach {
if (it.isDirectory) { if (it.isDirectory) {
fileList.addAll(traverseFolder(it)) traverseLargeFolder(it) { file ->
onDo?.invoke(file)
}
} else {
if (it.length() >= 10 * 1024 * 1024L) {
onDo?.invoke(it)
}
}
}
}
fun traverseLargeImage(folder: File, onDo: ((file: File) -> Unit)? = null) {
folder.listFiles()?.forEach {
if (it.isDirectory) {
traverseLargeImage(it) { file ->
onDo?.invoke(file)
}
} else {
if (it.name.contains(".jpg") && it.length() >= 10 * 1024 * 1024L) {
onDo?.invoke(it)
}
}
}
}
fun traverseLargeVideo(folder: File, onDo: ((file: File) -> Unit)? = null) {
folder.listFiles()?.forEach {
if (it.isDirectory) {
traverseLargeVideo(it) { file ->
onDo?.invoke(file)
}
} else {
if (it.name.contains(".mp4") && it.length() >= 10 * 1024 * 1024L) {
onDo?.invoke(it)
}
}
}
}
fun traverseEmptyFolder(folder: File, onDo: ((file: File) -> Unit)? = null) {
folder.listFiles()?.forEach {
if (it.isDirectory) {
traverseEmptyFolder(it) { file ->
onDo?.invoke(file)
}
} else { } else {
if (it.length() == 0L) { if (it.length() == 0L) {
emptyFile.add(it) onDo?.invoke(it)
} }
} }
} }
return emptyFile
} }
fun traverseImageFolder(folder: File, onDo: ((file: File) -> Unit)? = null) { fun traverseImageFolder(folder: File, onDo: ((file: File) -> Unit)? = null) {
folder.listFiles()?.forEach { folder.listFiles()?.forEach {
...@@ -191,6 +238,29 @@ fun traverseLogFolder(folder: File, onDo: ((file: File) -> Unit)? = null) { ...@@ -191,6 +238,29 @@ fun traverseLogFolder(folder: File, onDo: ((file: File) -> Unit)? = null) {
} }
} }
fun traverseDocumentFolder(folder: File, onDo: ((file: File) -> Unit)? = null) {
folder.listFiles()?.forEach {
if (it.isDirectory) {
traverseDocumentFolder(it) { file ->
onDo?.invoke(file)
}
} else {
if (
(it.name.contains(".txt")) or
(it.name.contains(".xls")) or
(it.name.contains(".xlsx")) or
(it.name.contains(".xlsx")) or
(it.name.contains(".pdf")) or
(it.name.contains(".ppt")) or
(it.name.contains(".pptx"))
) {
onDo?.invoke(it)
}
}
}
}
//删除文件夹 //删除文件夹
fun deleteDirectory(dir: File): Boolean { fun deleteDirectory(dir: File): Boolean {
val stackFiles = Stack<File>() val stackFiles = Stack<File>()
...@@ -218,27 +288,112 @@ fun deleteDirectory(dir: File): Boolean { ...@@ -218,27 +288,112 @@ fun deleteDirectory(dir: File): Boolean {
return true return true
} }
fun emptyFile(context: Context): ArrayList<MediaDataC> { fun largeFile(
val list = arrayListOf<MediaDataC>() context: Context,
onDoAction: (list: List<MediaDataC>) -> Unit,
finishAction: (() -> Unit)? = null
) {
try { try {
val file1 = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM) Thread {
val data = traverseEmptyFolder(file1) val root = Environment.getExternalStorageDirectory()
list.addAll(data.map { it.file2MediaDataC(context) }) val tempList = arrayListOf<File>()
val file2 = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS) traverseLargeFolder(root) {
list.addAll(traverseEmptyFolder(file2).map { it.file2MediaDataC(context) }) tempList.add(it)
if (tempList.size == 5) {
onDoAction.invoke(tempList.map { file -> file.file2MediaDataC(context) })
tempList.clear()
}
}
onDoAction.invoke(tempList.map { file -> file.file2MediaDataC(context) })
finishAction?.invoke()
}.start()
val file3 = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) } catch (e: Exception) {
list.addAll(traverseEmptyFolder(file3).map { it.file2MediaDataC(context) }) e.printStackTrace()
}
}
fun largeImage(
context: Context,
onDoAction: (list: List<MediaDataC>) -> Unit,
finishAction: (() -> Unit)? = null
) {
try {
Thread {
val root = Environment.getExternalStorageDirectory()
val tempList = arrayListOf<File>()
traverseLargeImage(root) {
tempList.add(it)
if (tempList.size == 5) {
onDoAction.invoke(tempList.map { file -> file.file2MediaDataC(context) })
tempList.clear()
}
}
onDoAction.invoke(tempList.map { file -> file.file2MediaDataC(context) })
finishAction?.invoke()
}.start()
val file4 = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES)
list.addAll(traverseEmptyFolder(file4).map { it.file2MediaDataC(context) })
} catch (e: Exception) { } catch (e: Exception) {
e.printStackTrace() e.printStackTrace()
} }
}
return list fun largeVideo(
context: Context,
onDoAction: (list: List<MediaDataC>) -> Unit,
finishAction: (() -> Unit)? = null
) {
try {
Thread {
val root = Environment.getExternalStorageDirectory()
val tempList = arrayListOf<File>()
traverseLargeVideo(root) {
tempList.add(it)
if (tempList.size == 5) {
onDoAction.invoke(tempList.map { file -> file.file2MediaDataC(context) })
tempList.clear()
}
}
onDoAction.invoke(tempList.map { file -> file.file2MediaDataC(context) })
finishAction?.invoke()
}.start()
} catch (e: Exception) {
e.printStackTrace()
}
}
fun emptyFile(
context: Context,
onDoAction: (list: List<MediaDataC>) -> Unit,
finishAction: (() -> Unit)? = null
) {
try {
Thread {
val root = Environment.getExternalStorageDirectory()
val tempList = arrayListOf<File>()
traverseEmptyFolder(root) {
tempList.add(it)
if (tempList.size == 5) {
onDoAction.invoke(tempList.map { file -> file.file2MediaDataC(context) })
tempList.clear()
}
}
onDoAction.invoke(tempList.map { file -> file.file2MediaDataC(context) })
finishAction?.invoke()
}.start()
} catch (e: Exception) {
e.printStackTrace()
}
} }
fun imageFile( fun imageFile(
...@@ -499,6 +654,32 @@ fun logFile( ...@@ -499,6 +654,32 @@ fun logFile(
finishAction?.invoke() finishAction?.invoke()
}.start() }.start()
} catch (e: Exception) {
e.printStackTrace()
}
}
fun documentFile(
context: Context,
onDoAction: (list: List<MediaDataC>) -> Unit,
finishAction: (() -> Unit)? = null
) {
try {
Thread {
val root = Environment.getExternalStorageDirectory()
val tempList = arrayListOf<File>()
traverseDocumentFolder(root) {
tempList.add(it)
if (tempList.size == 5) {
onDoAction.invoke(tempList.map { file -> file.file2MediaDataC(context) })
tempList.clear()
}
}
onDoAction.invoke(tempList.map { file -> file.file2MediaDataC(context) })
finishAction?.invoke()
}.start()
} catch (e: Exception) { } catch (e: Exception) {
e.printStackTrace() e.printStackTrace()
} }
......
package com.zxhy.hfilemanagermaster.knife
import android.content.Context
import android.net.Uri
import androidx.core.content.FileProvider
import java.io.File
// File通过FileProvider,获取Uri
fun fileProviderUri(context: Context, shareFile: File): Uri {
val s = context.applicationContext.packageName
//注意这里第二个参数,要和配置文件里的 android:authorities="${applicationId}.fileProvider",保持一致
return FileProvider.getUriForFile(
context, context.applicationContext.packageName + ".fileProvider", shareFile
)
}
\ No newline at end of file
...@@ -39,8 +39,8 @@ fun Context.recentPhoto(): ArrayList<Uri> { ...@@ -39,8 +39,8 @@ fun Context.recentPhoto(): ArrayList<Uri> {
do { do {
// 获取照片的ID和名称 // 获取照片的ID和名称
val id = cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.Images.Media._ID)) val id = cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.Images.Media._ID))
val name = // val name =
cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DISPLAY_NAME)) // cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DISPLAY_NAME))
// 根据ID构建照片的Uri // 根据ID构建照片的Uri
val photoUri = ContentUris.withAppendedId(uri, id) val photoUri = ContentUris.withAppendedId(uri, id)
...@@ -83,8 +83,8 @@ fun Context.largePhoto(): ArrayList<MediaDataC> { ...@@ -83,8 +83,8 @@ fun Context.largePhoto(): ArrayList<MediaDataC> {
do { do {
// 获取照片的ID和名称 // 获取照片的ID和名称
val id = cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.Images.Media._ID)) val id = cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.Images.Media._ID))
val name = // val name =
cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DISPLAY_NAME)) // cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DISPLAY_NAME))
// 根据ID构建照片的Uri // 根据ID构建照片的Uri
val photoUri = ContentUris.withAppendedId(uri, id) val photoUri = ContentUris.withAppendedId(uri, id)
...@@ -109,70 +109,70 @@ fun Context.largePhoto(): ArrayList<MediaDataC> { ...@@ -109,70 +109,70 @@ fun Context.largePhoto(): ArrayList<MediaDataC> {
return list return list
} }
@SuppressLint("SimpleDateFormat") //@SuppressLint("SimpleDateFormat")
fun Context.largeVideo(): ArrayList<MediaDataC> { //fun Context.largeVideo(): ArrayList<MediaDataC> {
val list = arrayListOf<MediaDataC>() // val list = arrayListOf<MediaDataC>()
var cursor: Cursor? = null // var cursor: Cursor? = null
// 查询视频的Uri和字段 // // 查询视频的Uri和字段
val uri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI // val uri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI
val projection = arrayOf( // val projection = arrayOf(
MediaStore.Video.Media._ID, // MediaStore.Video.Media._ID,
MediaStore.Video.Media.DISPLAY_NAME, // MediaStore.Video.Media.DISPLAY_NAME,
MediaStore.Video.Media.SIZE, // MediaStore.Video.Media.SIZE,
) // )
try { // try {
// 执行查询 // // 执行查询
val contentResolver: ContentResolver = contentResolver // val contentResolver: ContentResolver = contentResolver
cursor = contentResolver.query(uri, projection, null, null, null) // cursor = contentResolver.query(uri, projection, null, null, null)
//
// 遍历结果 // // 遍历结果
if (cursor != null && cursor.moveToFirst()) { // if (cursor != null && cursor.moveToFirst()) {
do { // do {
// 获取视频的ID // // 获取视频的ID
val id = cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.Video.Media._ID)) // val id = cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.Video.Media._ID))
//名称 // //名称
val name = // val name =
cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Video.Media.DISPLAY_NAME)) // cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Video.Media.DISPLAY_NAME))
//大小 // //大小
val size = // val size =
cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.Video.Media.SIZE)) // cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.Video.Media.SIZE))
val sizeS = Formatter.formatFileSize(this, size) // val sizeS = Formatter.formatFileSize(this, size)
//
// 根据ID构建视频的Uri // // 根据ID构建视频的Uri
val videoUri = ContentUris.withAppendedId(uri, id) // val videoUri = ContentUris.withAppendedId(uri, id)
//
//时间 // //时间
val filePath = getFilePathByUri(this, videoUri) ?: "" // val filePath = getFilePathByUri(this, videoUri) ?: ""
val time = File(filePath).lastModified() // val time = File(filePath).lastModified()
// val timeS = //// val timeS =
// SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(time) //// SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(time)
val timeE = SimpleDateFormat("MMM dd, yyyy", Locale.ENGLISH).format(time) // val timeE = SimpleDateFormat("MMM dd, yyyy", Locale.ENGLISH).format(time)
list.add( // list.add(
MediaDataC( // MediaDataC(
name = name, // name = name,
size = sizeS, // size = sizeS,
time = timeE, // time = timeE,
MediaDataC_TYPE_VIDEO, // MediaDataC_TYPE_VIDEO,
uri = videoUri, // uri = videoUri,
path = filePath // path = filePath
) // )
) // )
// 在此处进行视频的操作,例如显示、复制、删除等 // // 在此处进行视频的操作,例如显示、复制、删除等
// ... // // ...
if (list.size == 10) { // if (list.size == 10) {
break // break
} // }
} while (cursor.moveToNext()) // } while (cursor.moveToNext())
} else { // } else {
println("无数据") // println("无数据")
} // }
} catch (e: Exception) { // } catch (e: Exception) {
e.printStackTrace() // e.printStackTrace()
} finally { // } finally {
cursor?.close() // cursor?.close()
} // }
return list // return list
} //}
//无效 //无效
fun getMediaCreateTime(videoPath: String) { fun getMediaCreateTime(videoPath: String) {
......
package com.zxhy.hfilemanagermaster.largefile package com.zxhy.hfilemanagermaster.largefile
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.util.Log
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
...@@ -10,6 +11,7 @@ import com.example.hfilemanagermaster.databinding.ItemMediaSelectBinding ...@@ -10,6 +11,7 @@ import com.example.hfilemanagermaster.databinding.ItemMediaSelectBinding
import com.zxhy.hfilemanagermaster.data.MediaDataC import com.zxhy.hfilemanagermaster.data.MediaDataC
import com.zxhy.hfilemanagermaster.glide.loadIntoImageView import com.zxhy.hfilemanagermaster.glide.loadIntoImageView
import com.zxhy.hfilemanagermaster.knife.inflate import com.zxhy.hfilemanagermaster.knife.inflate
import java.io.File
class LagerFileSelectorAdapter( class LagerFileSelectorAdapter(
private val selectAction: ((flag: Boolean) -> Unit)? = null private val selectAction: ((flag: Boolean) -> Unit)? = null
...@@ -34,7 +36,32 @@ class LagerFileSelectorAdapter( ...@@ -34,7 +36,32 @@ class LagerFileSelectorAdapter(
val data = mediaList[position] val data = mediaList[position]
holder.binding.apply { holder.binding.apply {
loadIntoImageView(context, data.uri, iv) if (data.path.contains(".jpg")
or
data.path.contains(".mp4")
or
data.path.contains(".png")
) {
loadIntoImageView(context, File(data.path), iv)
} else if (data.path.contains(".txt")) {
iv.setImageResource(R.mipmap.io_002)
} else if (data.path.contains(".xlsx") or data.path.contains(".xls")) {
iv.setImageResource(R.mipmap.as_85230)
} else if (data.path.contains(".pdf")) {
iv.setImageResource(R.mipmap.io_0012)
} else if (data.path.contains(".ppt") or data.path.contains(".pptx")) {
iv.setImageResource(R.mipmap.io_002223)
} else if (data.path.contains(".apk")) {
iv.setImageResource(R.mipmap.fe_98856)
} else if (data.path.contains(".zip")) {
iv.setImageResource(R.mipmap.qwett_98959)
} else if (data.path.contains("log") && File(data.path).isFile) {
iv.setImageResource(R.mipmap.rqwr_875)
} else if (File(data.path).isDirectory) {
iv.setImageResource(R.mipmap.tt_695)
} else {
iv.setImageResource(R.drawable.icon_file_unknown)
}
tvName.text = data.name tvName.text = data.name
tvSize.text = data.size tvSize.text = data.size
...@@ -60,7 +87,32 @@ class LagerFileSelectorAdapter( ...@@ -60,7 +87,32 @@ class LagerFileSelectorAdapter(
//判断是做局部刷新还是单条刷新 //判断是做局部刷新还是单条刷新
if (payloads.isEmpty()) {//局部刷新 if (payloads.isEmpty()) {//局部刷新
holder.binding.apply { holder.binding.apply {
loadIntoImageView(context, data.uri, iv) if (data.path.contains(".jpg")
or
data.path.contains(".mp4")
or
data.path.contains(".png")
) {
loadIntoImageView(context, File(data.path), iv)
} else if (data.path.contains(".txt")) {
iv.setImageResource(R.mipmap.io_002)
} else if (data.path.contains(".xlsx") or data.path.contains(".xls")) {
iv.setImageResource(R.mipmap.as_85230)
} else if (data.path.contains(".pdf")) {
iv.setImageResource(R.mipmap.io_0012)
} else if (data.path.contains(".ppt") or data.path.contains(".pptx")) {
iv.setImageResource(R.mipmap.io_002223)
} else if (data.path.contains(".apk")) {
iv.setImageResource(R.mipmap.fe_98856)
} else if (data.path.contains(".zip")) {
iv.setImageResource(R.mipmap.qwett_98959)
} else if (data.path.contains("log") && File(data.path).isFile) {
iv.setImageResource(R.mipmap.rqwr_875)
} else if (File(data.path).isDirectory) {
iv.setImageResource(R.mipmap.tt_695)
} else {
iv.setImageResource(R.drawable.icon_file_unknown)
}
tvName.text = data.name tvName.text = data.name
tvSize.text = data.size tvSize.text = data.size
...@@ -108,4 +160,22 @@ class LagerFileSelectorAdapter( ...@@ -108,4 +160,22 @@ class LagerFileSelectorAdapter(
return mediaList.filter { it.select } return mediaList.filter { it.select }
} }
@SuppressLint("NotifyDataSetChanged")
fun addData(data: List<MediaDataC>) {
val index = mediaList.size
mediaList.addAll(data)
notifyItemRangeChanged(index, data.size)
// Log.e("FileSelectorAdapter", mediaList.size.toString())
}
@SuppressLint("NotifyDataSetChanged")
fun removeData(file: List<MediaDataC>) {
mediaList.removeAll(file.toSet())
// file.forEachIndexed { index, mediaDataC ->
// Log.e("removeData", "index=$index $mediaDataC")
// }
notifyDataSetChanged()
}
} }
\ No newline at end of file
package com.zxhy.hfilemanagermaster.largefile package com.zxhy.hfilemanagermaster.largefile
import android.app.Dialog
import android.os.Bundle import android.os.Bundle
import android.view.View
import androidx.activity.enableEdgeToEdge import androidx.activity.enableEdgeToEdge
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
...@@ -12,12 +14,21 @@ import androidx.recyclerview.widget.LinearLayoutManager ...@@ -12,12 +14,21 @@ import androidx.recyclerview.widget.LinearLayoutManager
import com.example.hfilemanagermaster.R import com.example.hfilemanagermaster.R
import com.example.hfilemanagermaster.databinding.ActivityLargeFileBinding import com.example.hfilemanagermaster.databinding.ActivityLargeFileBinding
import com.zxhy.hfilemanagermaster.data.MediaDataC import com.zxhy.hfilemanagermaster.data.MediaDataC
import com.zxhy.hfilemanagermaster.dialog.showLoadingDialog
import com.zxhy.hfilemanagermaster.dialog.showOperationDialog import com.zxhy.hfilemanagermaster.dialog.showOperationDialog
import com.zxhy.hfilemanagermaster.emptyfile.EmptyFileAdapter
import com.zxhy.hfilemanagermaster.knife.deleteDirectory import com.zxhy.hfilemanagermaster.knife.deleteDirectory
import com.zxhy.hfilemanagermaster.knife.emptyFile
import com.zxhy.hfilemanagermaster.knife.largeFile
import com.zxhy.hfilemanagermaster.knife.largeImage
import com.zxhy.hfilemanagermaster.knife.largePhoto import com.zxhy.hfilemanagermaster.knife.largePhoto
import com.zxhy.hfilemanagermaster.knife.largeVideo import com.zxhy.hfilemanagermaster.knife.largeVideo
import com.zxhy.hfilemanagermaster.knife.toast import com.zxhy.hfilemanagermaster.knife.toast
import com.zxhy.hfilemanagermaster.permission.IntentLauncher
import com.zxhy.hfilemanagermaster.permission.PermissionLauncher
import com.zxhy.hfilemanagermaster.permission.alert import com.zxhy.hfilemanagermaster.permission.alert
import com.zxhy.hfilemanagermaster.permission.requestStoreFollow
import com.zxhy.hfilemanagermaster.permission.storePermissionCheck
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay import kotlinx.coroutines.delay
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
...@@ -28,11 +39,15 @@ class LargeFileActivity : AppCompatActivity() { ...@@ -28,11 +39,15 @@ class LargeFileActivity : AppCompatActivity() {
private lateinit var mediaSelectAdapter: LagerFileSelectorAdapter private lateinit var mediaSelectAdapter: LagerFileSelectorAdapter
private lateinit var imageSelectorAdapter: LargeImageSelectorAdapter private lateinit var imageSelectorAdapter: LargeImageSelectorAdapter
private lateinit var videoSelectorAdapter: LargeVideoSelectorAdapter private lateinit var videoSelectorAdapter: LargeVideoSelectorAdapter
private lateinit var permissionLauncher: PermissionLauncher
private lateinit var intentLauncher: IntentLauncher
private var currentMode = 0//0 文件 1图片 2视频 private var currentMode = 0//0 文件 1图片 2视频
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
enableEdgeToEdge() enableEdgeToEdge()
intentLauncher = IntentLauncher(this)
permissionLauncher = PermissionLauncher(this)
binding = ActivityLargeFileBinding.inflate(layoutInflater) binding = ActivityLargeFileBinding.inflate(layoutInflater)
setContentView(binding.root) setContentView(binding.root)
ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main)) { v, insets -> ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main)) { v, insets ->
...@@ -56,8 +71,7 @@ class LargeFileActivity : AppCompatActivity() { ...@@ -56,8 +71,7 @@ class LargeFileActivity : AppCompatActivity() {
if (num == 0) return@setOnClickListener if (num == 0) return@setOnClickListener
this.alert("Currently selected $num items, are you sure to delete them") { this.alert("Currently selected $num items, are you sure to delete them") {
positiveButton("confirm") { dialog -> positiveButton("confirm") { dialog ->
val files = list.map { File(it.path) } deleteFiles(list)
deleteFiles(files)
dialog.dismiss() dialog.dismiss()
} }
negativeButton("cancel") { dialog -> negativeButton("cancel") { dialog ->
...@@ -66,6 +80,8 @@ class LargeFileActivity : AppCompatActivity() { ...@@ -66,6 +80,8 @@ class LargeFileActivity : AppCompatActivity() {
//禁止取消 //禁止取消
isCancel(false) isCancel(false)
} }
} }
binding.ivAll.setOnClickListener { view -> binding.ivAll.setOnClickListener { view ->
when (currentMode) { when (currentMode) {
...@@ -75,21 +91,50 @@ class LargeFileActivity : AppCompatActivity() { ...@@ -75,21 +91,50 @@ class LargeFileActivity : AppCompatActivity() {
} }
} }
fileMode()
binding.tvFile.setOnClickListener { binding.tvFile.setOnClickListener {
fileMode() if (currentMode != 0)
fileMode()
} }
binding.tvImage.setOnClickListener { binding.tvImage.setOnClickListener {
imageMode() if (currentMode != 1)
imageMode()
} }
binding.tvVideo.setOnClickListener { binding.tvVideo.setOnClickListener {
videoMode() if (currentMode != 2)
videoMode()
}
if (storePermissionCheck()) {
imageMode()
} else {
lockMode()
}
}
private fun lockMode() {
binding.clLock.visibility = View.VISIBLE
binding.clShow.visibility = View.GONE
binding.tvSet.setOnClickListener {
this.requestStoreFollow(
permissionLauncher,
intentLauncher,
disAgreeAction = {
lockMode()
},
agreeAction = {
fileMode()
})
} }
} }
private fun fileMode() { private fun fileMode() {
binding.clLock.visibility = View.GONE
binding.clShow.visibility = View.VISIBLE
currentMode = 0 currentMode = 0
binding.tvFile.setTextColor(ContextCompat.getColor(this, R.color.color_333333)) binding.tvFile.setTextColor(ContextCompat.getColor(this, R.color.color_333333))
binding.tvImage.setTextColor(ContextCompat.getColor(this, R.color.color_999999)) binding.tvImage.setTextColor(ContextCompat.getColor(this, R.color.color_999999))
...@@ -105,12 +150,17 @@ class LargeFileActivity : AppCompatActivity() { ...@@ -105,12 +150,17 @@ class LargeFileActivity : AppCompatActivity() {
} }
private fun loadLargeFileData() { private fun loadLargeFileData() {
lifecycleScope.launch(Dispatchers.IO) { val loadDialog = showLoadingDialog()
val list = this@LargeFileActivity.largeVideo() largeFile(this,
lifecycleScope.launch(Dispatchers.Main) { onDoAction = { list ->
mediaSelectAdapter.setData(list) runOnUiThread {
} loadDialog.dismiss()
} mediaSelectAdapter.addData(list)
}
}, finishAction = {
loadDialog.dismiss()
runOnUiThread { isEmptyUi() }
})
} }
private fun imageMode() { private fun imageMode() {
...@@ -128,12 +178,20 @@ class LargeFileActivity : AppCompatActivity() { ...@@ -128,12 +178,20 @@ class LargeFileActivity : AppCompatActivity() {
} }
private fun loadLargeImageData() { private fun loadLargeImageData() {
lifecycleScope.launch(Dispatchers.IO) { val loadDialog = showLoadingDialog()
val list = this@LargeFileActivity.largePhoto() largeImage(
lifecycleScope.launch(Dispatchers.Main) { this,
imageSelectorAdapter.setData(list) onDoAction = { list ->
} runOnUiThread {
} loadDialog.dismiss()
imageSelectorAdapter.addData(list)
}
}, finishAction = {
runOnUiThread {
loadDialog.dismiss()
isEmptyUi()
}
})
} }
private fun videoMode() { private fun videoMode() {
...@@ -153,19 +211,29 @@ class LargeFileActivity : AppCompatActivity() { ...@@ -153,19 +211,29 @@ class LargeFileActivity : AppCompatActivity() {
} }
private fun loadLargeVideoData() { private fun loadLargeVideoData() {
lifecycleScope.launch(Dispatchers.IO) { val loadDialog = showLoadingDialog()
val list = this@LargeFileActivity.largeVideo()
lifecycleScope.launch(Dispatchers.Main) { largeVideo(
videoSelectorAdapter.setData(list) this,
} onDoAction = { list ->
} runOnUiThread {
loadDialog.dismiss()
videoSelectorAdapter.addData(list)
}
}, finishAction = {
runOnUiThread {
loadDialog.dismiss()
isEmptyUi()
}
})
} }
private fun deleteFiles(files: List<File>) = Thread { private fun deleteFiles(files: List<MediaDataC>) = Thread {
try { try {
files.forEach { files.forEach {
if (it.exists()) { val file = File(it.path)
if (it.isFile) it.delete() else deleteDirectory(it) if (file.exists()) {
if (file.isFile) file.delete() else deleteDirectory(file)
} }
} }
runOnUiThread { runOnUiThread {
...@@ -173,13 +241,16 @@ class LargeFileActivity : AppCompatActivity() { ...@@ -173,13 +241,16 @@ class LargeFileActivity : AppCompatActivity() {
val dialog = showOperationDialog(R.mipmap.dads_889562, "delete success!") {} val dialog = showOperationDialog(R.mipmap.dads_889562, "delete success!") {}
delay(200) delay(200)
dialog.dismiss() dialog.dismiss()
when (currentMode) {
0 -> mediaSelectAdapter.removeData(files)
1 -> imageSelectorAdapter.removeData(files)
2 -> videoSelectorAdapter.removeData(files)
}
isEmptyUi()
} }
} }
when (currentMode) {
0 -> loadLargeFileData()
1 -> loadLargeImageData()
2 -> loadLargeVideoData()
}
} catch (e: Exception) { } catch (e: Exception) {
e.printStackTrace() e.printStackTrace()
runOnUiThread { runOnUiThread {
...@@ -187,4 +258,24 @@ class LargeFileActivity : AppCompatActivity() { ...@@ -187,4 +258,24 @@ class LargeFileActivity : AppCompatActivity() {
} }
} }
}.start() }.start()
private fun isEmptyUi() {
val count = when (currentMode) {
0 -> mediaSelectAdapter.itemCount
1 -> imageSelectorAdapter.itemCount
2 -> videoSelectorAdapter.itemCount
else -> 0
}
if (count == 0) {
binding.rv.visibility = View.GONE
binding.tvDelete.visibility = View.GONE
binding.ivEmpty.visibility = View.VISIBLE
} else {
binding.rv.visibility = View.VISIBLE
binding.tvDelete.visibility = View.VISIBLE
binding.ivEmpty.visibility = View.GONE
}
}
} }
\ No newline at end of file
...@@ -35,7 +35,7 @@ class LargeFileFragment : Fragment() { ...@@ -35,7 +35,7 @@ class LargeFileFragment : Fragment() {
companion object { companion object {
@JvmStatic @JvmStatic
fun newInstance(param1: String, param2: String) = fun newInstance() =
LargeFileFragment().apply { LargeFileFragment().apply {
arguments = Bundle().apply {} arguments = Bundle().apply {}
} }
......
package com.zxhy.hfilemanagermaster.largefile package com.zxhy.hfilemanagermaster.largefile
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.util.Log
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
...@@ -10,6 +11,7 @@ import com.example.hfilemanagermaster.databinding.ItemImageSelectBinding ...@@ -10,6 +11,7 @@ import com.example.hfilemanagermaster.databinding.ItemImageSelectBinding
import com.zxhy.hfilemanagermaster.data.MediaDataC import com.zxhy.hfilemanagermaster.data.MediaDataC
import com.zxhy.hfilemanagermaster.glide.loadIntoImageView import com.zxhy.hfilemanagermaster.glide.loadIntoImageView
import com.zxhy.hfilemanagermaster.knife.inflate import com.zxhy.hfilemanagermaster.knife.inflate
import java.io.File
class LargeImageSelectorAdapter( class LargeImageSelectorAdapter(
private val selectAction: ((flag: Boolean) -> Unit)? = null private val selectAction: ((flag: Boolean) -> Unit)? = null
...@@ -35,7 +37,7 @@ class LargeImageSelectorAdapter( ...@@ -35,7 +37,7 @@ class LargeImageSelectorAdapter(
val context = holder.binding.root.context val context = holder.binding.root.context
val data = mediaList[position] val data = mediaList[position]
holder.binding.apply { holder.binding.apply {
loadIntoImageView(context, data.uri, ivImage) loadIntoImageView(context, File(data.path), ivImage)
ivSelector.isSelected = data.select ivSelector.isSelected = data.select
ivSelector.setOnClickListener { ivSelector.setOnClickListener {
data.select = !data.select data.select = !data.select
...@@ -57,7 +59,7 @@ class LargeImageSelectorAdapter( ...@@ -57,7 +59,7 @@ class LargeImageSelectorAdapter(
//判断是做局部刷新还是单条刷新 //判断是做局部刷新还是单条刷新
if (payloads.isEmpty()) {//局部刷新 if (payloads.isEmpty()) {//局部刷新
holder.binding.apply { holder.binding.apply {
loadIntoImageView(context, data.uri, ivImage) loadIntoImageView(context, File(data.path), ivImage)
ivSelector.isSelected = data.select ivSelector.isSelected = data.select
ivSelector.setOnClickListener { ivSelector.setOnClickListener {
data.select = !data.select data.select = !data.select
...@@ -100,4 +102,20 @@ class LargeImageSelectorAdapter( ...@@ -100,4 +102,20 @@ class LargeImageSelectorAdapter(
return mediaList.filter { it.select } return mediaList.filter { it.select }
} }
@SuppressLint("NotifyDataSetChanged")
fun removeData(file: List<MediaDataC>) {
mediaList.removeAll(file.toSet())
// file.forEachIndexed { index, mediaDataC ->
// Log.e("removeData", "index=$index $mediaDataC")
// }
notifyDataSetChanged()
}
@SuppressLint("NotifyDataSetChanged")
fun addData(data: List<MediaDataC>) {
val index = mediaList.size
mediaList.addAll(data)
notifyItemRangeChanged(index, data.size)
// Log.e("FileSelectorAdapter", mediaList.size.toString())
}
} }
\ No newline at end of file
package com.zxhy.hfilemanagermaster.largefile package com.zxhy.hfilemanagermaster.largefile
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.util.Log
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
...@@ -10,6 +11,7 @@ import com.example.hfilemanagermaster.databinding.ItemVideoSelectBinding ...@@ -10,6 +11,7 @@ import com.example.hfilemanagermaster.databinding.ItemVideoSelectBinding
import com.zxhy.hfilemanagermaster.data.MediaDataC import com.zxhy.hfilemanagermaster.data.MediaDataC
import com.zxhy.hfilemanagermaster.glide.loadIntoImageView import com.zxhy.hfilemanagermaster.glide.loadIntoImageView
import com.zxhy.hfilemanagermaster.knife.inflate import com.zxhy.hfilemanagermaster.knife.inflate
import java.io.File
class LargeVideoSelectorAdapter( class LargeVideoSelectorAdapter(
private val selectAction: ((flag: Boolean) -> Unit)? = null private val selectAction: ((flag: Boolean) -> Unit)? = null
...@@ -34,7 +36,7 @@ class LargeVideoSelectorAdapter( ...@@ -34,7 +36,7 @@ class LargeVideoSelectorAdapter(
val context = holder.binding.root.context val context = holder.binding.root.context
val data = mediaList[position] val data = mediaList[position]
holder.binding.apply { holder.binding.apply {
loadIntoImageView(context, data.uri, ivImage) loadIntoImageView(context, File(data.path), ivImage)
ivSelector.isSelected = data.select ivSelector.isSelected = data.select
} }
} }
...@@ -50,7 +52,7 @@ class LargeVideoSelectorAdapter( ...@@ -50,7 +52,7 @@ class LargeVideoSelectorAdapter(
//判断是做局部刷新还是单条刷新 //判断是做局部刷新还是单条刷新
if (payloads.isEmpty()) {//局部刷新 if (payloads.isEmpty()) {//局部刷新
holder.binding.apply { holder.binding.apply {
loadIntoImageView(context, data.uri, ivImage) loadIntoImageView(context, File(data.path), ivImage)
ivSelector.isSelected = data.select ivSelector.isSelected = data.select
ivSelector.setOnClickListener { ivSelector.setOnClickListener {
...@@ -95,4 +97,21 @@ class LargeVideoSelectorAdapter( ...@@ -95,4 +97,21 @@ class LargeVideoSelectorAdapter(
fun getSelectData(): List<MediaDataC> { fun getSelectData(): List<MediaDataC> {
return mediaList.filter { it.select } return mediaList.filter { it.select }
} }
@SuppressLint("NotifyDataSetChanged")
fun removeData(file: List<MediaDataC>) {
mediaList.removeAll(file.toSet())
// file.forEachIndexed { index, mediaDataC ->
// Log.e("removeData", "index=$index $mediaDataC")
// }
notifyDataSetChanged()
}
@SuppressLint("NotifyDataSetChanged")
fun addData(data: List<MediaDataC>) {
val index = mediaList.size
mediaList.addAll(data)
notifyItemRangeChanged(index, data.size)
// Log.e("FileSelectorAdapter", mediaList.size.toString())
}
} }
\ No newline at end of file
package com.zxhy.hfilemanagermaster.manager package com.zxhy.hfilemanagermaster.manager
import android.Manifest
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.os.Build
import android.os.Bundle import android.os.Bundle
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
...@@ -13,15 +11,14 @@ import com.example.hfilemanagermaster.R ...@@ -13,15 +11,14 @@ import com.example.hfilemanagermaster.R
import com.example.hfilemanagermaster.databinding.FragmentManagerBinding import com.example.hfilemanagermaster.databinding.FragmentManagerBinding
import com.zxhy.hfilemanagermaster.OverviewActivity import com.zxhy.hfilemanagermaster.OverviewActivity
import com.zxhy.hfilemanagermaster.knife.getMountInfoList import com.zxhy.hfilemanagermaster.knife.getMountInfoList
import com.zxhy.hfilemanagermaster.permission.IntentLauncher
import com.zxhy.hfilemanagermaster.permission.PermissionLauncher
import com.zxhy.hfilemanagermaster.permission.requestStoreFollow import com.zxhy.hfilemanagermaster.permission.requestStoreFollow
import com.zxhy.hfilemanagermaster.permission.requestPermission
import java.math.BigDecimal import java.math.BigDecimal
/** /**
* A simple [Fragment] subclass.
* Use the [ManagerFragment.newInstance] factory method to
* create an instance of this fragment.
*/ */
@Suppress("DEPRECATION")
class ManagerFragment : Fragment() { class ManagerFragment : Fragment() {
private lateinit var binding: FragmentManagerBinding private lateinit var binding: FragmentManagerBinding
...@@ -55,13 +52,10 @@ class ManagerFragment : Fragment() { ...@@ -55,13 +52,10 @@ class ManagerFragment : Fragment() {
(requireActivity() as OverviewActivity).showManager() (requireActivity() as OverviewActivity).showManager()
binding.ivFile.setOnClickListener { binding.ivFile.setOnClickListener {
val bundle = Bundle().apply {
requireContext().requestStoreFollow( putString("tittle", "Document")
(requireActivity() as OverviewActivity).permissionLauncher,
(requireActivity() as OverviewActivity).intentLauncher
) {
findNavController().navigate(R.id.filesFragment)
} }
findNavController().navigate(R.id.fileBrowseActivity, bundle)
} }
binding.ivWord.setOnClickListener { binding.ivWord.setOnClickListener {
val bundle = Bundle().apply { val bundle = Bundle().apply {
...@@ -69,7 +63,6 @@ class ManagerFragment : Fragment() { ...@@ -69,7 +63,6 @@ class ManagerFragment : Fragment() {
} }
findNavController().navigate(R.id.fileBrowseActivity, bundle) findNavController().navigate(R.id.fileBrowseActivity, bundle)
} }
binding.ivExcel.setOnClickListener { binding.ivExcel.setOnClickListener {
val bundle = Bundle().apply { val bundle = Bundle().apply {
putString("tittle", "Excel") putString("tittle", "Excel")
...@@ -83,47 +76,38 @@ class ManagerFragment : Fragment() { ...@@ -83,47 +76,38 @@ class ManagerFragment : Fragment() {
findNavController().navigate(R.id.fileBrowseActivity, bundle) findNavController().navigate(R.id.fileBrowseActivity, bundle)
} }
binding.ivPpt.setOnClickListener { binding.ivPpt.setOnClickListener {
val bundle = Bundle().apply { val bundle = Bundle().apply {
putString("tittle", "PPT") putString("tittle", "PPT")
} }
findNavController().navigate(R.id.fileBrowseActivity, bundle) findNavController().navigate(R.id.fileBrowseActivity, bundle)
} }
binding.cardView1.setOnClickListener { binding.cardView1.setOnClickListener {
requireContext().requestStoreFollow( findNavController().navigate(R.id.dupPictureActivity)
(requireActivity() as OverviewActivity).permissionLauncher,
(requireActivity() as OverviewActivity).intentLauncher
) {
findNavController().navigate(R.id.dupPictureActivity)
}
} }
binding.cardView2.setOnClickListener { binding.cardView2.setOnClickListener {
findNavController().navigate(R.id.largeFileActivity)
requireContext().requestStoreFollow(
(requireActivity() as OverviewActivity).permissionLauncher,
(requireActivity() as OverviewActivity).intentLauncher
) {
findNavController().navigate(R.id.largeFileActivity)
}
} }
binding.cardView3.setOnClickListener { binding.cardView3.setOnClickListener {
requireContext().requestStoreFollow( findNavController().navigate(R.id.emptyFileActivity)
(requireActivity() as OverviewActivity).permissionLauncher,
(requireActivity() as OverviewActivity).intentLauncher
) {
findNavController().navigate(R.id.emptyFileActivity)
}
} }
binding.tvManage.setOnClickListener { binding.tvManage.setOnClickListener {
findNavController().navigate(R.id.internalStorageActivity) findNavController().navigate(R.id.internalStorageActivity)
} }
requireContext().requestStoreFollow(
(requireActivity() as OverviewActivity).permissionLauncher,
(requireActivity() as OverviewActivity).intentLauncher,
disAgreeAction = {
},
agreeAction = {
})
} }
companion object { companion object {
@JvmStatic @JvmStatic
fun newInstance(param1: String, param2: String) = fun newInstance() =
ManagerFragment().apply { ManagerFragment().apply {
arguments = Bundle().apply { arguments = Bundle().apply {
} }
......
package com.zxhy.hfilemanagermaster.permission package com.zxhy.hfilemanagermaster.permission
import android.Manifest import android.Manifest
import android.annotation.SuppressLint
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.content.pm.PackageManager import android.content.pm.PackageManager
...@@ -20,57 +21,37 @@ fun requestPermission( ...@@ -20,57 +21,37 @@ fun requestPermission(
intentLauncher: IntentLauncher, intentLauncher: IntentLauncher,
permission: Array<String>, permission: Array<String>,
tip: String, tip: String,
agreeAction: (() -> Unit)? = null agreeAction: (() -> Unit)? = null,
): Boolean { disAgreeAction: (() -> Unit)? = null
var flag = false ) {
val request: () -> Unit = { val permissionFlag =
val permissionFlag = permission.all {
permission.all { ContextCompat.checkSelfPermission(context, it) == PackageManager.PERMISSION_GRANTED
ContextCompat.checkSelfPermission(context, it) == PackageManager.PERMISSION_GRANTED }
} if (permissionFlag) {
if (permissionFlag) { agreeAction?.invoke()
flag = true } else {
} else { permissionLauncher.launch(permission) { callback ->
permissionLauncher.launch(permission) { callback -> val isGrantAll = callback.values.all { it }
val isGrantAll = callback.values.all { it } if (!isGrantAll) {
if (!isGrantAll) { context.alert(tip) {
context.alert(tip) { positiveButton("Jump") { dialog ->
positiveButton("Jump") { dialog -> goToPermissionSettings(context, intentLauncher)
goToPermissionSettings(context, intentLauncher) dialog.dismiss()
dialog.dismiss()
}
negativeButton("Cancel") { dialog ->
dialog.dismiss()
}
//禁止取消
isCancel(false)
} }
} else { negativeButton("Cancel") { dialog ->
agreeAction?.invoke() dialog.dismiss()
disAgreeAction?.invoke()
}
//禁止取消
isCancel(false)
} }
} else {
agreeAction?.invoke()
} }
} }
// Toast.makeText(context, "不会等待回调", Toast.LENGTH_SHORT).show()
} }
if (permission.contains(Manifest.permission.WRITE_EXTERNAL_STORAGE)
&& permission.contains(Manifest.permission.READ_EXTERNAL_STORAGE)
) {
val managerFlag = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
Environment.isExternalStorageManager()
} else {
false
}
if (managerFlag) {
return true
} else {
request()
}
} else {
request()
}
return flag
} }
//权限设置界面 //权限设置界面
...@@ -87,33 +68,83 @@ fun appSettingsIntent(packageName: String): Intent { ...@@ -87,33 +68,83 @@ fun appSettingsIntent(packageName: String): Intent {
.setData(Uri.fromParts("package", packageName, null)) .setData(Uri.fromParts("package", packageName, null))
} }
//Android 13以后,读写权限无法弹出系统弹窗,分化为Manifest.permission.READ_MEDIA_*权限
//Android 11以后,Manifest.permission.READ_EXTERNAL_STORAGE 授予后还需授予 额外储存管理权限 ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION
//Android 11以下使用Manifest.permission.READ_EXTERNAL_STORAGE
fun Context.storePermissionCheck(): Boolean {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {//Android 13以后
return Environment.isExternalStorageManager()
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {//Android 11以后
return Environment.isExternalStorageManager() && arrayOf(
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE
).all {
ContextCompat.checkSelfPermission(this, it) == PackageManager.PERMISSION_GRANTED
}
} else { //Android 11以下,Android 6以上
return arrayOf(
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE
).all {
ContextCompat.checkSelfPermission(this, it) == PackageManager.PERMISSION_GRANTED
}
}
}
//Android 13以后,读写权限无法弹出系统弹窗,分化为Manifest.permission.READ_MEDIA_*权限
//Android 11以后,Manifest.permission.READ_EXTERNAL_STORAGE 授予后还需授予 额外储存管理权限 ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION
//Android 11以下使用Manifest.permission.READ_EXTERNAL_STORAGE
@SuppressLint("LocalSuppress")
fun Context.requestStoreFollow( fun Context.requestStoreFollow(
permissionLauncher: PermissionLauncher, permissionLauncher: PermissionLauncher,
intentLauncher: IntentLauncher, intentLauncher: IntentLauncher,
agreeAction: (() -> Unit)? = null disAgreeAction: (() -> Unit)? = null,
agreeAction: (() -> Unit)? = null,
) { ) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
val flag = requestPermission( //请求读写管理权限
this, permissionLauncher, intentLauncher, @SuppressLint("NewApi")
arrayOf( val requestExternalStorageManager: () -> Unit = {
Manifest.permission.READ_MEDIA_IMAGES, if (!Environment.isExternalStorageManager()) {
Manifest.permission.READ_MEDIA_VIDEO val uri = Uri.parse("package:$packageName")
), "Set permission to access media images and videos" val intent = settingManageExternalStorage(uri)
) { intentLauncher.launch(intent) {
val flag = Environment.isExternalStorageManager()
if (flag) agreeAction?.invoke() else disAgreeAction?.invoke()
}
} else {
agreeAction?.invoke() agreeAction?.invoke()
} }
if (flag) agreeAction?.invoke() }
} else {
val flag = requestPermission( if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {//Android 13以后
requestExternalStorageManager()
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {//Android 11以后
requestPermission(
this, permissionLauncher, intentLauncher, this, permissionLauncher, intentLauncher,
arrayOf( arrayOf(
Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE Manifest.permission.WRITE_EXTERNAL_STORAGE
), "Set permission to access external storage" ), "Set permission to access external storage",
) { agreeAction = { //读写权限通过,设置储存管理权限
agreeAction?.invoke() requestExternalStorageManager()
} },
if (flag) agreeAction?.invoke() disAgreeAction = { disAgreeAction?.invoke() }
)
} else { //Android 11以下,Android 6以上
requestPermission(
this, permissionLauncher, intentLauncher,
arrayOf(
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE
), "Set permission to access external storage",
agreeAction = {
//读写权限通过
agreeAction?.invoke()
}, disAgreeAction = { disAgreeAction?.invoke() }
)
} }
} }
......
...@@ -16,11 +16,13 @@ import com.zxhy.hfilemanagermaster.data.MediaDataC ...@@ -16,11 +16,13 @@ import com.zxhy.hfilemanagermaster.data.MediaDataC
import com.zxhy.hfilemanagermaster.dialog.showLoadingDialog import com.zxhy.hfilemanagermaster.dialog.showLoadingDialog
import com.zxhy.hfilemanagermaster.dialog.showOperationDialog import com.zxhy.hfilemanagermaster.dialog.showOperationDialog
import com.zxhy.hfilemanagermaster.knife.deleteDirectory import com.zxhy.hfilemanagermaster.knife.deleteDirectory
import com.zxhy.hfilemanagermaster.knife.imageFile
import com.zxhy.hfilemanagermaster.knife.largeVideo
import com.zxhy.hfilemanagermaster.knife.toast import com.zxhy.hfilemanagermaster.knife.toast
import com.zxhy.hfilemanagermaster.knife.videoFile import com.zxhy.hfilemanagermaster.knife.videoFile
import com.zxhy.hfilemanagermaster.permission.IntentLauncher
import com.zxhy.hfilemanagermaster.permission.PermissionLauncher
import com.zxhy.hfilemanagermaster.permission.alert import com.zxhy.hfilemanagermaster.permission.alert
import com.zxhy.hfilemanagermaster.permission.requestStoreFollow
import com.zxhy.hfilemanagermaster.permission.storePermissionCheck
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay import kotlinx.coroutines.delay
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
...@@ -31,9 +33,14 @@ class VideoActivity : AppCompatActivity() { ...@@ -31,9 +33,14 @@ class VideoActivity : AppCompatActivity() {
private lateinit var binding: ActivityVideoBinding private lateinit var binding: ActivityVideoBinding
private lateinit var videoAdapter: VideoSelectAdapter private lateinit var videoAdapter: VideoSelectAdapter
private lateinit var loadDialog: Dialog private lateinit var loadDialog: Dialog
private lateinit var intentLauncher: IntentLauncher
private lateinit var permissionLauncher: PermissionLauncher
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
enableEdgeToEdge() enableEdgeToEdge()
intentLauncher = IntentLauncher(this)
permissionLauncher = PermissionLauncher(this)
binding = ActivityVideoBinding.inflate(layoutInflater) binding = ActivityVideoBinding.inflate(layoutInflater)
setContentView(binding.root) setContentView(binding.root)
ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main)) { v, insets -> ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main)) { v, insets ->
...@@ -54,9 +61,11 @@ class VideoActivity : AppCompatActivity() { ...@@ -54,9 +61,11 @@ class VideoActivity : AppCompatActivity() {
binding.rv.layoutManager = GridLayoutManager(this, 3) binding.rv.layoutManager = GridLayoutManager(this, 3)
binding.rv.adapter = videoAdapter binding.rv.adapter = videoAdapter
loadDialog = showLoadingDialog() if (storePermissionCheck()) {
loadVideoData() fileMode()
} else {
lockMode()
}
binding.tvDelete.setOnClickListener { binding.tvDelete.setOnClickListener {
val list = videoAdapter.getSelectFile() val list = videoAdapter.getSelectFile()
...@@ -78,6 +87,31 @@ class VideoActivity : AppCompatActivity() { ...@@ -78,6 +87,31 @@ class VideoActivity : AppCompatActivity() {
} }
} }
private fun lockMode() {
binding.clLock.visibility = View.VISIBLE
binding.clShow.visibility = View.GONE
binding.tvSet.setOnClickListener {
this.requestStoreFollow(
permissionLauncher,
intentLauncher,
disAgreeAction = {
lockMode()
},
agreeAction = {
fileMode()
})
}
}
private fun fileMode() {
binding.clLock.visibility = View.GONE
binding.clShow.visibility = View.VISIBLE
loadDialog = showLoadingDialog()
loadVideoData()
}
private fun deleteFiles(files: List<MediaDataC>) = Thread { private fun deleteFiles(files: List<MediaDataC>) = Thread {
try { try {
files.forEach { files.forEach {
......
...@@ -108,9 +108,9 @@ class VideoSelectAdapter( ...@@ -108,9 +108,9 @@ class VideoSelectAdapter(
@SuppressLint("NotifyDataSetChanged") @SuppressLint("NotifyDataSetChanged")
fun removeData(file: List<MediaDataC>) { fun removeData(file: List<MediaDataC>) {
mediaList.removeAll(file.toSet()) mediaList.removeAll(file.toSet())
file.forEachIndexed { index, mediaDataC -> // file.forEachIndexed { index, mediaDataC ->
Log.e("removeData", "index=$index $mediaDataC") // Log.e("removeData", "index=$index $mediaDataC")
} // }
notifyDataSetChanged() notifyDataSetChanged()
} }
...@@ -119,6 +119,6 @@ class VideoSelectAdapter( ...@@ -119,6 +119,6 @@ class VideoSelectAdapter(
val index = mediaList.size val index = mediaList.size
mediaList.addAll(data) mediaList.addAll(data)
notifyItemRangeChanged(index, data.size) notifyItemRangeChanged(index, data.size)
Log.e("FileSelectorAdapter", mediaList.size.toString()) // Log.e("FileSelectorAdapter", mediaList.size.toString())
} }
} }
\ No newline at end of file
...@@ -82,6 +82,10 @@ class IndicatorView : View { ...@@ -82,6 +82,10 @@ class IndicatorView : View {
// Log.e("IndicatorView", "width=$width height=$height") // Log.e("IndicatorView", "width=$width height=$height")
// 取出最小值 // 取出最小值
val len = min(width, height) val len = min(width, height)
hMargin = len * 0.125f
topMargin = len * 0.075f
//获取半径 //获取半径
radius = len.toFloat() - topMargin radius = len.toFloat() - topMargin
// Log.e("IndicatorView", "radius=$radius") // Log.e("IndicatorView", "radius=$radius")
...@@ -151,7 +155,8 @@ class IndicatorView : View { ...@@ -151,7 +155,8 @@ class IndicatorView : View {
indicatorX = 1f indicatorX = 1f
rotationDegreesOffset = 0f rotationDegreesOffset = 0f
} }
in 100f..119f->{
in 100f..119f -> {
indicatorY = 0.95f indicatorY = 0.95f
indicatorX = 1f indicatorX = 1f
rotationDegreesOffset = 2f rotationDegreesOffset = 2f
......
...@@ -76,7 +76,6 @@ ...@@ -76,7 +76,6 @@
app:layout_constraintRight_toRightOf="parent" app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/cl_top" /> app:layout_constraintTop_toBottomOf="@id/cl_top" />
<TextView <TextView
android:id="@+id/tv_delete" android:id="@+id/tv_delete"
android:layout_width="0dp" android:layout_width="0dp"
...@@ -94,4 +93,67 @@ ...@@ -94,4 +93,67 @@
app:layout_constraintRight_toRightOf="parent" app:layout_constraintRight_toRightOf="parent"
tools:ignore="HardcodedText" /> tools:ignore="HardcodedText" />
<ImageView
android:id="@+id/iv_empty"
android:layout_width="250dp"
android:layout_height="182dp"
android:layout_marginTop="180dp"
android:src="@mipmap/eqwe_8798521"
android:visibility="gone"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/cl_top"
tools:ignore="ContentDescription" />
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/cl_lock"
android:layout_width="match_parent"
android:layout_height="0dp"
android:visibility="invisible"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toBottomOf="@id/cl_top">
<ImageView
android:id="@+id/iv_lock"
android:layout_width="200dp"
android:layout_height="200dp"
android:layout_marginTop="82dp"
android:src="@mipmap/ewq_989752"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:ignore="ContentDescription" />
<TextView
android:id="@+id/tv_tip"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginHorizontal="66dp"
android:layout_marginTop="20dp"
android:text="There are no permissions We need to get permission to read all files."
android:textColor="#999999"
android:textSize="17sp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@+id/iv_lock"
tools:ignore="HardcodedText" />
<TextView
android:id="@+id/tv_set"
android:layout_width="0dp"
android:layout_height="40dp"
android:layout_marginHorizontal="55dp"
android:layout_marginTop="20dp"
android:background="@drawable/bg_rectangle_333333"
android:gravity="center"
android:text="Set"
android:textColor="#FFFFFF"
android:textSize="17sp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/tv_tip"
tools:ignore="HardcodedText" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
...@@ -64,6 +64,57 @@ ...@@ -64,6 +64,57 @@
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/cl_show"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toBottomOf="@id/cl_top">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginHorizontal="20dp"
android:layout_marginVertical="16dp"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
app:layout_constraintBottom_toTopOf="@id/tv_delete"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/tv_delete"
android:layout_width="0dp"
android:layout_height="51dp"
android:layout_marginHorizontal="50dp"
android:layout_marginBottom="45dp"
android:background="@mipmap/lopp_89956"
android:gravity="center"
android:text="Delete"
android:textColor="#FFFFFF"
android:textSize="17sp"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
tools:ignore="HardcodedText" />
<ImageView
android:id="@+id/iv_empty"
android:layout_width="250dp"
android:layout_height="182dp"
android:layout_marginTop="180dp"
android:src="@mipmap/eqwe_8798521"
android:visibility="gone"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:ignore="ContentDescription" />
</androidx.constraintlayout.widget.ConstraintLayout>
<androidx.constraintlayout.widget.ConstraintLayout <androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/cl_lock" android:id="@+id/cl_lock"
android:layout_width="match_parent" android:layout_width="match_parent"
...@@ -115,33 +166,5 @@ ...@@ -115,33 +166,5 @@
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginHorizontal="20dp"
android:layout_marginVertical="16dp"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
app:layout_constraintBottom_toTopOf="@id/tv_delete"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/cl_top" />
<TextView
android:id="@+id/tv_delete"
android:layout_width="0dp"
android:layout_height="51dp"
android:layout_marginHorizontal="50dp"
android:layout_marginBottom="45dp"
android:background="@mipmap/lopp_89956"
android:gravity="center"
android:text="Delete"
android:textColor="#FFFFFF"
android:textSize="17sp"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
tools:ignore="HardcodedText" />
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
...@@ -64,45 +64,107 @@ ...@@ -64,45 +64,107 @@
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>
<androidx.recyclerview.widget.RecyclerView <androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/rv" android:id="@+id/cl_show"
android:layout_width="0dp" android:layout_width="match_parent"
android:layout_height="0dp" android:layout_height="0dp"
android:layout_marginHorizontal="20dp"
android:layout_marginVertical="16dp"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
app:layout_constraintBottom_toTopOf="@id/tv_delete"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/cl_top" />
<TextView
android:id="@+id/tv_delete"
android:layout_width="0dp"
android:layout_height="51dp"
android:layout_marginHorizontal="50dp"
android:layout_marginBottom="45dp"
android:background="@mipmap/lopp_89956"
android:gravity="center"
android:text="Delete"
android:textColor="#FFFFFF"
android:textSize="17sp"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent" app:layout_constraintRight_toRightOf="parent"
tools:ignore="HardcodedText" /> app:layout_constraintTop_toBottomOf="@id/cl_top">
<ImageView <androidx.recyclerview.widget.RecyclerView
android:id="@+id/iv_empty" android:id="@+id/rv"
android:layout_width="250dp" android:layout_width="0dp"
android:layout_height="182dp" android:layout_height="0dp"
android:layout_marginTop="180dp" android:layout_marginHorizontal="20dp"
android:src="@mipmap/eqwe_8798521" android:layout_marginVertical="16dp"
android:visibility="gone" app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintBottom_toTopOf="@id/tv_delete"
app:layout_constraintRight_toRightOf="parent" app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toBottomOf="@id/cl_top" app:layout_constraintRight_toRightOf="parent"
tools:ignore="ContentDescription" /> app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/tv_delete"
android:layout_width="0dp"
android:layout_height="51dp"
android:layout_marginHorizontal="50dp"
android:layout_marginBottom="45dp"
android:background="@mipmap/lopp_89956"
android:gravity="center"
android:text="Delete"
android:textColor="#FFFFFF"
android:textSize="17sp"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
tools:ignore="HardcodedText" />
<ImageView
android:id="@+id/iv_empty"
android:layout_width="250dp"
android:layout_height="182dp"
android:layout_marginTop="180dp"
android:src="@mipmap/eqwe_8798521"
android:visibility="gone"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:ignore="ContentDescription" />
</androidx.constraintlayout.widget.ConstraintLayout>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/cl_lock"
android:layout_width="match_parent"
android:layout_height="0dp"
android:visibility="invisible"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toBottomOf="@id/cl_top">
<ImageView
android:id="@+id/iv_lock"
android:layout_width="200dp"
android:layout_height="200dp"
android:layout_marginTop="82dp"
android:src="@mipmap/ewq_989752"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:ignore="ContentDescription" />
<TextView
android:id="@+id/tv_tip"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginHorizontal="66dp"
android:layout_marginTop="20dp"
android:text="There are no permissions We need to get permission to read all files."
android:textColor="#999999"
android:textSize="17sp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@+id/iv_lock"
tools:ignore="HardcodedText" />
<TextView
android:id="@+id/tv_set"
android:layout_width="0dp"
android:layout_height="40dp"
android:layout_marginHorizontal="55dp"
android:layout_marginTop="20dp"
android:background="@drawable/bg_rectangle_333333"
android:gravity="center"
android:text="Set"
android:textColor="#FFFFFF"
android:textSize="17sp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/tv_tip"
tools:ignore="HardcodedText" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
...@@ -64,45 +64,105 @@ ...@@ -64,45 +64,105 @@
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>
<androidx.recyclerview.widget.RecyclerView <androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/rv" android:id="@+id/cl_show"
android:layout_width="0dp" android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toBottomOf="@id/cl_top">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginHorizontal="20dp"
android:layout_marginVertical="16dp"
app:layout_constraintBottom_toTopOf="@id/tv_delete"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/tv_delete"
android:layout_width="0dp"
android:layout_height="51dp"
android:layout_marginHorizontal="50dp"
android:layout_marginBottom="45dp"
android:background="@mipmap/lopp_89956"
android:gravity="center"
android:text="Delete"
android:textColor="#FFFFFF"
android:textSize="17sp"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
tools:ignore="HardcodedText" />
<ImageView
android:id="@+id/iv_empty"
android:layout_width="250dp"
android:layout_height="182dp"
android:layout_marginTop="180dp"
android:src="@mipmap/eqwe_8798521"
android:visibility="gone"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:ignore="ContentDescription" />
</androidx.constraintlayout.widget.ConstraintLayout>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/cl_lock"
android:layout_width="match_parent"
android:layout_height="0dp" android:layout_height="0dp"
android:layout_marginHorizontal="20dp" android:visibility="invisible"
android:layout_marginVertical="16dp"
app:layout_constraintBottom_toTopOf="@id/tv_delete"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/cl_top" />
<TextView
android:id="@+id/tv_delete"
android:layout_width="0dp"
android:layout_height="51dp"
android:layout_marginHorizontal="50dp"
android:layout_marginBottom="45dp"
android:background="@mipmap/lopp_89956"
android:gravity="center"
android:text="Delete"
android:textColor="#FFFFFF"
android:textSize="17sp"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintTop_toBottomOf="@id/cl_top">
app:layout_constraintRight_toRightOf="parent"
tools:ignore="HardcodedText" /> <ImageView
android:id="@+id/iv_lock"
<ImageView android:layout_width="200dp"
android:id="@+id/iv_empty" android:layout_height="200dp"
android:layout_width="250dp" android:layout_marginTop="82dp"
android:layout_height="182dp" android:src="@mipmap/ewq_989752"
android:layout_marginTop="180dp" app:layout_constraintLeft_toLeftOf="parent"
android:src="@mipmap/eqwe_8798521" app:layout_constraintRight_toRightOf="parent"
android:visibility="gone" app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="parent" tools:ignore="ContentDescription" />
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/cl_top" <TextView
tools:ignore="ContentDescription" /> android:id="@+id/tv_tip"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginHorizontal="66dp"
android:layout_marginTop="20dp"
android:text="There are no permissions We need to get permission to read all files."
android:textColor="#999999"
android:textSize="17sp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@+id/iv_lock"
tools:ignore="HardcodedText" />
<TextView
android:id="@+id/tv_set"
android:layout_width="0dp"
android:layout_height="40dp"
android:layout_marginHorizontal="55dp"
android:layout_marginTop="20dp"
android:background="@drawable/bg_rectangle_333333"
android:gravity="center"
android:text="Set"
android:textColor="#FFFFFF"
android:textSize="17sp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/tv_tip"
tools:ignore="HardcodedText" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
...@@ -146,6 +146,17 @@ ...@@ -146,6 +146,17 @@
app:layout_constraintRight_toRightOf="parent" app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/cl_top"> app:layout_constraintTop_toBottomOf="@id/cl_top">
<TextView
android:id="@+id/tv_dir"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:paddingHorizontal="12dp"
android:textColor="#FF333333"
android:textSize="15sp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.recyclerview.widget.RecyclerView <androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv" android:id="@+id/rv"
android:layout_width="match_parent" android:layout_width="match_parent"
...@@ -153,26 +164,16 @@ ...@@ -153,26 +164,16 @@
android:layout_marginBottom="12dp" android:layout_marginBottom="12dp"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
app:layout_constraintBottom_toTopOf="@id/cl_operation" app:layout_constraintBottom_toTopOf="@id/cl_operation"
app:layout_constraintTop_toTopOf="parent" app:layout_constraintTop_toBottomOf="@id/tv_dir"
tools:listitem="@layout/item_file_select" /> tools:listitem="@layout/item_file_select" />
<ImageView
android:id="@+id/iv_placeholder"
android:layout_width="36dp"
android:layout_height="36dp"
android:layout_marginRight="50dp"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="@id/cl_operation"
tools:ignore="ContentDescription,MissingConstraints,RtlHardcoded" />
<androidx.constraintlayout.widget.ConstraintLayout <androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/cl_operation" android:id="@+id/cl_operation"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginHorizontal="50dp" android:layout_marginHorizontal="50dp"
android:layout_marginBottom="24dp" android:layout_marginBottom="24dp"
android:visibility="invisible" app:layout_constraintBottom_toTopOf="@id/cl_confirm"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent" app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/rv"> app:layout_constraintTop_toBottomOf="@id/rv">
...@@ -273,10 +274,11 @@ ...@@ -273,10 +274,11 @@
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginHorizontal="57dp" android:layout_marginHorizontal="57dp"
android:visibility="invisible" android:layout_marginBottom="24dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent" app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="@id/cl_operation"> app:layout_constraintTop_toBottomOf="@id/cl_operation">
<TextView <TextView
android:id="@+id/tv_cancel" android:id="@+id/tv_cancel"
...@@ -308,6 +310,27 @@ ...@@ -308,6 +310,27 @@
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>
<ImageView
android:id="@+id/iv_empty"
android:layout_width="250dp"
android:layout_height="182dp"
android:layout_marginTop="180dp"
android:src="@mipmap/eqwe_8798521"
android:visibility="gone"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="@id/rv"
tools:ignore="ContentDescription" />
<ImageView
android:id="@+id/iv_placeholder"
android:layout_width="36dp"
android:layout_height="36dp"
android:layout_marginRight="50dp"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="@id/cl_operation"
tools:ignore="ContentDescription,MissingConstraints,RtlHardcoded" />
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
...@@ -65,78 +65,153 @@ ...@@ -65,78 +65,153 @@
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>
<TextView <androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/tv_file" android:id="@+id/cl_show"
android:layout_width="wrap_content" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="0dp"
android:layout_marginLeft="59dp" app:layout_constraintBottom_toBottomOf="parent"
android:layout_marginTop="12dp"
android:text="File"
android:textColor="#333333"
android:textSize="15sp"
android:textStyle="bold"
app:layout_constraintHorizontal_chainStyle="spread_inside"
app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toLeftOf="@id/tv_image"
app:layout_constraintTop_toBottomOf="@id/cl_top"
tools:ignore="HardcodedText,RtlHardcoded" />
<TextView
android:id="@+id/tv_image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Image"
android:textColor="#333333"
android:textSize="15sp"
android:textStyle="bold"
app:layout_constraintLeft_toRightOf="@id/tv_file"
app:layout_constraintRight_toLeftOf="@id/tv_video"
app:layout_constraintTop_toTopOf="@id/tv_file"
tools:ignore="HardcodedText" />
<TextView
android:id="@+id/tv_video"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="59dp"
android:text="Video"
android:textColor="#333333"
android:textSize="15sp"
android:textStyle="bold"
app:layout_constraintLeft_toRightOf="@id/tv_image"
app:layout_constraintRight_toRightOf="parent" app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="@id/tv_file" app:layout_constraintTop_toBottomOf="@id/cl_top">
tools:ignore="HardcodedText,RtlHardcoded" />
<TextView
android:id="@+id/tv_file"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="59dp"
android:layout_marginTop="8dp"
android:text="All"
android:textColor="#333333"
android:textSize="15sp"
android:textStyle="bold"
android:visibility="gone"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toLeftOf="@id/tv_image"
app:layout_constraintTop_toTopOf="parent"
tools:ignore="HardcodedText,RtlHardcoded" />
<TextView
android:id="@+id/tv_image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="Image"
android:textColor="#333333"
android:textSize="15sp"
android:textStyle="bold"
app:layout_constraintLeft_toRightOf="@id/tv_file"
app:layout_constraintRight_toLeftOf="@id/tv_video"
app:layout_constraintTop_toTopOf="@id/tv_file"
tools:ignore="HardcodedText" />
<TextView
android:id="@+id/tv_video"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="Video"
android:textColor="#333333"
android:textSize="15sp"
android:textStyle="bold"
app:layout_constraintLeft_toRightOf="@id/tv_image"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="@id/tv_file"
tools:ignore="HardcodedText,RtlHardcoded" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginHorizontal="0dp"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
app:layout_constraintBottom_toTopOf="@id/tv_delete"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/tv_image"
tools:listitem="@layout/item_media_select" />
<TextView
android:id="@+id/tv_delete"
android:layout_width="0dp"
android:layout_height="51dp"
android:layout_marginHorizontal="50dp"
android:layout_marginBottom="45dp"
android:background="@mipmap/lopp_89956"
android:gravity="center"
android:text="Delete"
android:textColor="#FFFFFF"
android:textSize="17sp"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
tools:ignore="HardcodedText" />
<androidx.recyclerview.widget.RecyclerView <ImageView
android:id="@+id/rv" android:id="@+id/iv_empty"
android:layout_width="0dp" android:layout_width="250dp"
android:layout_height="182dp"
android:layout_marginTop="180dp"
android:src="@mipmap/eqwe_8798521"
android:visibility="gone"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:ignore="ContentDescription" />
</androidx.constraintlayout.widget.ConstraintLayout>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/cl_lock"
android:layout_width="match_parent"
android:layout_height="0dp" android:layout_height="0dp"
android:layout_marginHorizontal="0dp" android:visibility="invisible"
android:layout_marginVertical="16dp"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
app:layout_constraintBottom_toTopOf="@id/tv_delete"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/tv_file"
tools:listitem="@layout/item_media_select" />
<TextView
android:id="@+id/tv_delete"
android:layout_width="0dp"
android:layout_height="51dp"
android:layout_marginHorizontal="50dp"
android:layout_marginBottom="45dp"
android:background="@mipmap/lopp_89956"
android:gravity="center"
android:text="Delete"
android:textColor="#FFFFFF"
android:textSize="17sp"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintTop_toBottomOf="@id/cl_top">
app:layout_constraintRight_toRightOf="parent"
tools:ignore="HardcodedText" /> <ImageView
android:id="@+id/iv_lock"
android:layout_width="200dp"
android:layout_height="200dp"
android:layout_marginTop="82dp"
android:src="@mipmap/ewq_989752"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:ignore="ContentDescription" />
<TextView
android:id="@+id/tv_tip"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginHorizontal="66dp"
android:layout_marginTop="20dp"
android:text="There are no permissions We need to get permission to read all files."
android:textColor="#999999"
android:textSize="17sp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@+id/iv_lock"
tools:ignore="HardcodedText" />
<TextView
android:id="@+id/tv_set"
android:layout_width="0dp"
android:layout_height="40dp"
android:layout_marginHorizontal="55dp"
android:layout_marginTop="20dp"
android:background="@drawable/bg_rectangle_333333"
android:gravity="center"
android:text="Set"
android:textColor="#FFFFFF"
android:textSize="17sp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/tv_tip"
tools:ignore="HardcodedText" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="0dp" android:layout_height="0dp"
app:defaultNavHost="true" app:defaultNavHost="true"
app:layout_constraintBottom_toTopOf="@id/iv_manager" app:layout_constraintBottom_toTopOf="@id/fl_manager"
app:layout_constraintTop_toTopOf="parent" app:layout_constraintTop_toTopOf="parent"
app:navGraph="@navigation/nav" /> app:navGraph="@navigation/nav" />
...@@ -30,8 +30,8 @@ ...@@ -30,8 +30,8 @@
<FrameLayout <FrameLayout
android:id="@+id/fl_manager" android:id="@+id/fl_manager"
android:layout_width="36dp" android:layout_width="84dp"
android:layout_height="36dp" android:layout_height="48dp"
app:layout_constraintBottom_toBottomOf="@id/iv_manager" app:layout_constraintBottom_toBottomOf="@id/iv_manager"
app:layout_constraintLeft_toLeftOf="@id/iv_manager" app:layout_constraintLeft_toLeftOf="@id/iv_manager"
app:layout_constraintRight_toRightOf="@id/iv_manager" app:layout_constraintRight_toRightOf="@id/iv_manager"
...@@ -63,8 +63,8 @@ ...@@ -63,8 +63,8 @@
<FrameLayout <FrameLayout
android:id="@+id/fl_tools" android:id="@+id/fl_tools"
android:layout_width="36dp" android:layout_width="84dp"
android:layout_height="36dp" android:layout_height="48dp"
app:layout_constraintBottom_toBottomOf="@id/iv_tools" app:layout_constraintBottom_toBottomOf="@id/iv_tools"
app:layout_constraintLeft_toLeftOf="@id/iv_tools" app:layout_constraintLeft_toLeftOf="@id/iv_tools"
app:layout_constraintRight_toRightOf="@id/iv_tools" app:layout_constraintRight_toRightOf="@id/iv_tools"
......
...@@ -23,7 +23,7 @@ ...@@ -23,7 +23,7 @@
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent" app:layout_constraintTop_toTopOf="parent"
tools:ignore="RtlHardcoded" /> tools:ignore="ContentDescription,RtlHardcoded" />
<TextView <TextView
android:layout_width="wrap_content" android:layout_width="wrap_content"
...@@ -63,45 +63,107 @@ ...@@ -63,45 +63,107 @@
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>
<androidx.recyclerview.widget.RecyclerView <androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/rv" android:id="@+id/cl_show"
android:layout_width="0dp" android:layout_width="match_parent"
android:layout_height="0dp" android:layout_height="0dp"
android:layout_marginHorizontal="20dp"
android:layout_marginVertical="16dp"
app:layout_constraintBottom_toTopOf="@id/tv_delete"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/cl_top" />
<TextView
android:id="@+id/tv_delete"
android:layout_width="0dp"
android:layout_height="51dp"
android:layout_marginHorizontal="50dp"
android:layout_marginBottom="45dp"
android:background="@mipmap/lopp_89956"
android:gravity="center"
android:text="Delete"
android:textColor="#FFFFFF"
android:textSize="17sp"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent" app:layout_constraintRight_toRightOf="parent"
tools:ignore="HardcodedText" /> app:layout_constraintTop_toBottomOf="@id/cl_top">
<ImageView <androidx.recyclerview.widget.RecyclerView
android:id="@+id/iv_empty" android:id="@+id/rv"
android:layout_width="250dp" android:layout_width="0dp"
android:layout_height="182dp" android:layout_height="0dp"
android:layout_marginTop="180dp" android:layout_marginHorizontal="20dp"
android:src="@mipmap/eqwe_8798521" android:layout_marginVertical="16dp"
android:visibility="gone" app:layout_constraintBottom_toTopOf="@id/tv_delete"
app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent" app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/cl_top" app:layout_constraintTop_toTopOf="parent" />
tools:ignore="ContentDescription" />
<TextView
android:id="@+id/tv_delete"
android:layout_width="0dp"
android:layout_height="51dp"
android:layout_marginHorizontal="50dp"
android:layout_marginBottom="45dp"
android:background="@mipmap/lopp_89956"
android:gravity="center"
android:text="Delete"
android:textColor="#FFFFFF"
android:textSize="17sp"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
tools:ignore="HardcodedText" />
<ImageView
android:id="@+id/iv_empty"
android:layout_width="250dp"
android:layout_height="182dp"
android:layout_marginTop="180dp"
android:src="@mipmap/eqwe_8798521"
android:visibility="gone"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:ignore="ContentDescription" />
</androidx.constraintlayout.widget.ConstraintLayout>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/cl_lock"
android:layout_width="match_parent"
android:layout_height="0dp"
android:visibility="invisible"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toBottomOf="@id/cl_top">
<ImageView
android:id="@+id/iv_lock"
android:layout_width="200dp"
android:layout_height="200dp"
android:layout_marginTop="82dp"
android:src="@mipmap/ewq_989752"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:ignore="ContentDescription" />
<TextView
android:id="@+id/tv_tip"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginHorizontal="66dp"
android:layout_marginTop="20dp"
android:text="There are no permissions We need to get permission to read all files."
android:textColor="#999999"
android:textSize="17sp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@+id/iv_lock"
tools:ignore="HardcodedText" />
<TextView
android:id="@+id/tv_set"
android:layout_width="0dp"
android:layout_height="40dp"
android:layout_marginHorizontal="55dp"
android:layout_marginTop="20dp"
android:background="@drawable/bg_rectangle_333333"
android:gravity="center"
android:text="Set"
android:textColor="#FFFFFF"
android:textSize="17sp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/tv_tip"
tools:ignore="HardcodedText" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
<?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:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@android:color/transparent">
<androidx.cardview.widget.CardView
android:layout_width="250dp"
android:layout_height="228dp"
android:layout_margin="5dp"
app:cardBackgroundColor="#FF1A1A1A"
app:cardCornerRadius="16dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/tv_tittle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:text="New Folder"
android:textColor="#ffffff"
android:textSize="17sp"
android:textStyle="bold"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:ignore="HardcodedText" />
<ImageView
android:id="@+id/iv_cancel"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_margin="5dp"
android:src="@drawable/icon_delete"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:ignore="ContentDescription" />
<ImageView
android:id="@+id/iv_file"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_marginLeft="20dp"
android:layout_marginTop="20dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toBottomOf="@id/tv_tittle"
tools:ignore="ContentDescription,RtlHardcoded" />
<TextView
android:id="@+id/tv_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="12dp"
android:text="name"
android:textColor="#FFFFFFFF"
android:textSize="14sp"
app:layout_constraintLeft_toRightOf="@id/iv_file"
app:layout_constraintTop_toTopOf="@id/iv_file"
tools:ignore="HardcodedText,RtlHardcoded" />
<TextView
android:id="@+id/tv_size"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="20MB"
android:textColor="#CCFFFFFF"
android:textSize="12sp"
app:layout_constraintLeft_toLeftOf="@id/tv_name"
app:layout_constraintTop_toBottomOf="@id/tv_name"
tools:ignore="HardcodedText" />
<TextView
android:id="@+id/tv_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:text="Time:"
android:textColor="#FFFFFFFF"
android:textSize="14sp"
app:layout_constraintLeft_toLeftOf="@id/iv_file"
app:layout_constraintTop_toBottomOf="@id/iv_file"
tools:ignore="HardcodedText" />
<TextView
android:id="@+id/tv_position"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="Position:"
android:textColor="#FFFFFFFF"
android:textSize="14sp"
app:layout_constraintLeft_toLeftOf="@id/iv_file"
app:layout_constraintTop_toBottomOf="@id/tv_time"
tools:ignore="HardcodedText" />
<TextView
android:id="@+id/tv_cancel"
android:layout_width="210dp"
android:layout_height="40dp"
android:layout_marginBottom="8dp"
android:background="@mipmap/ds_0230"
android:gravity="center"
android:text="Sure"
android:textSize="15sp"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
tools:ignore="HardcodedText" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.cardview.widget.CardView>
</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
...@@ -65,6 +65,7 @@ ...@@ -65,6 +65,7 @@
android:hint="Please enter a new name" android:hint="Please enter a new name"
android:singleLine="true" android:singleLine="true"
android:textColor="#CCFFFFFF" android:textColor="#CCFFFFFF"
android:textColorHint="#CCFFFFFF"
android:textSize="14sp" android:textSize="14sp"
app:layout_constraintBottom_toBottomOf="@id/iv_placeholder" app:layout_constraintBottom_toBottomOf="@id/iv_placeholder"
app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintLeft_toLeftOf="parent"
......
...@@ -9,7 +9,15 @@ ...@@ -9,7 +9,15 @@
<dimen name="dp_140">140dp</dimen> <dimen name="dp_140">140dp</dimen>
<dimen name="dp_180">180dp</dimen> <dimen name="dp_180">180dp</dimen>
<dimen name="dp_12">12dp</dimen> <dimen name="dp_12">12dp</dimen>
<dimen name="dp_15">15dp</dimen>
<dimen name="dp_18">18dp</dimen>
<dimen name="dp_25">25dp</dimen>
<dimen name="dp_36">36dp</dimen>
<dimen name="dp_6">6dp</dimen>
<dimen name="dp_9">9dp</dimen>
<dimen name="dp_24">24dp</dimen> <dimen name="dp_24">24dp</dimen>
<dimen name="dp_20">20dp</dimen>
<dimen name="dp_255">255dp</dimen> <dimen name="dp_255">255dp</dimen>
<dimen name="dp_177">177dp</dimen> <dimen name="dp_177">177dp</dimen>
<dimen name="dp_233">233dp</dimen>
</resources> </resources>
\ No newline at end of file
<resources xmlns:tools="http://schemas.android.com/tools"
tools:ignore="MissingDefaultResource">
<paths>
<!-- FileProvide 访问的文件路径 -->
<!-- path 指定路径下的文件夹 -->
<root-path
name="root"
path="." />
<!-- Context.getFilesDir() + “/path/-->
<!-- /data/data/<package-name>/files/path/ -->
<files-path
name="files"
path="." />
<!-- 对应Context.getCacheDir() + “/path/” -->
<!-- data/data/<package-name>/cache/path/ -->
<cache-path
name="cache"
path="." />
<!-- Environment.getExternalStorageDirectory() + “/path/” -->
<!-- /storage/emulated/0/path/ -->
<external-path
name="sdcard"
path="." />
<!-- Context.getExternalFilesDir(null) + “/path/”-->
<!-- /storage/emulated/0/Android/data/<package_name>/files/path/ -->
<external-files-path
name="external_files_path"
path="." />
<!-- Context.getExternalCacheDir() + “/path/” -->
<!-- /storage/emulated/0/Android/data/<package-name>/cache/path/ -->
<external-cache-path
name="external_cache_path"
path="." />
</paths>
</resources>
...@@ -20,4 +20,4 @@ kotlin.code.style=official ...@@ -20,4 +20,4 @@ kotlin.code.style=official
# Enables namespacing of each library's R class so that its R class includes only the # Enables namespacing of each library's R class so that its R class includes only the
# resources declared in the library itself and none from the library's dependencies, # resources declared in the library itself and none from the library's dependencies,
# thereby reducing the size of the R class for that library # thereby reducing the size of the R class for that library
android.nonTransitiveRClass=true android.nonTransitiveRClass=true
\ No newline at end of file
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