Commit fe26db10 authored by wanglei's avatar wanglei

feat:白包版本

parents 904f996d 719c4908
......@@ -3,7 +3,20 @@
<component name="deploymentTargetDropDown">
<value>
<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>
</value>
</component>
......
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<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" />
</component>
</project>
\ No newline at end of file
......@@ -7,6 +7,7 @@ android {
namespace = "com.example.hfilemanagermaster"
compileSdk = 34
defaultConfig {
applicationId = "com.example.hfilemanagermaster"
minSdk = 24
......@@ -17,13 +18,30 @@ android {
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 {
val signConfig = signingConfigs.getByName("keyStore")
release {
isMinifyEnabled = false
isMinifyEnabled = true
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro"
)
signingConfig = signConfig
}
}
buildFeatures {
......@@ -36,6 +54,7 @@ android {
kotlinOptions {
jvmTarget = "1.8"
}
}
dependencies {
......
......@@ -2,16 +2,13 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<uses-permission
android:name="android.permission.READ_EXTERNAL_STORAGE"
android:maxSdkVersion="32" />
<uses-permission
android:name="android.permission.WRITE_EXTERNAL_STORAGE"
android:maxSdkVersion="32"
tools:ignore="ScopedStorage" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission
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_IMAGES"
......@@ -26,6 +23,7 @@
android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:requestLegacyExternalStorage="true"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.HFileManagerMaster"
......@@ -88,6 +86,16 @@
<!-- <category android:name="android.intent.category.LAUNCHER" /> -->
<!-- </intent-filter> -->
</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>
</manifest>
\ No newline at end of file
......@@ -34,7 +34,7 @@ class HLaunchActivity : AppCompatActivity() {
while (i <= 100) {
binding.progressH.progress = i
i++
delay(50)
delay(10)
}
val intent = Intent(this@HLaunchActivity, OverviewActivity::class.java)
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
import com.example.hfilemanagermaster.databinding.ActivityOverviewBinding
import com.zxhy.hfilemanagermaster.permission.IntentLauncher
import com.zxhy.hfilemanagermaster.permission.PermissionLauncher
import com.zxhy.hfilemanagermaster.permission.requestStoreFollow
class OverviewActivity : AppCompatActivity() {
private lateinit var binding: ActivityOverviewBinding
......@@ -70,4 +71,5 @@ class OverviewActivity : AppCompatActivity() {
binding.ivManager.isSelected = false
window.statusBarColor = ContextCompat.getColor(this, R.color.white)
}
}
\ No newline at end of file
......@@ -19,9 +19,11 @@ data class MediaDataC(
val path: String = "",
val md5: String = "",
var select: Boolean = false,
)
var index: Int = 0
) {
}
fun File.file2MediaDataC(context: Context): MediaDataC {
fun File.file2MediaDataC(context: Context, md5: String = ""): MediaDataC {
return try {
val sizeS = Formatter.formatFileSize(context, length())
val timeE = SimpleDateFormat("MMM dd, yyyy", Locale.ENGLISH).format(lastModified())
......@@ -29,7 +31,8 @@ fun File.file2MediaDataC(context: Context): MediaDataC {
name = name,
size = sizeS,
time = timeE,
path = absolutePath
path = absolutePath,
md5 = md5
)
} catch (e: Exception) {
MediaDataC()
......
package com.zxhy.hfilemanagermaster.dialog
import android.annotation.SuppressLint
import android.content.Context
import android.text.format.Formatter
import android.view.LayoutInflater
import androidx.appcompat.app.AlertDialog
import com.example.hfilemanagermaster.R
import com.example.hfilemanagermaster.databinding.DialogFileDetailsBinding
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(
tittle: String = "",
......@@ -26,6 +33,7 @@ fun Context.showFileNameDialog(
binding.tvTittle.text = tittle
binding.tvSure.setOnClickListener {
dialog.dismiss()
sureAction.invoke(binding.etName.text.toString())
}
binding.ivCancel.setOnClickListener {
......@@ -34,3 +42,72 @@ fun Context.showFileNameDialog(
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(
binding.tv.text = tips
dialog.setOnCancelListener { dismissAction.invoke() }
return dialog
}
\ No newline at end of file
}
......@@ -12,6 +12,7 @@ import com.zxhy.hfilemanagermaster.data.DupImageData
import com.zxhy.hfilemanagermaster.data.MediaDataC
import com.zxhy.hfilemanagermaster.glide.loadIntoImageView
import com.zxhy.hfilemanagermaster.knife.inflate
import java.io.File
class DupImageAdapter(
private val selectAction: ((flag: Boolean) -> Unit)? = null
......@@ -34,7 +35,7 @@ class DupImageAdapter(
@SuppressLint("SetTextI18n")
override fun onBindViewHolder(holder: DupImageVideHolder, position: Int) {
val context = holder.binding.root.context
// val context = holder.binding.root.context
val data = dupImageList[position]
holder.binding.apply {
......@@ -73,7 +74,7 @@ class DupImageAdapter(
payloads: MutableList<Any>
) {
val context = holder.binding.root.context
// val context = holder.binding.root.context
val data = dupImageList[position]
//判断是做局部刷新还是单条刷新
if (payloads.isEmpty()) {//局部刷新
......@@ -179,7 +180,7 @@ private class DupImageItemAdapter(
val context = holder.binding.root.context
val data = mediaList[position]
holder.binding.apply {
loadIntoImageView(context, data.uri, ivImage)
loadIntoImageView(context, File(data.path), ivImage)
ivSelector.isSelected = data.select
ivSelector.setOnClickListener {
data.select = !data.select
......@@ -201,7 +202,7 @@ private class DupImageItemAdapter(
//判断是做局部刷新还是单条刷新
if (payloads.isEmpty()) {//局部刷新
holder.binding.apply {
loadIntoImageView(context, data.uri, ivImage)
loadIntoImageView(context, File(data.path), ivImage)
ivSelector.isSelected = data.select
ivSelector.setOnClickListener {
data.select = !data.select
......
package com.zxhy.hfilemanagermaster.duplicate
import android.app.AlertDialog
import android.app.Dialog
import android.os.Bundle
import android.view.View
import androidx.activity.enableEdgeToEdge
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat
......@@ -12,12 +12,18 @@ import androidx.lifecycle.lifecycleScope
import com.example.hfilemanagermaster.R
import com.example.hfilemanagermaster.databinding.ActivityDupPictureBinding
import com.zxhy.hfilemanagermaster.data.DupImageData
import com.zxhy.hfilemanagermaster.dialog.showLoadingDialog
import com.zxhy.hfilemanagermaster.dialog.showOperationDialog
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.toast
import com.zxhy.hfilemanagermaster.permission.IntentLauncher
import com.zxhy.hfilemanagermaster.permission.PermissionLauncher
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.delay
import kotlinx.coroutines.launch
......@@ -26,9 +32,14 @@ import java.io.File
class DupPictureActivity : AppCompatActivity() {
private lateinit var binding: ActivityDupPictureBinding
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?) {
super.onCreate(savedInstanceState)
enableEdgeToEdge()
intentLauncher = IntentLauncher(this)
permissionLauncher = PermissionLauncher(this)
binding = ActivityDupPictureBinding.inflate(layoutInflater)
setContentView(binding.root)
ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main)) { v, insets ->
......@@ -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()
}
......@@ -95,16 +140,34 @@ class DupPictureActivity : AppCompatActivity() {
}.start()
private fun loadData() {
dialog.show()
lifecycleScope.launch(Dispatchers.IO) {
val list = dupImage()
val list = dupImageStore()
val dupDataList = arrayListOf<DupImageData>()
val dupList = getDupImageList(list)
dupList.forEach {
dupDataList.add(DupImageData(dupList = it))
}
lifecycleScope.launch(Dispatchers.Main) {
dialog.dismiss()
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
import android.Manifest
import android.app.Dialog
import android.net.Uri
import android.os.Build
import android.os.Bundle
......@@ -13,6 +15,8 @@ import androidx.core.view.WindowInsetsCompat
import androidx.lifecycle.lifecycleScope
import com.example.hfilemanagermaster.R
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.knife.deleteDirectory
import com.zxhy.hfilemanagermaster.knife.emptyFile
......@@ -21,7 +25,7 @@ import com.zxhy.hfilemanagermaster.permission.IntentLauncher
import com.zxhy.hfilemanagermaster.permission.PermissionLauncher
import com.zxhy.hfilemanagermaster.permission.alert
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.delay
import kotlinx.coroutines.launch
......@@ -33,6 +37,7 @@ class EmptyFileActivity : AppCompatActivity() {
private lateinit var intentLauncher: IntentLauncher
private lateinit var permissionLauncher: PermissionLauncher
private lateinit var emptyFileAdapter: EmptyFileAdapter
private lateinit var loadDialog: Dialog
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enableEdgeToEdge()
......@@ -50,65 +55,47 @@ class EmptyFileActivity : AppCompatActivity() {
finish()
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
if (Environment.isExternalStorageManager()) {
fileMode()
} else {
lockMode()
}
} else {
if (storePermissionCheck()) {
fileMode()
} else {
lockMode()
}
}
private fun loadEmptyFile() = Thread {
val list = emptyFile(this)
runOnUiThread {
emptyFileAdapter.setData(list)
}
}.start()
private fun loadEmptyFile() {
loadDialog.show()
emptyFile(
this,
onDoAction = { list ->
runOnUiThread {
loadDialog.dismiss()
emptyFileAdapter.addData(list)
}
})
}
private fun lockMode() {
binding.clLock.visibility = View.VISIBLE
binding.rv.visibility = View.INVISIBLE
binding.ivAll.visibility = View.GONE
binding.tvAll.visibility = View.GONE
binding.clShow.visibility = View.GONE
binding.tvSet.setOnClickListener {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
if (!Environment.isExternalStorageManager()) {
val uri = Uri.parse("package:$packageName")
val intent = settingManageExternalStorage(uri)
intentLauncher.launch(intent) {
val flag = Environment.isExternalStorageManager()
if (flag) {
fileMode()
// toast("已设置额外储存管理")
} else {
// toast("未设置额外储存管理")
lockMode()
}
}
} else {
// toast("已设置额外储存管理")
this.requestStoreFollow(
permissionLauncher,
intentLauncher,
disAgreeAction = {
lockMode()
},
agreeAction = {
fileMode()
}
} else {
requestStoreFollow(permissionLauncher, intentLauncher) { 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.clShow.visibility = View.VISIBLE
emptyFileAdapter = EmptyFileAdapter {
binding.ivAll.isSelected = it
......@@ -125,8 +112,7 @@ class EmptyFileActivity : AppCompatActivity() {
"Delete Confirm"
) {
positiveButton("confirm") { dialog ->
val fileList = list.map { File(it.path) }
deleteFiles(fileList)
deleteFiles(list)
dialog.dismiss()
}
negativeButton("cancel") { dialog ->
......@@ -136,24 +122,25 @@ class EmptyFileActivity : AppCompatActivity() {
isCancel(false)
}
}
loadDialog = showLoadingDialog()
loadEmptyFile()
}
private fun deleteFiles(files: List<File>) = Thread {
private fun deleteFiles(files: List<MediaDataC>) = Thread {
try {
files.forEach {
if (it.exists()) {
if (it.isFile) it.delete() else deleteDirectory(it)
val file = File(it.path)
if (file.exists()) {
if (file.isFile) file.delete() else deleteDirectory(file)
}
}
runOnUiThread {
lifecycleScope.launch(Dispatchers.Main) {
val dialog = showOperationDialog(R.mipmap.dads_889562, "delete success!") {}
delay(200)
dialog.dismiss()
}
lifecycleScope.launch(Dispatchers.Main) {
val dialog = showOperationDialog(R.mipmap.dads_889562, "delete success!") {}
delay(200)
dialog.dismiss()
emptyFileAdapter.removeData(files)
}
loadEmptyFile()
} catch (e: Exception) {
e.printStackTrace()
runOnUiThread {
......
package com.zxhy.hfilemanagermaster.emptyfile
import android.annotation.SuppressLint
import android.util.Log
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
......@@ -9,6 +10,7 @@ import com.example.hfilemanagermaster.databinding.ItemMediaSelectBinding
import com.zxhy.hfilemanagermaster.data.MediaDataC
import com.zxhy.hfilemanagermaster.glide.loadIntoImageView
import com.zxhy.hfilemanagermaster.knife.inflate
import java.io.File
class EmptyFileAdapter(
private val selectAction: ((flag: Boolean) -> Unit)? = null
......@@ -34,7 +36,32 @@ class EmptyFileAdapter(
val data = mediaList[position]
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
tvSize.text = data.size
......@@ -60,7 +87,34 @@ class EmptyFileAdapter(
//判断是做局部刷新还是单条刷新
if (payloads.isEmpty()) {//局部刷新
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
tvSize.text = data.size
......@@ -107,4 +161,22 @@ class EmptyFileAdapter(
fun getSelectFile(): List<MediaDataC> {
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
import com.zxhy.hfilemanagermaster.knife.apkFile
import com.zxhy.hfilemanagermaster.knife.audioFile
import com.zxhy.hfilemanagermaster.knife.deleteDirectory
import com.zxhy.hfilemanagermaster.knife.documentFile
import com.zxhy.hfilemanagermaster.knife.excelFile
import com.zxhy.hfilemanagermaster.knife.logFile
import com.zxhy.hfilemanagermaster.knife.pdfFile
......@@ -24,7 +25,11 @@ import com.zxhy.hfilemanagermaster.knife.pptFile
import com.zxhy.hfilemanagermaster.knife.toast
import com.zxhy.hfilemanagermaster.knife.wordFile
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.requestStoreFollow
import com.zxhy.hfilemanagermaster.permission.storePermissionCheck
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
......@@ -35,9 +40,14 @@ class FileBrowseActivity : AppCompatActivity() {
private var tittle = ""
private lateinit var fileSelectAdapter: FileSelectorAdapter
private lateinit var loadDialog: Dialog
private lateinit var intentLauncher: IntentLauncher
private lateinit var permissionLauncher: PermissionLauncher
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enableEdgeToEdge()
intentLauncher = IntentLauncher(this)
permissionLauncher = PermissionLauncher(this)
binding = ActivityFileBrowseBinding.inflate(layoutInflater)
setContentView(binding.root)
ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main)) { v, insets ->
......@@ -78,9 +88,40 @@ class FileBrowseActivity : AppCompatActivity() {
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()
loadData()
}
private fun loadData() {
......@@ -191,13 +232,25 @@ class FileBrowseActivity : AppCompatActivity() {
loadDialog.dismiss()
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 {
try {
files.forEach {
val file =File(it.path)
val file = File(it.path)
if (file.exists()) {
if (file.isFile) file.delete() else deleteDirectory(file)
}
......
......@@ -55,12 +55,15 @@ class FileSelectorAdapter(
iv.setImageResource(R.mipmap.fe_98856)
} else if (data.path.contains(".zip")) {
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)
} else {
} else if (File(data.path).isDirectory) {
iv.setImageResource(R.mipmap.tt_695)
} else {
iv.setImageResource(R.drawable.icon_file_unknown)
}
tvName.text = data.name
tvSize.text = data.size
ivSelector.isSelected = data.select
......@@ -104,12 +107,15 @@ class FileSelectorAdapter(
iv.setImageResource(R.mipmap.fe_98856)
} else if (data.path.contains(".zip")) {
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)
} else {
} else if (File(data.path).isDirectory) {
iv.setImageResource(R.mipmap.tt_695)
} else {
iv.setImageResource(R.drawable.icon_file_unknown)
}
tvName.text = data.name
tvSize.text = data.size
ivSelector.isSelected = data.select
......@@ -142,9 +148,9 @@ class FileSelectorAdapter(
@SuppressLint("NotifyDataSetChanged")
fun removeData(file: List<MediaDataC>) {
mediaList.removeAll(file.toSet())
file.forEachIndexed { index, mediaDataC ->
Log.e("removeData", "index=$index $mediaDataC")
}
// file.forEachIndexed { index, mediaDataC ->
// Log.e("removeData", "index=$index $mediaDataC")
// }
notifyDataSetChanged()
}
......@@ -153,7 +159,7 @@ class FileSelectorAdapter(
val index = mediaList.size
mediaList.addAll(data)
notifyItemRangeChanged(index, data.size)
Log.e("FileSelectorAdapter", mediaList.size.toString())
// Log.e("FileSelectorAdapter", mediaList.size.toString())
}
......
......@@ -100,7 +100,7 @@ class FilesFragment : Fragment() {
companion object {
@JvmStatic
fun newInstance(param1: String, param2: String) =
fun newInstance() =
FilesFragment().apply {
arguments = Bundle().apply {
}
......
......@@ -10,12 +10,14 @@ import java.net.URI
fun loadIntoImageView(context: Context, uri: String, imageView: ImageView) {
Glide.with(context)
.load(uri)
.centerCrop()
.into(imageView)
}
fun loadIntoImageView(context: Context, file: File, imageView: ImageView) {
Glide.with(context)
.load(file)
.centerCrop()
.into(imageView)
}
......
......@@ -19,7 +19,11 @@ import com.zxhy.hfilemanagermaster.dialog.showOperationDialog
import com.zxhy.hfilemanagermaster.knife.deleteDirectory
import com.zxhy.hfilemanagermaster.knife.imageFile
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.requestStoreFollow
import com.zxhy.hfilemanagermaster.permission.storePermissionCheck
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
......@@ -30,10 +34,14 @@ class ImageActivity : AppCompatActivity() {
private lateinit var binding: ActivityImageBinding
private lateinit var imageAdapter: ImageSelectAdapter2
private lateinit var loadDialog: Dialog
private lateinit var intentLauncher: IntentLauncher
private lateinit var permissionLauncher: PermissionLauncher
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enableEdgeToEdge()
intentLauncher = IntentLauncher(this)
permissionLauncher = PermissionLauncher(this)
binding = ActivityImageBinding.inflate(layoutInflater)
setContentView(binding.root)
imageAdapter = ImageSelectAdapter2()
......@@ -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()
loadImageData()
}
......@@ -96,7 +133,7 @@ class ImageActivity : AppCompatActivity() {
private fun deleteFiles(files: List<MediaDataC>) = Thread {
try {
files.forEach {
val file =File(it.path)
val file = File(it.path)
if (file.exists()) {
if (file.isFile) file.delete() else deleteDirectory(file)
}
......
......@@ -101,7 +101,7 @@ class ImageSelectAdapter2(
val index = mediaList.size
mediaList.addAll(data)
notifyItemRangeChanged(index, data.size)
Log.e("FileSelectorAdapter", mediaList.size.toString())
// Log.e("FileSelectorAdapter", mediaList.size.toString())
}
fun getSelectSize(): Int {
......@@ -115,9 +115,9 @@ class ImageSelectAdapter2(
@SuppressLint("NotifyDataSetChanged")
fun removeData(file: List<MediaDataC>) {
mediaList.removeAll(file.toSet())
file.forEachIndexed { index, mediaDataC ->
Log.e("removeData", "index=$index $mediaDataC")
}
// file.forEachIndexed { index, mediaDataC ->
// Log.e("removeData", "index=$index $mediaDataC")
// }
notifyDataSetChanged()
}
}
\ No newline at end of file
......@@ -2,6 +2,8 @@ package com.zxhy.hfilemanagermaster.internalstorage
import android.annotation.SuppressLint
import android.content.Context
import android.os.Environment
import android.util.Log
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
......@@ -14,11 +16,13 @@ import com.zxhy.hfilemanagermaster.knife.inflate
import java.io.File
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>() {
private val mediaList = arrayListOf<MediaDataC>()
private var isSelect = false
// private var currentDir: File? = null
private var currentDir: File = Environment.getExternalStorageDirectory()
class FileSelectViewHolder(view: View) : RecyclerView.ViewHolder(view) {
val binding = ItemFileSelectBinding.bind(view)
......@@ -56,8 +60,16 @@ class FileAdapter(
iv.setImageResource(R.mipmap.io_0012)
} else if (data.path.contains(".ppt") or data.path.contains(".pptx")) {
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)
} else {
iv.setImageResource(R.drawable.icon_file_unknown)
}
tvName.text = data.name
......@@ -106,10 +118,17 @@ class FileAdapter(
iv.setImageResource(R.mipmap.io_0012)
} else if (data.path.contains(".ppt") or data.path.contains(".pptx")) {
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)
} else {
iv.setImageResource(R.drawable.icon_file_unknown)
}
tvName.text = data.name
tvSize.text = data.size
ivSelector.isSelected = data.select
......@@ -162,18 +181,21 @@ class FileAdapter(
val subList = file.listFiles()
val subData = subList?.map { it.file2MediaDataC(context) } ?: listOf()
setData(subData)
nextPageAction?.invoke(file)
currentDir = file
}
}
fun beforePage(context: Context): Boolean {
val file = File(mediaList.first().path).parentFile?.parentFile
if (file != null && file.exists()) {
if (file.isDirectory) {
val subList = file.listFiles()
if (subList.isNullOrEmpty()) return false
val subData = subList.map { it.file2MediaDataC(context) }
setData(subData)
}
// Log.e("beforePage", "$currentDir")
val parentDir = currentDir.parentFile ?: File("")
if (parentDir.exists() && parentDir.isDirectory) {
val subList = parentDir.listFiles()
if (subList.isNullOrEmpty()) return false
val subData = subList.map { it.file2MediaDataC(context) }
setData(subData)
beforePageAction?.invoke(parentDir)
currentDir = parentDir
return true
} else {
return false
......@@ -196,15 +218,40 @@ class FileAdapter(
return mediaList.filter { it.select }
}
fun getSelectFileIndex(): List<MediaDataC> {
return mediaList.filterIndexed { index, mediaDataC ->
mediaDataC.index = index
mediaDataC.select
}
}
fun getCurrentDir(): File? {
val dir = File(mediaList[0].path).parentFile
return dir
fun getCurrentDir(): File {
return currentDir
}
fun notifyCurrentDir(context: Context) {
val dir = File(mediaList[0].path).parentFile
val data = dir?.listFiles()?.map { it.file2MediaDataC(context) } ?: listOf()
val data = currentDir.listFiles()?.map { it.file2MediaDataC(context) } ?: listOf()
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
......@@ -4,13 +4,15 @@ import android.content.ContentResolver
import android.content.ContentUris
import android.content.Context
import android.database.Cursor
import android.os.Environment
import android.provider.MediaStore
import com.zxhy.hfilemanagermaster.data.MediaDataC
import com.zxhy.hfilemanagermaster.data.file2MediaDataC
import java.io.File
import java.text.SimpleDateFormat
import java.util.Locale
fun Context.dupImage(): ArrayList<MediaDataC> {
fun Context.dupImageMedia(): ArrayList<MediaDataC> {
val list = arrayListOf<MediaDataC>()
var cursor: Cursor? = null
// 查询照片的Uri和字段
......@@ -29,8 +31,8 @@ fun Context.dupImage(): ArrayList<MediaDataC> {
do {
// 获取照片的ID和名称
val id = cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.Images.Media._ID))
val name =
cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DISPLAY_NAME))
// val name =
// cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DISPLAY_NAME))
// 根据ID构建照片的Uri
val photoUri = ContentUris.withAppendedId(uri, id)
......@@ -57,6 +59,20 @@ fun Context.dupImage(): ArrayList<MediaDataC> {
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>> {
val dupList = arrayListOf<List<MediaDataC>>()
......
......@@ -22,21 +22,68 @@ fun traverseFolder(folder: File): ArrayList<File> {
return fileList
}
fun traverseEmptyFolder(folder: File): ArrayList<File> {
val fileList = arrayListOf<File>()
val emptyFile = arrayListOf<File>()
fun traverseLargeFolder(folder: File, onDo: ((file: File) -> Unit)? = null) {
folder.listFiles()?.forEach {
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 {
if (it.length() == 0L) {
emptyFile.add(it)
onDo?.invoke(it)
}
}
}
return emptyFile
}
fun traverseImageFolder(folder: File, onDo: ((file: File) -> Unit)? = null) {
folder.listFiles()?.forEach {
......@@ -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 {
val stackFiles = Stack<File>()
......@@ -218,27 +288,112 @@ fun deleteDirectory(dir: File): Boolean {
return true
}
fun emptyFile(context: Context): ArrayList<MediaDataC> {
val list = arrayListOf<MediaDataC>()
fun largeFile(
context: Context,
onDoAction: (list: List<MediaDataC>) -> Unit,
finishAction: (() -> Unit)? = null
) {
try {
val file1 = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM)
val data = traverseEmptyFolder(file1)
list.addAll(data.map { it.file2MediaDataC(context) })
Thread {
val root = Environment.getExternalStorageDirectory()
val tempList = arrayListOf<File>()
val file2 = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS)
list.addAll(traverseEmptyFolder(file2).map { it.file2MediaDataC(context) })
traverseLargeFolder(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 file3 = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)
list.addAll(traverseEmptyFolder(file3).map { it.file2MediaDataC(context) })
} catch (e: Exception) {
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) {
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(
......@@ -499,6 +654,32 @@ fun logFile(
finishAction?.invoke()
}.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) {
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> {
do {
// 获取照片的ID和名称
val id = cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.Images.Media._ID))
val name =
cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DISPLAY_NAME))
// val name =
// cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DISPLAY_NAME))
// 根据ID构建照片的Uri
val photoUri = ContentUris.withAppendedId(uri, id)
......@@ -83,8 +83,8 @@ fun Context.largePhoto(): ArrayList<MediaDataC> {
do {
// 获取照片的ID和名称
val id = cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.Images.Media._ID))
val name =
cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DISPLAY_NAME))
// val name =
// cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DISPLAY_NAME))
// 根据ID构建照片的Uri
val photoUri = ContentUris.withAppendedId(uri, id)
......@@ -109,70 +109,70 @@ fun Context.largePhoto(): ArrayList<MediaDataC> {
return list
}
@SuppressLint("SimpleDateFormat")
fun Context.largeVideo(): ArrayList<MediaDataC> {
val list = arrayListOf<MediaDataC>()
var cursor: Cursor? = null
// 查询视频的Uri和字段
val uri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI
val projection = arrayOf(
MediaStore.Video.Media._ID,
MediaStore.Video.Media.DISPLAY_NAME,
MediaStore.Video.Media.SIZE,
)
try {
// 执行查询
val contentResolver: ContentResolver = contentResolver
cursor = contentResolver.query(uri, projection, null, null, null)
// 遍历结果
if (cursor != null && cursor.moveToFirst()) {
do {
// 获取视频的ID
val id = cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.Video.Media._ID))
//名称
val name =
cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Video.Media.DISPLAY_NAME))
//大小
val size =
cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.Video.Media.SIZE))
val sizeS = Formatter.formatFileSize(this, size)
// 根据ID构建视频的Uri
val videoUri = ContentUris.withAppendedId(uri, id)
//时间
val filePath = getFilePathByUri(this, videoUri) ?: ""
val time = File(filePath).lastModified()
// val timeS =
// SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(time)
val timeE = SimpleDateFormat("MMM dd, yyyy", Locale.ENGLISH).format(time)
list.add(
MediaDataC(
name = name,
size = sizeS,
time = timeE,
MediaDataC_TYPE_VIDEO,
uri = videoUri,
path = filePath
)
)
// 在此处进行视频的操作,例如显示、复制、删除等
// ...
if (list.size == 10) {
break
}
} while (cursor.moveToNext())
} else {
println("无数据")
}
} catch (e: Exception) {
e.printStackTrace()
} finally {
cursor?.close()
}
return list
}
//@SuppressLint("SimpleDateFormat")
//fun Context.largeVideo(): ArrayList<MediaDataC> {
// val list = arrayListOf<MediaDataC>()
// var cursor: Cursor? = null
// // 查询视频的Uri和字段
// val uri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI
// val projection = arrayOf(
// MediaStore.Video.Media._ID,
// MediaStore.Video.Media.DISPLAY_NAME,
// MediaStore.Video.Media.SIZE,
// )
// try {
// // 执行查询
// val contentResolver: ContentResolver = contentResolver
// cursor = contentResolver.query(uri, projection, null, null, null)
//
// // 遍历结果
// if (cursor != null && cursor.moveToFirst()) {
// do {
// // 获取视频的ID
// val id = cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.Video.Media._ID))
// //名称
// val name =
// cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Video.Media.DISPLAY_NAME))
// //大小
// val size =
// cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.Video.Media.SIZE))
// val sizeS = Formatter.formatFileSize(this, size)
//
// // 根据ID构建视频的Uri
// val videoUri = ContentUris.withAppendedId(uri, id)
//
// //时间
// val filePath = getFilePathByUri(this, videoUri) ?: ""
// val time = File(filePath).lastModified()
//// val timeS =
//// SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(time)
// val timeE = SimpleDateFormat("MMM dd, yyyy", Locale.ENGLISH).format(time)
// list.add(
// MediaDataC(
// name = name,
// size = sizeS,
// time = timeE,
// MediaDataC_TYPE_VIDEO,
// uri = videoUri,
// path = filePath
// )
// )
// // 在此处进行视频的操作,例如显示、复制、删除等
// // ...
// if (list.size == 10) {
// break
// }
// } while (cursor.moveToNext())
// } else {
// println("无数据")
// }
// } catch (e: Exception) {
// e.printStackTrace()
// } finally {
// cursor?.close()
// }
// return list
//}
//无效
fun getMediaCreateTime(videoPath: String) {
......
package com.zxhy.hfilemanagermaster.largefile
import android.annotation.SuppressLint
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
......@@ -10,6 +11,7 @@ import com.example.hfilemanagermaster.databinding.ItemMediaSelectBinding
import com.zxhy.hfilemanagermaster.data.MediaDataC
import com.zxhy.hfilemanagermaster.glide.loadIntoImageView
import com.zxhy.hfilemanagermaster.knife.inflate
import java.io.File
class LagerFileSelectorAdapter(
private val selectAction: ((flag: Boolean) -> Unit)? = null
......@@ -34,7 +36,32 @@ class LagerFileSelectorAdapter(
val data = mediaList[position]
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
tvSize.text = data.size
......@@ -60,7 +87,32 @@ class LagerFileSelectorAdapter(
//判断是做局部刷新还是单条刷新
if (payloads.isEmpty()) {//局部刷新
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
tvSize.text = data.size
......@@ -108,4 +160,22 @@ class LagerFileSelectorAdapter(
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
import android.app.Dialog
import android.os.Bundle
import android.view.View
import androidx.activity.enableEdgeToEdge
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat
......@@ -12,12 +14,21 @@ import androidx.recyclerview.widget.LinearLayoutManager
import com.example.hfilemanagermaster.R
import com.example.hfilemanagermaster.databinding.ActivityLargeFileBinding
import com.zxhy.hfilemanagermaster.data.MediaDataC
import com.zxhy.hfilemanagermaster.dialog.showLoadingDialog
import com.zxhy.hfilemanagermaster.dialog.showOperationDialog
import com.zxhy.hfilemanagermaster.emptyfile.EmptyFileAdapter
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.largeVideo
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.requestStoreFollow
import com.zxhy.hfilemanagermaster.permission.storePermissionCheck
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
......@@ -28,11 +39,15 @@ class LargeFileActivity : AppCompatActivity() {
private lateinit var mediaSelectAdapter: LagerFileSelectorAdapter
private lateinit var imageSelectorAdapter: LargeImageSelectorAdapter
private lateinit var videoSelectorAdapter: LargeVideoSelectorAdapter
private lateinit var permissionLauncher: PermissionLauncher
private lateinit var intentLauncher: IntentLauncher
private var currentMode = 0//0 文件 1图片 2视频
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enableEdgeToEdge()
intentLauncher = IntentLauncher(this)
permissionLauncher = PermissionLauncher(this)
binding = ActivityLargeFileBinding.inflate(layoutInflater)
setContentView(binding.root)
ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main)) { v, insets ->
......@@ -56,8 +71,7 @@ class LargeFileActivity : AppCompatActivity() {
if (num == 0) return@setOnClickListener
this.alert("Currently selected $num items, are you sure to delete them") {
positiveButton("confirm") { dialog ->
val files = list.map { File(it.path) }
deleteFiles(files)
deleteFiles(list)
dialog.dismiss()
}
negativeButton("cancel") { dialog ->
......@@ -66,6 +80,8 @@ class LargeFileActivity : AppCompatActivity() {
//禁止取消
isCancel(false)
}
}
binding.ivAll.setOnClickListener { view ->
when (currentMode) {
......@@ -75,21 +91,50 @@ class LargeFileActivity : AppCompatActivity() {
}
}
fileMode()
binding.tvFile.setOnClickListener {
fileMode()
if (currentMode != 0)
fileMode()
}
binding.tvImage.setOnClickListener {
imageMode()
if (currentMode != 1)
imageMode()
}
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() {
binding.clLock.visibility = View.GONE
binding.clShow.visibility = View.VISIBLE
currentMode = 0
binding.tvFile.setTextColor(ContextCompat.getColor(this, R.color.color_333333))
binding.tvImage.setTextColor(ContextCompat.getColor(this, R.color.color_999999))
......@@ -105,12 +150,17 @@ class LargeFileActivity : AppCompatActivity() {
}
private fun loadLargeFileData() {
lifecycleScope.launch(Dispatchers.IO) {
val list = this@LargeFileActivity.largeVideo()
lifecycleScope.launch(Dispatchers.Main) {
mediaSelectAdapter.setData(list)
}
}
val loadDialog = showLoadingDialog()
largeFile(this,
onDoAction = { list ->
runOnUiThread {
loadDialog.dismiss()
mediaSelectAdapter.addData(list)
}
}, finishAction = {
loadDialog.dismiss()
runOnUiThread { isEmptyUi() }
})
}
private fun imageMode() {
......@@ -128,12 +178,20 @@ class LargeFileActivity : AppCompatActivity() {
}
private fun loadLargeImageData() {
lifecycleScope.launch(Dispatchers.IO) {
val list = this@LargeFileActivity.largePhoto()
lifecycleScope.launch(Dispatchers.Main) {
imageSelectorAdapter.setData(list)
}
}
val loadDialog = showLoadingDialog()
largeImage(
this,
onDoAction = { list ->
runOnUiThread {
loadDialog.dismiss()
imageSelectorAdapter.addData(list)
}
}, finishAction = {
runOnUiThread {
loadDialog.dismiss()
isEmptyUi()
}
})
}
private fun videoMode() {
......@@ -153,19 +211,29 @@ class LargeFileActivity : AppCompatActivity() {
}
private fun loadLargeVideoData() {
lifecycleScope.launch(Dispatchers.IO) {
val list = this@LargeFileActivity.largeVideo()
lifecycleScope.launch(Dispatchers.Main) {
videoSelectorAdapter.setData(list)
}
}
val loadDialog = showLoadingDialog()
largeVideo(
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 {
files.forEach {
if (it.exists()) {
if (it.isFile) it.delete() else deleteDirectory(it)
val file = File(it.path)
if (file.exists()) {
if (file.isFile) file.delete() else deleteDirectory(file)
}
}
runOnUiThread {
......@@ -173,13 +241,16 @@ class LargeFileActivity : AppCompatActivity() {
val dialog = showOperationDialog(R.mipmap.dads_889562, "delete success!") {}
delay(200)
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) {
e.printStackTrace()
runOnUiThread {
......@@ -187,4 +258,24 @@ class LargeFileActivity : AppCompatActivity() {
}
}
}.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() {
companion object {
@JvmStatic
fun newInstance(param1: String, param2: String) =
fun newInstance() =
LargeFileFragment().apply {
arguments = Bundle().apply {}
}
......
package com.zxhy.hfilemanagermaster.largefile
import android.annotation.SuppressLint
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
......@@ -10,6 +11,7 @@ import com.example.hfilemanagermaster.databinding.ItemImageSelectBinding
import com.zxhy.hfilemanagermaster.data.MediaDataC
import com.zxhy.hfilemanagermaster.glide.loadIntoImageView
import com.zxhy.hfilemanagermaster.knife.inflate
import java.io.File
class LargeImageSelectorAdapter(
private val selectAction: ((flag: Boolean) -> Unit)? = null
......@@ -35,7 +37,7 @@ class LargeImageSelectorAdapter(
val context = holder.binding.root.context
val data = mediaList[position]
holder.binding.apply {
loadIntoImageView(context, data.uri, ivImage)
loadIntoImageView(context, File(data.path), ivImage)
ivSelector.isSelected = data.select
ivSelector.setOnClickListener {
data.select = !data.select
......@@ -57,7 +59,7 @@ class LargeImageSelectorAdapter(
//判断是做局部刷新还是单条刷新
if (payloads.isEmpty()) {//局部刷新
holder.binding.apply {
loadIntoImageView(context, data.uri, ivImage)
loadIntoImageView(context, File(data.path), ivImage)
ivSelector.isSelected = data.select
ivSelector.setOnClickListener {
data.select = !data.select
......@@ -100,4 +102,20 @@ class LargeImageSelectorAdapter(
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
import android.annotation.SuppressLint
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
......@@ -10,6 +11,7 @@ import com.example.hfilemanagermaster.databinding.ItemVideoSelectBinding
import com.zxhy.hfilemanagermaster.data.MediaDataC
import com.zxhy.hfilemanagermaster.glide.loadIntoImageView
import com.zxhy.hfilemanagermaster.knife.inflate
import java.io.File
class LargeVideoSelectorAdapter(
private val selectAction: ((flag: Boolean) -> Unit)? = null
......@@ -34,7 +36,7 @@ class LargeVideoSelectorAdapter(
val context = holder.binding.root.context
val data = mediaList[position]
holder.binding.apply {
loadIntoImageView(context, data.uri, ivImage)
loadIntoImageView(context, File(data.path), ivImage)
ivSelector.isSelected = data.select
}
}
......@@ -50,7 +52,7 @@ class LargeVideoSelectorAdapter(
//判断是做局部刷新还是单条刷新
if (payloads.isEmpty()) {//局部刷新
holder.binding.apply {
loadIntoImageView(context, data.uri, ivImage)
loadIntoImageView(context, File(data.path), ivImage)
ivSelector.isSelected = data.select
ivSelector.setOnClickListener {
......@@ -95,4 +97,21 @@ class LargeVideoSelectorAdapter(
fun getSelectData(): List<MediaDataC> {
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
import android.Manifest
import android.annotation.SuppressLint
import android.os.Build
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
......@@ -13,15 +11,14 @@ import com.example.hfilemanagermaster.R
import com.example.hfilemanagermaster.databinding.FragmentManagerBinding
import com.zxhy.hfilemanagermaster.OverviewActivity
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.requestPermission
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() {
private lateinit var binding: FragmentManagerBinding
......@@ -55,13 +52,10 @@ class ManagerFragment : Fragment() {
(requireActivity() as OverviewActivity).showManager()
binding.ivFile.setOnClickListener {
requireContext().requestStoreFollow(
(requireActivity() as OverviewActivity).permissionLauncher,
(requireActivity() as OverviewActivity).intentLauncher
) {
findNavController().navigate(R.id.filesFragment)
val bundle = Bundle().apply {
putString("tittle", "Document")
}
findNavController().navigate(R.id.fileBrowseActivity, bundle)
}
binding.ivWord.setOnClickListener {
val bundle = Bundle().apply {
......@@ -69,7 +63,6 @@ class ManagerFragment : Fragment() {
}
findNavController().navigate(R.id.fileBrowseActivity, bundle)
}
binding.ivExcel.setOnClickListener {
val bundle = Bundle().apply {
putString("tittle", "Excel")
......@@ -83,47 +76,38 @@ class ManagerFragment : Fragment() {
findNavController().navigate(R.id.fileBrowseActivity, bundle)
}
binding.ivPpt.setOnClickListener {
val bundle = Bundle().apply {
putString("tittle", "PPT")
}
findNavController().navigate(R.id.fileBrowseActivity, bundle)
}
binding.cardView1.setOnClickListener {
requireContext().requestStoreFollow(
(requireActivity() as OverviewActivity).permissionLauncher,
(requireActivity() as OverviewActivity).intentLauncher
) {
findNavController().navigate(R.id.dupPictureActivity)
}
findNavController().navigate(R.id.dupPictureActivity)
}
binding.cardView2.setOnClickListener {
requireContext().requestStoreFollow(
(requireActivity() as OverviewActivity).permissionLauncher,
(requireActivity() as OverviewActivity).intentLauncher
) {
findNavController().navigate(R.id.largeFileActivity)
}
findNavController().navigate(R.id.largeFileActivity)
}
binding.cardView3.setOnClickListener {
requireContext().requestStoreFollow(
(requireActivity() as OverviewActivity).permissionLauncher,
(requireActivity() as OverviewActivity).intentLauncher
) {
findNavController().navigate(R.id.emptyFileActivity)
}
findNavController().navigate(R.id.emptyFileActivity)
}
binding.tvManage.setOnClickListener {
findNavController().navigate(R.id.internalStorageActivity)
}
requireContext().requestStoreFollow(
(requireActivity() as OverviewActivity).permissionLauncher,
(requireActivity() as OverviewActivity).intentLauncher,
disAgreeAction = {
},
agreeAction = {
})
}
companion object {
@JvmStatic
fun newInstance(param1: String, param2: String) =
fun newInstance() =
ManagerFragment().apply {
arguments = Bundle().apply {
}
......
package com.zxhy.hfilemanagermaster.permission
import android.Manifest
import android.annotation.SuppressLint
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
......@@ -20,57 +21,37 @@ fun requestPermission(
intentLauncher: IntentLauncher,
permission: Array<String>,
tip: String,
agreeAction: (() -> Unit)? = null
): Boolean {
var flag = false
agreeAction: (() -> Unit)? = null,
disAgreeAction: (() -> Unit)? = null
) {
val request: () -> Unit = {
val permissionFlag =
permission.all {
ContextCompat.checkSelfPermission(context, it) == PackageManager.PERMISSION_GRANTED
}
if (permissionFlag) {
flag = true
} else {
permissionLauncher.launch(permission) { callback ->
val isGrantAll = callback.values.all { it }
if (!isGrantAll) {
context.alert(tip) {
positiveButton("Jump") { dialog ->
goToPermissionSettings(context, intentLauncher)
dialog.dismiss()
}
negativeButton("Cancel") { dialog ->
dialog.dismiss()
}
//禁止取消
isCancel(false)
val permissionFlag =
permission.all {
ContextCompat.checkSelfPermission(context, it) == PackageManager.PERMISSION_GRANTED
}
if (permissionFlag) {
agreeAction?.invoke()
} else {
permissionLauncher.launch(permission) { callback ->
val isGrantAll = callback.values.all { it }
if (!isGrantAll) {
context.alert(tip) {
positiveButton("Jump") { dialog ->
goToPermissionSettings(context, intentLauncher)
dialog.dismiss()
}
} else {
agreeAction?.invoke()
negativeButton("Cancel") { dialog ->
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 {
.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(
permissionLauncher: PermissionLauncher,
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,
arrayOf(
Manifest.permission.READ_MEDIA_IMAGES,
Manifest.permission.READ_MEDIA_VIDEO
), "Set permission to access media images and videos"
) {
//请求读写管理权限
@SuppressLint("NewApi")
val requestExternalStorageManager: () -> Unit = {
if (!Environment.isExternalStorageManager()) {
val uri = Uri.parse("package:$packageName")
val intent = settingManageExternalStorage(uri)
intentLauncher.launch(intent) {
val flag = Environment.isExternalStorageManager()
if (flag) agreeAction?.invoke() else disAgreeAction?.invoke()
}
} else {
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,
arrayOf(
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE
), "Set permission to access external storage"
) {
agreeAction?.invoke()
}
if (flag) agreeAction?.invoke()
), "Set permission to access external storage",
agreeAction = { //读写权限通过,设置储存管理权限
requestExternalStorageManager()
},
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
import com.zxhy.hfilemanagermaster.dialog.showLoadingDialog
import com.zxhy.hfilemanagermaster.dialog.showOperationDialog
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.videoFile
import com.zxhy.hfilemanagermaster.permission.IntentLauncher
import com.zxhy.hfilemanagermaster.permission.PermissionLauncher
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.delay
import kotlinx.coroutines.launch
......@@ -31,9 +33,14 @@ class VideoActivity : AppCompatActivity() {
private lateinit var binding: ActivityVideoBinding
private lateinit var videoAdapter: VideoSelectAdapter
private lateinit var loadDialog: Dialog
private lateinit var intentLauncher: IntentLauncher
private lateinit var permissionLauncher: PermissionLauncher
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enableEdgeToEdge()
intentLauncher = IntentLauncher(this)
permissionLauncher = PermissionLauncher(this)
binding = ActivityVideoBinding.inflate(layoutInflater)
setContentView(binding.root)
ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main)) { v, insets ->
......@@ -54,9 +61,11 @@ class VideoActivity : AppCompatActivity() {
binding.rv.layoutManager = GridLayoutManager(this, 3)
binding.rv.adapter = videoAdapter
loadDialog = showLoadingDialog()
loadVideoData()
if (storePermissionCheck()) {
fileMode()
} else {
lockMode()
}
binding.tvDelete.setOnClickListener {
val list = videoAdapter.getSelectFile()
......@@ -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 {
try {
files.forEach {
......
......@@ -108,9 +108,9 @@ class VideoSelectAdapter(
@SuppressLint("NotifyDataSetChanged")
fun removeData(file: List<MediaDataC>) {
mediaList.removeAll(file.toSet())
file.forEachIndexed { index, mediaDataC ->
Log.e("removeData", "index=$index $mediaDataC")
}
// file.forEachIndexed { index, mediaDataC ->
// Log.e("removeData", "index=$index $mediaDataC")
// }
notifyDataSetChanged()
}
......@@ -119,6 +119,6 @@ class VideoSelectAdapter(
val index = mediaList.size
mediaList.addAll(data)
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 {
// Log.e("IndicatorView", "width=$width height=$height")
// 取出最小值
val len = min(width, height)
hMargin = len * 0.125f
topMargin = len * 0.075f
//获取半径
radius = len.toFloat() - topMargin
// Log.e("IndicatorView", "radius=$radius")
......@@ -151,7 +155,8 @@ class IndicatorView : View {
indicatorX = 1f
rotationDegreesOffset = 0f
}
in 100f..119f->{
in 100f..119f -> {
indicatorY = 0.95f
indicatorX = 1f
rotationDegreesOffset = 2f
......
......@@ -76,7 +76,6 @@
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/cl_top" />
<TextView
android:id="@+id/tv_delete"
android:layout_width="0dp"
......@@ -94,4 +93,67 @@
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_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>
\ No newline at end of file
......@@ -64,6 +64,57 @@
</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
android:id="@+id/cl_lock"
android:layout_width="match_parent"
......@@ -115,33 +166,5 @@
</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>
\ No newline at end of file
......@@ -64,45 +64,107 @@
</androidx.constraintlayout.widget.ConstraintLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv"
android:layout_width="0dp"
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/cl_show"
android:layout_width="match_parent"
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" />
<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" />
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
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>
\ No newline at end of file
......@@ -64,45 +64,105 @@
</androidx.constraintlayout.widget.ConstraintLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv"
android:layout_width="0dp"
<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: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_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"
android:visibility="invisible"
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_toBottomOf="@id/cl_top"
tools:ignore="ContentDescription" />
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>
\ No newline at end of file
......@@ -146,6 +146,17 @@
app:layout_constraintRight_toRightOf="parent"
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
android:id="@+id/rv"
android:layout_width="match_parent"
......@@ -153,26 +164,16 @@
android:layout_marginBottom="12dp"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
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" />
<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
android:id="@+id/cl_operation"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginHorizontal="50dp"
android:layout_marginBottom="24dp"
android:visibility="invisible"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintBottom_toTopOf="@id/cl_confirm"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/rv">
......@@ -273,10 +274,11 @@
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginHorizontal="57dp"
android:visibility="invisible"
android:layout_marginBottom="24dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="@id/cl_operation">
app:layout_constraintTop_toBottomOf="@id/cl_operation">
<TextView
android:id="@+id/tv_cancel"
......@@ -308,6 +310,27 @@
</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>
\ No newline at end of file
......@@ -65,78 +65,153 @@
</androidx.constraintlayout.widget.ConstraintLayout>
<TextView
android:id="@+id/tv_file"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="59dp"
android:layout_marginTop="12dp"
android:text="File"
android:textColor="#333333"
android:textSize="15sp"
android:textStyle="bold"
app:layout_constraintHorizontal_chainStyle="spread_inside"
<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_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_constraintTop_toTopOf="@id/tv_file"
tools:ignore="HardcodedText,RtlHardcoded" />
app:layout_constraintTop_toBottomOf="@id/cl_top">
<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
android:id="@+id/rv"
android:layout_width="0dp"
<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_marginHorizontal="0dp"
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"
android:visibility="invisible"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
tools:ignore="HardcodedText" />
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>
\ No newline at end of file
......@@ -13,7 +13,7 @@
android:layout_width="match_parent"
android:layout_height="0dp"
app:defaultNavHost="true"
app:layout_constraintBottom_toTopOf="@id/iv_manager"
app:layout_constraintBottom_toTopOf="@id/fl_manager"
app:layout_constraintTop_toTopOf="parent"
app:navGraph="@navigation/nav" />
......@@ -30,8 +30,8 @@
<FrameLayout
android:id="@+id/fl_manager"
android:layout_width="36dp"
android:layout_height="36dp"
android:layout_width="84dp"
android:layout_height="48dp"
app:layout_constraintBottom_toBottomOf="@id/iv_manager"
app:layout_constraintLeft_toLeftOf="@id/iv_manager"
app:layout_constraintRight_toRightOf="@id/iv_manager"
......@@ -63,8 +63,8 @@
<FrameLayout
android:id="@+id/fl_tools"
android:layout_width="36dp"
android:layout_height="36dp"
android:layout_width="84dp"
android:layout_height="48dp"
app:layout_constraintBottom_toBottomOf="@id/iv_tools"
app:layout_constraintLeft_toLeftOf="@id/iv_tools"
app:layout_constraintRight_toRightOf="@id/iv_tools"
......
......@@ -23,7 +23,7 @@
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:ignore="RtlHardcoded" />
tools:ignore="ContentDescription,RtlHardcoded" />
<TextView
android:layout_width="wrap_content"
......@@ -63,45 +63,107 @@
</androidx.constraintlayout.widget.ConstraintLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv"
android:layout_width="0dp"
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/cl_show"
android:layout_width="match_parent"
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_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_toBottomOf="@id/cl_top"
tools:ignore="ContentDescription" />
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: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>
\ 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 @@
android:hint="Please enter a new name"
android:singleLine="true"
android:textColor="#CCFFFFFF"
android:textColorHint="#CCFFFFFF"
android:textSize="14sp"
app:layout_constraintBottom_toBottomOf="@id/iv_placeholder"
app:layout_constraintLeft_toLeftOf="parent"
......
......@@ -9,7 +9,15 @@
<dimen name="dp_140">140dp</dimen>
<dimen name="dp_180">180dp</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_20">20dp</dimen>
<dimen name="dp_255">255dp</dimen>
<dimen name="dp_177">177dp</dimen>
<dimen name="dp_233">233dp</dimen>
</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
# 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,
# thereby reducing the size of the R class for that library
android.nonTransitiveRClass=true
\ No newline at end of file
android.nonTransitiveRClass=true
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