Created
November 19, 2020 17:45
-
-
Save yrezgui/79488ca2b810e9fcd5f5ece1f43840eb to your computer and use it in GitHub Desktop.
Storage utilities for Android
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.yrezgui.videoplayer | |
import android.annotation.SuppressLint | |
import android.content.Context | |
import android.os.Build.VERSION | |
import android.os.Build.VERSION_CODES | |
import android.os.Environment | |
import android.os.storage.StorageManager | |
import android.os.storage.StorageVolume | |
import androidx.annotation.RequiresApi | |
import java.io.File | |
enum class VolumeType { | |
EMULATED, REMOVABLE, MIXED | |
} | |
data class VolumeResource( | |
val type: VolumeType, | |
val path: String | |
) | |
@RequiresApi(api = VERSION_CODES.KITKAT) | |
private fun getVolumesApi19(): List<VolumeResource> { | |
val path = Environment.getExternalStorageDirectory() | |
val isRemovable = Environment.isExternalStorageRemovable() | |
val isEmulated = Environment.isExternalStorageEmulated() | |
val volumeType = when { | |
isEmulated && isRemovable -> VolumeType.MIXED | |
isEmulated && !isRemovable -> VolumeType.EMULATED | |
else -> VolumeType.REMOVABLE | |
} | |
return listOf(VolumeResource(type = volumeType, path = path.toString())) | |
} | |
@RequiresApi(api = VERSION_CODES.LOLLIPOP) | |
fun getVolumesApi21(context: Context): List<VolumeResource> { | |
// e.g. /storage/emulated/0/Android/media/com.yrezgui.videoplayer | |
// e.g. /storage/sdcard/Android/media/com.yrezgui.videoplayer | |
val volumeRootFolders = context.externalMediaDirs.map { | |
it.parentFile?.parentFile?.parentFile | |
} | |
return volumeRootFolders.filterNotNull().map { folder -> | |
val folderState = Environment.getStorageState(folder) | |
val isEmulated = Environment.isExternalStorageEmulated(folder) | |
val isRemovable = Environment.isExternalStorageRemovable(folder) | |
val volumeType = when { | |
isEmulated && isRemovable -> VolumeType.MIXED | |
isEmulated && !isRemovable -> VolumeType.EMULATED | |
else -> VolumeType.REMOVABLE | |
} | |
VolumeResource(type = volumeType, path = folder.toString()) | |
} | |
} | |
@RequiresApi(api = VERSION_CODES.R) | |
private fun getVolumesApi30(context: Context): List<VolumeResource> { | |
val storageManager = context.getSystemService(Context.STORAGE_SERVICE) as StorageManager | |
return storageManager.storageVolumes.map { | |
val volumeType = when { | |
it.isEmulated && it.isRemovable -> VolumeType.MIXED | |
it.isEmulated && !it.isRemovable -> VolumeType.EMULATED | |
else -> VolumeType.REMOVABLE | |
} | |
VolumeResource(type = volumeType, path = it.directory!!.toString()) | |
} | |
} | |
fun getVolumes(context: Context): List<VolumeResource> { | |
return when { | |
VERSION.SDK_INT >= VERSION_CODES.R -> getVolumesApi30(context) | |
VERSION.SDK_INT >= VERSION_CODES.LOLLIPOP -> getVolumesApi21(context) | |
else -> getVolumesApi19() | |
} | |
} | |
fun getFiles(folder: File): List<File> { | |
val files = folder.listFiles()?.asSequence() ?: emptySequence<File>() | |
return files | |
.filter(::removeHiddenFiles) | |
.filter(::removeNonVideoFiles) | |
.sortedByDescending { it.isDirectory } | |
.toList() | |
} | |
private fun removeHiddenFiles(file: File): Boolean { | |
return !file.isHidden || file.name.first() != '.' | |
} | |
val VIDEO_EXTENSIONS = arrayOf("mpg", "mpeg", "mp4", "asf", "wma", "wmv", "avi", "3gpp", "3gpp2") | |
private fun removeNonVideoFiles(file: File): Boolean { | |
return file.isDirectory || (file.isFile && VIDEO_EXTENSIONS.contains(file.extension)) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment