This commit is contained in:
Binondi
2024-12-15 15:21:26 +05:30
parent c6bbb076fc
commit f44c231493
5 changed files with 68 additions and 73 deletions

View File

@@ -59,6 +59,19 @@
<activity <activity
android:name=".activities.PreviewActivity" android:name=".activities.PreviewActivity"
android:configChanges="orientation|screenSize"/> android:configChanges="orientation|screenSize"/>
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="devs.org.calculator.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths" />
</provider>
</application> </application>
</manifest> </manifest>

View File

@@ -73,7 +73,7 @@ class PreviewActivity : AppCompatActivity() {
private fun clickListeners() { private fun clickListeners() {
binding.delete.setOnClickListener { binding.delete.setOnClickListener {
val fileUri = FileManager.FileManager().getContentUri(this, files[binding.viewPager.currentItem], filetype) val fileUri = FileManager.FileManager().getContentUriImage(this, files[binding.viewPager.currentItem], filetype)
if (fileUri != null) { if (fileUri != null) {
MaterialAlertDialogBuilder(this) MaterialAlertDialogBuilder(this)
.setTitle("Delete File") .setTitle("Delete File")
@@ -93,7 +93,7 @@ class PreviewActivity : AppCompatActivity() {
} }
binding.unHide.setOnClickListener { binding.unHide.setOnClickListener {
val fileUri = FileManager.FileManager().getContentUri(this, files[binding.viewPager.currentItem], filetype) val fileUri = FileManager.FileManager().getContentUriImage(this, files[binding.viewPager.currentItem], filetype)
if (fileUri != null) { if (fileUri != null) {
MaterialAlertDialogBuilder(this) MaterialAlertDialogBuilder(this)
.setTitle("Unhide File") .setTitle("Unhide File")

View File

@@ -2,7 +2,6 @@ package devs.org.calculator.adapters
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.net.Uri
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
@@ -16,19 +15,21 @@ import androidx.recyclerview.widget.RecyclerView
import com.bumptech.glide.Glide import com.bumptech.glide.Glide
import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.google.android.material.dialog.MaterialAlertDialogBuilder
import devs.org.calculator.R import devs.org.calculator.R
import devs.org.calculator.activities.BaseGalleryActivity
import devs.org.calculator.activities.PreviewActivity import devs.org.calculator.activities.PreviewActivity
import devs.org.calculator.utils.DialogUtil
import devs.org.calculator.utils.FileManager import devs.org.calculator.utils.FileManager
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import java.io.File import java.io.File
import kotlin.collections.remove
class FileAdapter(private val fileType: FileManager.FileType, var context: Context, private var lifecycleOwner: LifecycleOwner) : class FileAdapter(
private val fileType: FileManager.FileType,
var context: Context,
private var lifecycleOwner: LifecycleOwner
) :
ListAdapter<File, FileAdapter.FileViewHolder>(FileDiffCallback()) { ListAdapter<File, FileAdapter.FileViewHolder>(FileDiffCallback()) {
private val selectedItems = mutableSetOf<Int>() private val selectedItems = mutableSetOf<Int>()
private var isSelectionMode = false private var isSelectionMode = false
private var fileName = "Unknown File"
inner class FileViewHolder(view: View) : RecyclerView.ViewHolder(view) { inner class FileViewHolder(view: View) : RecyclerView.ViewHolder(view) {
private val imageView: ImageView = view.findViewById(R.id.imageView) private val imageView: ImageView = view.findViewById(R.id.imageView)
@@ -42,6 +43,7 @@ class FileAdapter(private val fileType: FileManager.FileType, var context: Conte
.centerCrop() .centerCrop()
.into(imageView) .into(imageView)
} }
FileManager.FileType.VIDEO -> { FileManager.FileType.VIDEO -> {
Glide.with(imageView) Glide.with(imageView)
.asBitmap() .asBitmap()
@@ -49,6 +51,7 @@ class FileAdapter(private val fileType: FileManager.FileType, var context: Conte
.centerCrop() .centerCrop()
.into(imageView) .into(imageView)
} }
else -> { else -> {
val resourceId = when (fileType) { val resourceId = when (fileType) {
FileManager.FileType.AUDIO -> R.drawable.ic_audio FileManager.FileType.AUDIO -> R.drawable.ic_audio
@@ -66,12 +69,15 @@ class FileAdapter(private val fileType: FileManager.FileType, var context: Conte
FileManager.FileType.IMAGE -> { FileManager.FileType.IMAGE -> {
"IMAGE" "IMAGE"
} }
FileManager.FileType.VIDEO -> { FileManager.FileType.VIDEO -> {
"VIDEO" "VIDEO"
} }
FileManager.FileType.AUDIO -> { FileManager.FileType.AUDIO -> {
"AUDIO" "AUDIO"
} }
else -> "DOCUMENT" else -> "DOCUMENT"
} }
@@ -83,20 +89,27 @@ class FileAdapter(private val fileType: FileManager.FileType, var context: Conte
} }
itemView.setOnLongClickListener { itemView.setOnLongClickListener {
val fileUri = FileManager.FileManager().getContentUri(context, file, fileType)
if (fileUri == null) {
Toast.makeText(context, "Unable to access file: $file", Toast.LENGTH_SHORT).show()
return@setOnLongClickListener true
}
val fileName = FileManager.FileName(context).getFileNameFromUri(fileUri)?.toString() ?: "Unknown File" val fileUri = FileManager.FileManager().getContentUriImage(context, file, fileType)
if (fileUri == null) {
Toast.makeText(context, "Unable to access file: $file", Toast.LENGTH_SHORT)
.show()
return@setOnLongClickListener true
}
fileName = FileManager.FileName(context).getFileNameFromUri(fileUri)?.toString()
?: "Unknown File"
MaterialAlertDialogBuilder(context) MaterialAlertDialogBuilder(context)
.setTitle("Details") .setTitle("Details")
.setMessage("File Name: $fileName\n\nYou can delete or unhide this file.") .setMessage("File Name: $fileName\n\nFile Path: $file\n\nYou can delete or unhide this file.")
.setPositiveButton("Delete") { dialog, _ -> .setPositiveButton("Delete") { dialog, _ ->
lifecycleOwner.lifecycleScope.launch { lifecycleOwner.lifecycleScope.launch {
FileManager(context, lifecycleOwner).deletePhotoFromExternalStorage(fileUri) FileManager(context, lifecycleOwner).deletePhotoFromExternalStorage(
fileUri
)
} }
val currentList = currentList.toMutableList() val currentList = currentList.toMutableList()
currentList.remove(file) currentList.remove(file)

View File

@@ -24,6 +24,7 @@ import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import java.io.File import java.io.File
import android.Manifest import android.Manifest
import androidx.core.content.FileProvider
class FileManager(private val context: Context, private val lifecycleOwner: LifecycleOwner) { class FileManager(private val context: Context, private val lifecycleOwner: LifecycleOwner) {
private lateinit var intentSenderLauncher: ActivityResultLauncher<IntentSenderRequest> private lateinit var intentSenderLauncher: ActivityResultLauncher<IntentSenderRequest>
@@ -224,9 +225,9 @@ class FileManager(private val context: Context, private val lifecycleOwner: Life
} }
class FileManager(){ class FileManager(){
fun getContentUri(context: Context, file: File, fileType: FileType): Uri? { fun getContentUriImage(context: Context, file: File, fileType: FileType): Uri? {
when(fileType){
FileType.IMAGE -> { // Query MediaStore for the file
val projection = arrayOf(MediaStore.MediaColumns._ID) val projection = arrayOf(MediaStore.MediaColumns._ID)
val selection = "${MediaStore.MediaColumns.DATA} = ?" val selection = "${MediaStore.MediaColumns.DATA} = ?"
val selectionArgs = arrayOf(file.absolutePath) val selectionArgs = arrayOf(file.absolutePath)
@@ -238,55 +239,15 @@ class FileManager(private val context: Context, private val lifecycleOwner: Life
return Uri.withAppendedPath(queryUri, id.toString()) return Uri.withAppendedPath(queryUri, id.toString())
} }
} }
return null
}
FileType.VIDEO -> { // If the file is not found in MediaStore, fallback to FileProvider for hidden files
val projection = arrayOf(MediaStore.Video.Media._ID) return if (file.exists()) {
val selection = "${MediaStore.Video.Media.DATA} = ?" FileProvider.getUriForFile(context, "devs.org.calculator.fileprovider", file)
val selectionArgs = arrayOf(file.absolutePath) } else {
val queryUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI null
context.contentResolver.query(queryUri, projection, selection, selectionArgs, null)?.use { cursor ->
if (cursor.moveToFirst()) {
val id = cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.Video.Media._ID))
return Uri.withAppendedPath(queryUri, id.toString())
}
}
return null
}
FileType.AUDIO -> {
val projection = arrayOf(MediaStore.Audio.Media._ID)
val selection = "${MediaStore.Audio.Media.DATA} = ?"
val selectionArgs = arrayOf(file.absolutePath)
val queryUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI
context.contentResolver.query(queryUri, projection, selection, selectionArgs, null)?.use { cursor ->
if (cursor.moveToFirst()) {
val id = cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media._ID))
return Uri.withAppendedPath(queryUri, id.toString())
}
}
return null
}
FileType.DOCUMENT -> {
val projection = arrayOf(MediaStore.Files.FileColumns._ID)
val selection = "${MediaStore.Files.FileColumns.DATA} = ?"
val selectionArgs = arrayOf(file.absolutePath)
val queryUri = MediaStore.Files.getContentUri("external")
context.contentResolver.query(queryUri, projection, selection, selectionArgs, null)?.use { cursor ->
if (cursor.moveToFirst()) {
val id = cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.Files.FileColumns._ID))
return Uri.withAppendedPath(queryUri, id.toString())
} }
} }
return null
}
}
}
} }

View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<!-- Allow access to external files -->
<external-path name="external_files" path="." />
<!-- Allow access to hidden directories -->
<external-files-path name="hidden_files" path=".CalculatorHide/" />
</paths>