Merge pull request #745 from esensar/feature/678-sdcard-storage-analysis

Add SD card to storage analysis
This commit is contained in:
Tibor Kaputa 2023-09-07 13:35:29 +02:00 committed by GitHub
commit d1e75ef217
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 531 additions and 384 deletions

View File

@ -40,6 +40,7 @@ class MimeTypesActivity : SimpleActivity(), ItemOperationsListener {
private var zoomListener: MyRecyclerView.MyZoomListener? = null private var zoomListener: MyRecyclerView.MyZoomListener? = null
private var storedItems = ArrayList<ListItem>() private var storedItems = ArrayList<ListItem>()
private var currentViewType = VIEW_TYPE_LIST private var currentViewType = VIEW_TYPE_LIST
private var currentVolume = PRIMARY_VOLUME_NAME
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
isMaterialActivity = true isMaterialActivity = true
@ -53,6 +54,7 @@ class MimeTypesActivity : SimpleActivity(), ItemOperationsListener {
} }
currentMimeType = intent.getStringExtra(SHOW_MIMETYPE) ?: return currentMimeType = intent.getStringExtra(SHOW_MIMETYPE) ?: return
currentVolume = intent.getStringExtra(VOLUME_NAME) ?: currentVolume
binding.mimetypesToolbar.title = getString( binding.mimetypesToolbar.title = getString(
when (currentMimeType) { when (currentMimeType) {
IMAGES -> R.string.images IMAGES -> R.string.images
@ -267,7 +269,7 @@ class MimeTypesActivity : SimpleActivity(), ItemOperationsListener {
private fun getProperFileDirItems(callback: (ArrayList<FileDirItem>) -> Unit) { private fun getProperFileDirItems(callback: (ArrayList<FileDirItem>) -> Unit) {
val fileDirItems = ArrayList<FileDirItem>() val fileDirItems = ArrayList<FileDirItem>()
val showHidden = config.shouldShowHidden() val showHidden = config.shouldShowHidden()
val uri = MediaStore.Files.getContentUri("external") val uri = MediaStore.Files.getContentUri(currentVolume)
val projection = arrayOf( val projection = arrayOf(
MediaStore.Files.FileColumns.MIME_TYPE, MediaStore.Files.FileColumns.MIME_TYPE,
MediaStore.Files.FileColumns.DATA, MediaStore.Files.FileColumns.DATA,

View File

@ -1,10 +1,29 @@
package com.simplemobiletools.filemanager.pro.extensions package com.simplemobiletools.filemanager.pro.extensions
import android.content.Context import android.content.Context
import android.os.storage.StorageManager
import com.simplemobiletools.commons.extensions.isPathOnOTG import com.simplemobiletools.commons.extensions.isPathOnOTG
import com.simplemobiletools.commons.extensions.isPathOnSD import com.simplemobiletools.commons.extensions.isPathOnSD
import com.simplemobiletools.commons.helpers.isNougatPlus
import com.simplemobiletools.filemanager.pro.helpers.Config import com.simplemobiletools.filemanager.pro.helpers.Config
import com.simplemobiletools.filemanager.pro.helpers.PRIMARY_VOLUME_NAME
import java.util.Locale
val Context.config: Config get() = Config.newInstance(applicationContext) val Context.config: Config get() = Config.newInstance(applicationContext)
fun Context.isPathOnRoot(path: String) = !(path.startsWith(config.internalStoragePath) || isPathOnOTG(path) || (isPathOnSD(path))) fun Context.isPathOnRoot(path: String) = !(path.startsWith(config.internalStoragePath) || isPathOnOTG(path) || (isPathOnSD(path)))
fun Context.getAllVolumeNames(): List<String> {
val volumeNames = mutableListOf(PRIMARY_VOLUME_NAME)
if (isNougatPlus()) {
val storageManager = getSystemService(Context.STORAGE_SERVICE) as StorageManager
getExternalFilesDirs(null)
.mapNotNull { storageManager.getStorageVolume(it) }
.filterNot { it.isPrimary }
.mapNotNull { it.uuid?.lowercase(Locale.US) }
.forEach {
volumeNames.add(it)
}
}
return volumeNames
}

View File

@ -6,13 +6,17 @@ import android.app.usage.StorageStatsManager
import android.content.ContentResolver import android.content.ContentResolver
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.media.MediaScannerConnection
import android.os.Handler import android.os.Handler
import android.os.Looper
import android.os.storage.StorageManager import android.os.storage.StorageManager
import android.provider.MediaStore import android.provider.MediaStore
import android.provider.Settings import android.provider.Settings
import android.util.AttributeSet import android.util.AttributeSet
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.core.os.bundleOf import androidx.core.os.bundleOf
import androidx.core.view.children
import androidx.core.view.isVisible
import com.simplemobiletools.commons.extensions.* import com.simplemobiletools.commons.extensions.*
import com.simplemobiletools.commons.helpers.* import com.simplemobiletools.commons.helpers.*
import com.simplemobiletools.commons.models.FileDirItem import com.simplemobiletools.commons.models.FileDirItem
@ -21,12 +25,15 @@ import com.simplemobiletools.filemanager.pro.R
import com.simplemobiletools.filemanager.pro.activities.MimeTypesActivity import com.simplemobiletools.filemanager.pro.activities.MimeTypesActivity
import com.simplemobiletools.filemanager.pro.activities.SimpleActivity import com.simplemobiletools.filemanager.pro.activities.SimpleActivity
import com.simplemobiletools.filemanager.pro.adapters.ItemsAdapter import com.simplemobiletools.filemanager.pro.adapters.ItemsAdapter
import com.simplemobiletools.filemanager.pro.databinding.ItemStorageVolumeBinding
import com.simplemobiletools.filemanager.pro.databinding.StorageFragmentBinding import com.simplemobiletools.filemanager.pro.databinding.StorageFragmentBinding
import com.simplemobiletools.filemanager.pro.extensions.config import com.simplemobiletools.filemanager.pro.extensions.config
import com.simplemobiletools.filemanager.pro.extensions.formatSizeThousand import com.simplemobiletools.filemanager.pro.extensions.formatSizeThousand
import com.simplemobiletools.filemanager.pro.extensions.getAllVolumeNames
import com.simplemobiletools.filemanager.pro.helpers.* import com.simplemobiletools.filemanager.pro.helpers.*
import com.simplemobiletools.filemanager.pro.interfaces.ItemOperationsListener import com.simplemobiletools.filemanager.pro.interfaces.ItemOperationsListener
import com.simplemobiletools.filemanager.pro.models.ListItem import com.simplemobiletools.filemanager.pro.models.ListItem
import java.io.File
import java.util.* import java.util.*
class StorageFragment(context: Context, attributeSet: AttributeSet) : MyViewPagerFragment<MyViewPagerFragment.StorageInnerBinding>(context, attributeSet), class StorageFragment(context: Context, attributeSet: AttributeSet) : MyViewPagerFragment<MyViewPagerFragment.StorageInnerBinding>(context, attributeSet),
@ -35,6 +42,7 @@ class StorageFragment(context: Context, attributeSet: AttributeSet) : MyViewPage
private var allDeviceListItems = ArrayList<ListItem>() private var allDeviceListItems = ArrayList<ListItem>()
private var lastSearchedText = "" private var lastSearchedText = ""
private lateinit var binding: StorageFragmentBinding private lateinit var binding: StorageFragmentBinding
private val volumes = mutableMapOf<String, ItemStorageVolumeBinding>()
override fun onFinishInflate() { override fun onFinishInflate() {
super.onFinishInflate() super.onFinishInflate()
@ -47,88 +55,132 @@ class StorageFragment(context: Context, attributeSet: AttributeSet) : MyViewPage
this.activity = activity this.activity = activity
} }
binding.totalSpace.text = String.format(context.getString(R.string.total_storage), "") val volumeNames = activity.getAllVolumeNames()
getSizes() volumeNames.forEach { volumeName ->
val volumeBinding = ItemStorageVolumeBinding.inflate(activity.layoutInflater)
volumes[volumeName] = volumeBinding
volumeBinding.apply {
if (volumeName == PRIMARY_VOLUME_NAME) {
storageName.setText(R.string.internal)
} else {
storageName.setText(R.string.sd_card)
}
binding.freeSpaceHolder.setOnClickListener { totalSpace.text = String.format(context.getString(R.string.total_storage), "")
try { getSizes(volumeName)
val storageSettingsIntent = Intent(Settings.ACTION_INTERNAL_STORAGE_SETTINGS)
activity.startActivity(storageSettingsIntent) if (volumeNames.size > 1) {
} catch (e: Exception) { root.children.forEach { it.beGone() }
activity.showErrorToast(e) freeSpaceHolder.beVisible()
expandButton.applyColorFilter(context.getProperPrimaryColor())
expandButton.setImageResource(R.drawable.ic_arrow_down_vector)
expandButton.setOnClickListener { _ ->
if (imagesHolder.isVisible) {
root.children.filterNot { it == freeSpaceHolder }.forEach { it.beGone() }
expandButton.setImageResource(R.drawable.ic_arrow_down_vector)
} else {
root.children.filterNot { it == freeSpaceHolder }.forEach { it.beVisible() }
expandButton.setImageResource(R.drawable.ic_arrow_up_vector)
}
}
} else {
expandButton.beGone()
}
freeSpaceHolder.setOnClickListener {
try {
val storageSettingsIntent = Intent(Settings.ACTION_INTERNAL_STORAGE_SETTINGS)
activity.startActivity(storageSettingsIntent)
} catch (e: Exception) {
activity.showErrorToast(e)
}
}
imagesHolder.setOnClickListener { launchMimetypeActivity(IMAGES, volumeName) }
videosHolder.setOnClickListener { launchMimetypeActivity(VIDEOS, volumeName) }
audioHolder.setOnClickListener { launchMimetypeActivity(AUDIO, volumeName) }
documentsHolder.setOnClickListener { launchMimetypeActivity(DOCUMENTS, volumeName) }
archivesHolder.setOnClickListener { launchMimetypeActivity(ARCHIVES, volumeName) }
othersHolder.setOnClickListener { launchMimetypeActivity(OTHERS, volumeName) }
} }
binding.storageVolumesHolder.addView(volumeBinding.root)
} }
binding.apply { ensureBackgroundThread {
imagesHolder.setOnClickListener { launchMimetypeActivity(IMAGES) } getVolumeStorageStats(context)
videosHolder.setOnClickListener { launchMimetypeActivity(VIDEOS) }
audioHolder.setOnClickListener { launchMimetypeActivity(AUDIO) }
documentsHolder.setOnClickListener { launchMimetypeActivity(DOCUMENTS) }
archivesHolder.setOnClickListener { launchMimetypeActivity(ARCHIVES) }
othersHolder.setOnClickListener { launchMimetypeActivity(OTHERS) }
} }
Handler().postDelayed({ Handler(Looper.getMainLooper()).postDelayed({
refreshFragment() refreshFragment()
}, 2000) }, 2000)
} }
override fun onResume(textColor: Int) { override fun onResume(textColor: Int) {
getSizes()
context.updateTextColors(binding.root) context.updateTextColors(binding.root)
val properPrimaryColor = context.getProperPrimaryColor()
val redColor = context.resources.getColor(R.color.md_red_700)
val greenColor = context.resources.getColor(R.color.md_green_700)
val lightBlueColor = context.resources.getColor(R.color.md_light_blue_700)
val yellowColor = context.resources.getColor(R.color.md_yellow_700)
val tealColor = context.resources.getColor(R.color.md_teal_700)
val pinkColor = context.resources.getColor(R.color.md_pink_700)
volumes.entries.forEach { (it, volumeBinding) ->
getSizes(it)
volumeBinding.apply {
mainStorageUsageProgressbar.setIndicatorColor(properPrimaryColor)
mainStorageUsageProgressbar.trackColor = properPrimaryColor.adjustAlpha(LOWER_ALPHA)
imagesProgressbar.setIndicatorColor(redColor)
imagesProgressbar.trackColor = redColor.adjustAlpha(LOWER_ALPHA)
videosProgressbar.setIndicatorColor(greenColor)
videosProgressbar.trackColor = greenColor.adjustAlpha(LOWER_ALPHA)
audioProgressbar.setIndicatorColor(lightBlueColor)
audioProgressbar.trackColor = lightBlueColor.adjustAlpha(LOWER_ALPHA)
documentsProgressbar.setIndicatorColor(yellowColor)
documentsProgressbar.trackColor = yellowColor.adjustAlpha(LOWER_ALPHA)
archivesProgressbar.setIndicatorColor(tealColor)
archivesProgressbar.trackColor = tealColor.adjustAlpha(LOWER_ALPHA)
othersProgressbar.setIndicatorColor(pinkColor)
othersProgressbar.trackColor = pinkColor.adjustAlpha(LOWER_ALPHA)
expandButton.applyColorFilter(context.getProperPrimaryColor())
}
}
binding.apply { binding.apply {
val properPrimaryColor = context.getProperPrimaryColor()
mainStorageUsageProgressbar.setIndicatorColor(properPrimaryColor)
mainStorageUsageProgressbar.trackColor = properPrimaryColor.adjustAlpha(LOWER_ALPHA)
val redColor = context.resources.getColor(R.color.md_red_700)
imagesProgressbar.setIndicatorColor(redColor)
imagesProgressbar.trackColor = redColor.adjustAlpha(LOWER_ALPHA)
val greenColor = context.resources.getColor(R.color.md_green_700)
videosProgressbar.setIndicatorColor(greenColor)
videosProgressbar.trackColor = greenColor.adjustAlpha(LOWER_ALPHA)
val lightBlueColor = context.resources.getColor(R.color.md_light_blue_700)
audioProgressbar.setIndicatorColor(lightBlueColor)
audioProgressbar.trackColor = lightBlueColor.adjustAlpha(LOWER_ALPHA)
val yellowColor = context.resources.getColor(R.color.md_yellow_700)
documentsProgressbar.setIndicatorColor(yellowColor)
documentsProgressbar.trackColor = yellowColor.adjustAlpha(LOWER_ALPHA)
val tealColor = context.resources.getColor(R.color.md_teal_700)
archivesProgressbar.setIndicatorColor(tealColor)
archivesProgressbar.trackColor = tealColor.adjustAlpha(LOWER_ALPHA)
val pinkColor = context.resources.getColor(R.color.md_pink_700)
othersProgressbar.setIndicatorColor(pinkColor)
othersProgressbar.trackColor = pinkColor.adjustAlpha(LOWER_ALPHA)
searchHolder.setBackgroundColor(context.getProperBackgroundColor()) searchHolder.setBackgroundColor(context.getProperBackgroundColor())
progressBar.setIndicatorColor(properPrimaryColor) progressBar.setIndicatorColor(properPrimaryColor)
progressBar.trackColor = properPrimaryColor.adjustAlpha(LOWER_ALPHA) progressBar.trackColor = properPrimaryColor.adjustAlpha(LOWER_ALPHA)
} }
ensureBackgroundThread {
getVolumeStorageStats(context)
}
} }
private fun launchMimetypeActivity(mimetype: String) { private fun launchMimetypeActivity(mimetype: String, volumeName: String) {
Intent(context, MimeTypesActivity::class.java).apply { Intent(context, MimeTypesActivity::class.java).apply {
putExtra(SHOW_MIMETYPE, mimetype) putExtra(SHOW_MIMETYPE, mimetype)
putExtra(VOLUME_NAME, volumeName)
context.startActivity(this) context.startActivity(this)
} }
} }
private fun getSizes() { private fun getSizes(volumeName: String) {
if (!isOreoPlus()) { if (!isOreoPlus()) {
return return
} }
ensureBackgroundThread { ensureBackgroundThread {
getMainStorageStats(context) val filesSize = getSizesByMimeType(volumeName)
val filesSize = getSizesByMimeType()
val fileSizeImages = filesSize[IMAGES]!! val fileSizeImages = filesSize[IMAGES]!!
val fileSizeVideos = filesSize[VIDEOS]!! val fileSizeVideos = filesSize[VIDEOS]!!
val fileSizeAudios = filesSize[AUDIO]!! val fileSizeAudios = filesSize[AUDIO]!!
@ -137,7 +189,7 @@ class StorageFragment(context: Context, attributeSet: AttributeSet) : MyViewPage
val fileSizeOthers = filesSize[OTHERS]!! val fileSizeOthers = filesSize[OTHERS]!!
post { post {
binding.apply { volumes[volumeName]!!.apply {
imagesSize.text = fileSizeImages.formatSize() imagesSize.text = fileSizeImages.formatSize()
imagesProgressbar.progress = (fileSizeImages / SIZE_DIVIDER).toInt() imagesProgressbar.progress = (fileSizeImages / SIZE_DIVIDER).toInt()
@ -160,8 +212,8 @@ class StorageFragment(context: Context, attributeSet: AttributeSet) : MyViewPage
} }
} }
private fun getSizesByMimeType(): HashMap<String, Long> { private fun getSizesByMimeType(volumeName: String): HashMap<String, Long> {
val uri = MediaStore.Files.getContentUri("external") val uri = MediaStore.Files.getContentUri(volumeName)
val projection = arrayOf( val projection = arrayOf(
MediaStore.Files.FileColumns.SIZE, MediaStore.Files.FileColumns.SIZE,
MediaStore.Files.FileColumns.MIME_TYPE, MediaStore.Files.FileColumns.MIME_TYPE,
@ -222,40 +274,70 @@ class StorageFragment(context: Context, attributeSet: AttributeSet) : MyViewPage
} }
@SuppressLint("NewApi") @SuppressLint("NewApi")
private fun getMainStorageStats(context: Context) { private fun getVolumeStorageStats(context: Context) {
val externalDirs = context.getExternalFilesDirs(null) val externalDirs = context.getExternalFilesDirs(null)
val storageManager = context.getSystemService(AppCompatActivity.STORAGE_SERVICE) as StorageManager val storageManager = context.getSystemService(AppCompatActivity.STORAGE_SERVICE) as StorageManager
externalDirs.forEach { file -> externalDirs.forEach { file ->
val volumeName: String
val totalStorageSpace: Long
val freeStorageSpace: Long
val storageVolume = storageManager.getStorageVolume(file) ?: return val storageVolume = storageManager.getStorageVolume(file) ?: return
if (storageVolume.isPrimary) { if (storageVolume.isPrimary) {
// internal storage // internal storage
val storageStatsManager = context.getSystemService(AppCompatActivity.STORAGE_STATS_SERVICE) as StorageStatsManager volumeName = PRIMARY_VOLUME_NAME
val uuid = StorageManager.UUID_DEFAULT if (isOreoPlus()) {
val totalStorageSpace = storageStatsManager.getTotalBytes(uuid) val storageStatsManager = context.getSystemService(AppCompatActivity.STORAGE_STATS_SERVICE) as StorageStatsManager
val freeStorageSpace = storageStatsManager.getFreeBytes(uuid) val uuid = StorageManager.UUID_DEFAULT
totalStorageSpace = storageStatsManager.getTotalBytes(uuid)
post { freeStorageSpace = storageStatsManager.getFreeBytes(uuid)
binding.apply { } else {
arrayOf( totalStorageSpace = file.totalSpace
mainStorageUsageProgressbar, imagesProgressbar, videosProgressbar, audioProgressbar, documentsProgressbar, freeStorageSpace = file.freeSpace
archivesProgressbar, othersProgressbar
).forEach {
it.max = (totalStorageSpace / SIZE_DIVIDER).toInt()
}
mainStorageUsageProgressbar.progress = ((totalStorageSpace - freeStorageSpace) / SIZE_DIVIDER).toInt()
mainStorageUsageProgressbar.beVisible()
freeSpaceValue.text = freeStorageSpace.formatSizeThousand()
totalSpace.text = String.format(context.getString(R.string.total_storage), totalStorageSpace.formatSizeThousand())
freeSpaceLabel.beVisible()
}
} }
} else { } else {
// sd card volumeName = storageVolume.uuid!!.lowercase(Locale.US)
val totalSpace = file.totalSpace totalStorageSpace = file.totalSpace
val freeSpace = file.freeSpace freeStorageSpace = file.freeSpace
post {
ensureBackgroundThread {
scanVolume(volumeName, file)
}
}
}
post {
volumes[volumeName]?.apply {
arrayOf(
mainStorageUsageProgressbar, imagesProgressbar, videosProgressbar, audioProgressbar, documentsProgressbar,
archivesProgressbar, othersProgressbar
).forEach {
it.max = (totalStorageSpace / SIZE_DIVIDER).toInt()
}
mainStorageUsageProgressbar.progress = ((totalStorageSpace - freeStorageSpace) / SIZE_DIVIDER).toInt()
mainStorageUsageProgressbar.beVisible()
freeSpaceValue.text = freeStorageSpace.formatSizeThousand()
totalSpace.text = String.format(context.getString(R.string.total_storage), totalStorageSpace.formatSizeThousand())
freeSpaceLabel.beVisible()
}
}
}
}
private fun scanVolume(volumeName: String, root: File) {
val paths = mutableListOf<String>()
if (context.isPathOnSD(root.path)) {
File(context.sdCardPath).walkBottomUp().forEach {
paths.add(it.path)
}
}
var callbackCount = 0
MediaScannerConnection.scanFile(context, paths.toTypedArray(), null) { _, _ ->
callbackCount++
if (callbackCount == paths.size) {
getSizes(volumeName)
} }
} }
} }
@ -334,10 +416,10 @@ class StorageFragment(context: Context, attributeSet: AttributeSet) : MyViewPage
} }
} }
private fun getAllFiles(): ArrayList<FileDirItem> { private fun getAllFiles(volumeName: String): ArrayList<FileDirItem> {
val fileDirItems = ArrayList<FileDirItem>() val fileDirItems = ArrayList<FileDirItem>()
val showHidden = context?.config?.shouldShowHidden() ?: return fileDirItems val showHidden = context?.config?.shouldShowHidden() ?: return fileDirItems
val uri = MediaStore.Files.getContentUri("external") val uri = MediaStore.Files.getContentUri(volumeName)
val projection = arrayOf( val projection = arrayOf(
MediaStore.Files.FileColumns.DATA, MediaStore.Files.FileColumns.DATA,
MediaStore.Files.FileColumns.DISPLAY_NAME, MediaStore.Files.FileColumns.DISPLAY_NAME,
@ -396,8 +478,8 @@ class StorageFragment(context: Context, attributeSet: AttributeSet) : MyViewPage
override fun refreshFragment() { override fun refreshFragment() {
ensureBackgroundThread { ensureBackgroundThread {
val fileDirItems = getAllFiles() val fileDirItems = volumes.keys.map { getAllFiles(it) }.flatten()
allDeviceListItems = getListItemsFromFileDirItems(fileDirItems) allDeviceListItems = getListItemsFromFileDirItems(ArrayList(fileDirItems))
} }
setupLayoutManager() setupLayoutManager()
} }

View File

@ -41,6 +41,9 @@ const val ARCHIVES = "archives"
const val OTHERS = "others" const val OTHERS = "others"
const val SHOW_MIMETYPE = "show_mimetype" const val SHOW_MIMETYPE = "show_mimetype"
const val VOLUME_NAME = "volume_name"
const val PRIMARY_VOLUME_NAME = "external_primary"
// what else should we count as an audio except "audio/*" mimetype // what else should we count as an audio except "audio/*" mimetype
val extraAudioMimeTypes = arrayListOf("application/ogg") val extraAudioMimeTypes = arrayListOf("application/ogg")
val extraDocumentMimeTypes = arrayListOf( val extraDocumentMimeTypes = arrayListOf(

View File

@ -0,0 +1,5 @@
<vector android:height="24dp" android:tint="#FFFFFF"
android:viewportHeight="24" android:viewportWidth="24"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="@android:color/white" android:pathData="M7.41,8.59L12,13.17l4.59,-4.58L18,10l-6,6 -6,-6 1.41,-1.41z"/>
</vector>

View File

@ -0,0 +1,5 @@
<vector android:height="24dp" android:tint="#FFFFFF"
android:viewportHeight="24" android:viewportWidth="24"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="@android:color/white" android:pathData="M7.41,15.41L12,10.83l4.59,4.58L18,14l-6,-6 -6,6z"/>
</vector>

View File

@ -0,0 +1,328 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/storage_holder"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:animateLayoutChanges="true"
tools:ignore="HardcodedText">
<RelativeLayout
android:id="@+id/free_space_holder"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/selectableItemBackground"
android:paddingStart="@dimen/activity_margin"
android:paddingTop="@dimen/activity_margin"
android:paddingEnd="@dimen/activity_margin"
app:layout_constraintTop_toTopOf="parent">
<com.simplemobiletools.commons.views.MyTextView
android:id="@+id/storage_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_toStartOf="@+id/expand_button"
android:ellipsize="end"
android:maxLines="1"
android:text="@string/internal"
android:textSize="@dimen/big_text_size" />
<com.simplemobiletools.commons.views.MyTextView
android:id="@+id/free_space_value"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/storage_name"
android:text="…"
android:textSize="@dimen/storage_free_space_text_size"
tools:text="23 GB" />
<ImageView
android:id="@+id/expand_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_alignParentEnd="true"
android:padding="@dimen/medium_margin"
android:src="@drawable/ic_arrow_up_vector" />
<com.simplemobiletools.commons.views.MyTextView
android:id="@+id/free_space_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="@+id/total_space"
android:layout_alignBaseline="@+id/free_space_value"
android:layout_alignBottom="@+id/free_space_value"
android:layout_marginStart="@dimen/medium_margin"
android:layout_toEndOf="@+id/free_space_value"
android:text="@string/storage_free"
android:textSize="@dimen/big_text_size"
android:visibility="invisible" />
<com.google.android.material.progressindicator.LinearProgressIndicator
android:id="@+id/main_storage_usage_progressbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/free_space_value"
android:layout_marginTop="@dimen/medium_margin"
android:layout_marginBottom="@dimen/medium_margin"
android:max="100"
app:trackThickness="4dp" />
<com.simplemobiletools.commons.views.MyTextView
android:id="@+id/total_space"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/main_storage_usage_progressbar"
android:layout_marginBottom="@dimen/big_margin"
android:textSize="@dimen/big_text_size"
tools:text="Total storage: 64 GB" />
</RelativeLayout>
<RelativeLayout
android:id="@+id/images_holder"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/selectableItemBackground"
android:paddingStart="@dimen/activity_margin"
android:paddingTop="@dimen/normal_margin"
android:paddingEnd="@dimen/activity_margin"
android:paddingBottom="@dimen/normal_margin"
app:layout_constraintTop_toBottomOf="@+id/free_space_holder">
<com.simplemobiletools.commons.views.MyTextView
android:id="@+id/images_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_toStartOf="@+id/images_size"
android:text="@string/images"
android:textSize="@dimen/bigger_text_size" />
<com.simplemobiletools.commons.views.MyTextView
android:id="@+id/images_size"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:alpha="0.7"
android:text="…"
android:textSize="@dimen/normal_text_size"
tools:text="20 GB" />
<com.google.android.material.progressindicator.LinearProgressIndicator
android:id="@+id/images_progressbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/images_label"
android:layout_marginTop="@dimen/medium_margin"
android:layout_marginBottom="@dimen/medium_margin"
android:max="100"
app:trackThickness="2dp" />
</RelativeLayout>
<RelativeLayout
android:id="@+id/videos_holder"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/selectableItemBackground"
android:paddingStart="@dimen/activity_margin"
android:paddingTop="@dimen/normal_margin"
android:paddingEnd="@dimen/activity_margin"
android:paddingBottom="@dimen/normal_margin"
app:layout_constraintTop_toBottomOf="@+id/images_holder">
<com.simplemobiletools.commons.views.MyTextView
android:id="@+id/videos_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_toStartOf="@+id/videos_size"
android:text="@string/videos"
android:textSize="@dimen/bigger_text_size" />
<com.simplemobiletools.commons.views.MyTextView
android:id="@+id/videos_size"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:alpha="0.7"
android:text="…"
android:textSize="@dimen/normal_text_size"
tools:text="20 GB" />
<com.google.android.material.progressindicator.LinearProgressIndicator
android:id="@+id/videos_progressbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/videos_label"
android:layout_marginTop="@dimen/medium_margin"
android:layout_marginBottom="@dimen/medium_margin"
android:max="100"
app:trackThickness="2dp" />
</RelativeLayout>
<RelativeLayout
android:id="@+id/audio_holder"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/selectableItemBackground"
android:paddingStart="@dimen/activity_margin"
android:paddingTop="@dimen/normal_margin"
android:paddingEnd="@dimen/activity_margin"
android:paddingBottom="@dimen/normal_margin"
app:layout_constraintTop_toBottomOf="@+id/videos_holder">
<com.simplemobiletools.commons.views.MyTextView
android:id="@+id/audio_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_toStartOf="@+id/audio_size"
android:text="@string/audio"
android:textSize="@dimen/bigger_text_size" />
<com.simplemobiletools.commons.views.MyTextView
android:id="@+id/audio_size"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:alpha="0.7"
android:text="…"
android:textSize="@dimen/normal_text_size"
tools:text="20 GB" />
<com.google.android.material.progressindicator.LinearProgressIndicator
android:id="@+id/audio_progressbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/audio_label"
android:layout_marginTop="@dimen/medium_margin"
android:layout_marginBottom="@dimen/medium_margin"
android:max="100"
app:trackThickness="2dp" />
</RelativeLayout>
<RelativeLayout
android:id="@+id/documents_holder"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/selectableItemBackground"
android:paddingStart="@dimen/activity_margin"
android:paddingTop="@dimen/normal_margin"
android:paddingEnd="@dimen/activity_margin"
android:paddingBottom="@dimen/normal_margin"
app:layout_constraintTop_toBottomOf="@+id/audio_holder">
<com.simplemobiletools.commons.views.MyTextView
android:id="@+id/documents_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_toStartOf="@+id/documents_size"
android:text="@string/documents"
android:textSize="@dimen/bigger_text_size" />
<com.simplemobiletools.commons.views.MyTextView
android:id="@+id/documents_size"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:alpha="0.7"
android:text="…"
android:textSize="@dimen/normal_text_size"
tools:text="20 GB" />
<com.google.android.material.progressindicator.LinearProgressIndicator
android:id="@+id/documents_progressbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/documents_label"
android:layout_marginTop="@dimen/medium_margin"
android:layout_marginBottom="@dimen/medium_margin"
android:max="100"
app:trackThickness="2dp" />
</RelativeLayout>
<RelativeLayout
android:id="@+id/archives_holder"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/selectableItemBackground"
android:paddingStart="@dimen/activity_margin"
android:paddingTop="@dimen/normal_margin"
android:paddingEnd="@dimen/activity_margin"
android:paddingBottom="@dimen/normal_margin"
app:layout_constraintTop_toBottomOf="@+id/documents_holder">
<com.simplemobiletools.commons.views.MyTextView
android:id="@+id/archives_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_toStartOf="@+id/archives_size"
android:text="@string/archives"
android:textSize="@dimen/bigger_text_size" />
<com.simplemobiletools.commons.views.MyTextView
android:id="@+id/archives_size"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:alpha="0.7"
android:text="…"
android:textSize="@dimen/normal_text_size"
tools:text="20 GB" />
<com.google.android.material.progressindicator.LinearProgressIndicator
android:id="@+id/archives_progressbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/archives_label"
android:layout_marginTop="@dimen/medium_margin"
android:layout_marginBottom="@dimen/medium_margin"
android:max="100"
app:trackThickness="2dp" />
</RelativeLayout>
<RelativeLayout
android:id="@+id/others_holder"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/selectableItemBackground"
android:paddingStart="@dimen/activity_margin"
android:paddingTop="@dimen/normal_margin"
android:paddingEnd="@dimen/activity_margin"
android:paddingBottom="@dimen/normal_margin"
app:layout_constraintTop_toBottomOf="@+id/archives_holder">
<com.simplemobiletools.commons.views.MyTextView
android:id="@+id/others_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_toStartOf="@+id/others_size"
android:text="@string/others"
android:textSize="@dimen/bigger_text_size" />
<com.simplemobiletools.commons.views.MyTextView
android:id="@+id/others_size"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:alpha="0.7"
android:text="…"
android:textSize="@dimen/normal_text_size"
tools:text="20 GB" />
<com.google.android.material.progressindicator.LinearProgressIndicator
android:id="@+id/others_progressbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/others_label"
android:layout_marginTop="@dimen/medium_margin"
android:layout_marginBottom="@dimen/medium_margin"
android:max="100"
app:trackThickness="2dp" />
</RelativeLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -11,309 +11,12 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content"> android:layout_height="wrap_content">
<androidx.constraintlayout.widget.ConstraintLayout <LinearLayout
android:id="@+id/storage_holder" android:id="@+id/storage_volumes_holder"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="wrap_content"
tools:ignore="HardcodedText"> android:orientation="vertical" />
<RelativeLayout
android:id="@+id/free_space_holder"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/selectableItemBackground"
android:paddingStart="@dimen/activity_margin"
android:paddingTop="@dimen/activity_margin"
android:paddingEnd="@dimen/activity_margin"
app:layout_constraintTop_toTopOf="parent">
<com.simplemobiletools.commons.views.MyTextView
android:id="@+id/free_space_value"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="…"
android:textSize="@dimen/storage_free_space_text_size"
tools:text="23 GB" />
<com.simplemobiletools.commons.views.MyTextView
android:id="@+id/free_space_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="@+id/total_space"
android:layout_alignBaseline="@+id/free_space_value"
android:layout_alignBottom="@+id/free_space_value"
android:layout_marginStart="@dimen/medium_margin"
android:layout_toEndOf="@+id/free_space_value"
android:text="@string/storage_free"
android:textSize="@dimen/big_text_size"
android:visibility="invisible" />
<com.google.android.material.progressindicator.LinearProgressIndicator
android:id="@+id/main_storage_usage_progressbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/free_space_value"
android:layout_marginTop="@dimen/medium_margin"
android:layout_marginBottom="@dimen/medium_margin"
android:max="100"
app:trackThickness="4dp" />
<com.simplemobiletools.commons.views.MyTextView
android:id="@+id/total_space"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/main_storage_usage_progressbar"
android:layout_marginBottom="@dimen/big_margin"
android:textSize="@dimen/big_text_size"
tools:text="Total storage: 64 GB" />
</RelativeLayout>
<RelativeLayout
android:id="@+id/images_holder"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/selectableItemBackground"
android:paddingStart="@dimen/activity_margin"
android:paddingTop="@dimen/normal_margin"
android:paddingEnd="@dimen/activity_margin"
android:paddingBottom="@dimen/normal_margin"
app:layout_constraintTop_toBottomOf="@+id/free_space_holder">
<com.simplemobiletools.commons.views.MyTextView
android:id="@+id/images_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_toStartOf="@+id/images_size"
android:text="@string/images"
android:textSize="@dimen/bigger_text_size" />
<com.simplemobiletools.commons.views.MyTextView
android:id="@+id/images_size"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:alpha="0.7"
android:text="…"
android:textSize="@dimen/normal_text_size"
tools:text="20 GB" />
<com.google.android.material.progressindicator.LinearProgressIndicator
android:id="@+id/images_progressbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/images_label"
android:layout_marginTop="@dimen/medium_margin"
android:layout_marginBottom="@dimen/medium_margin"
android:max="100"
app:trackThickness="2dp" />
</RelativeLayout>
<RelativeLayout
android:id="@+id/videos_holder"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/selectableItemBackground"
android:paddingStart="@dimen/activity_margin"
android:paddingTop="@dimen/normal_margin"
android:paddingEnd="@dimen/activity_margin"
android:paddingBottom="@dimen/normal_margin"
app:layout_constraintTop_toBottomOf="@+id/images_holder">
<com.simplemobiletools.commons.views.MyTextView
android:id="@+id/videos_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_toStartOf="@+id/videos_size"
android:text="@string/videos"
android:textSize="@dimen/bigger_text_size" />
<com.simplemobiletools.commons.views.MyTextView
android:id="@+id/videos_size"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:alpha="0.7"
android:text="…"
android:textSize="@dimen/normal_text_size"
tools:text="20 GB" />
<com.google.android.material.progressindicator.LinearProgressIndicator
android:id="@+id/videos_progressbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/videos_label"
android:layout_marginTop="@dimen/medium_margin"
android:layout_marginBottom="@dimen/medium_margin"
android:max="100"
app:trackThickness="2dp" />
</RelativeLayout>
<RelativeLayout
android:id="@+id/audio_holder"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/selectableItemBackground"
android:paddingStart="@dimen/activity_margin"
android:paddingTop="@dimen/normal_margin"
android:paddingEnd="@dimen/activity_margin"
android:paddingBottom="@dimen/normal_margin"
app:layout_constraintTop_toBottomOf="@+id/videos_holder">
<com.simplemobiletools.commons.views.MyTextView
android:id="@+id/audio_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_toStartOf="@+id/audio_size"
android:text="@string/audio"
android:textSize="@dimen/bigger_text_size" />
<com.simplemobiletools.commons.views.MyTextView
android:id="@+id/audio_size"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:alpha="0.7"
android:text="…"
android:textSize="@dimen/normal_text_size"
tools:text="20 GB" />
<com.google.android.material.progressindicator.LinearProgressIndicator
android:id="@+id/audio_progressbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/audio_label"
android:layout_marginTop="@dimen/medium_margin"
android:layout_marginBottom="@dimen/medium_margin"
android:max="100"
app:trackThickness="2dp" />
</RelativeLayout>
<RelativeLayout
android:id="@+id/documents_holder"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/selectableItemBackground"
android:paddingStart="@dimen/activity_margin"
android:paddingTop="@dimen/normal_margin"
android:paddingEnd="@dimen/activity_margin"
android:paddingBottom="@dimen/normal_margin"
app:layout_constraintTop_toBottomOf="@+id/audio_holder">
<com.simplemobiletools.commons.views.MyTextView
android:id="@+id/documents_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_toStartOf="@+id/documents_size"
android:text="@string/documents"
android:textSize="@dimen/bigger_text_size" />
<com.simplemobiletools.commons.views.MyTextView
android:id="@+id/documents_size"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:alpha="0.7"
android:text="…"
android:textSize="@dimen/normal_text_size"
tools:text="20 GB" />
<com.google.android.material.progressindicator.LinearProgressIndicator
android:id="@+id/documents_progressbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/documents_label"
android:layout_marginTop="@dimen/medium_margin"
android:layout_marginBottom="@dimen/medium_margin"
android:max="100"
app:trackThickness="2dp" />
</RelativeLayout>
<RelativeLayout
android:id="@+id/archives_holder"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/selectableItemBackground"
android:paddingStart="@dimen/activity_margin"
android:paddingTop="@dimen/normal_margin"
android:paddingEnd="@dimen/activity_margin"
android:paddingBottom="@dimen/normal_margin"
app:layout_constraintTop_toBottomOf="@+id/documents_holder">
<com.simplemobiletools.commons.views.MyTextView
android:id="@+id/archives_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_toStartOf="@+id/archives_size"
android:text="@string/archives"
android:textSize="@dimen/bigger_text_size" />
<com.simplemobiletools.commons.views.MyTextView
android:id="@+id/archives_size"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:alpha="0.7"
android:text="…"
android:textSize="@dimen/normal_text_size"
tools:text="20 GB" />
<com.google.android.material.progressindicator.LinearProgressIndicator
android:id="@+id/archives_progressbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/archives_label"
android:layout_marginTop="@dimen/medium_margin"
android:layout_marginBottom="@dimen/medium_margin"
android:max="100"
app:trackThickness="2dp" />
</RelativeLayout>
<RelativeLayout
android:id="@+id/others_holder"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/selectableItemBackground"
android:paddingStart="@dimen/activity_margin"
android:paddingTop="@dimen/normal_margin"
android:paddingEnd="@dimen/activity_margin"
android:paddingBottom="@dimen/normal_margin"
app:layout_constraintTop_toBottomOf="@+id/archives_holder">
<com.simplemobiletools.commons.views.MyTextView
android:id="@+id/others_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_toStartOf="@+id/others_size"
android:text="@string/others"
android:textSize="@dimen/bigger_text_size" />
<com.simplemobiletools.commons.views.MyTextView
android:id="@+id/others_size"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:alpha="0.7"
android:text="…"
android:textSize="@dimen/normal_text_size"
tools:text="20 GB" />
<com.google.android.material.progressindicator.LinearProgressIndicator
android:id="@+id/others_progressbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/others_label"
android:layout_marginTop="@dimen/medium_margin"
android:layout_marginBottom="@dimen/medium_margin"
android:max="100"
app:trackThickness="2dp" />
</RelativeLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.core.widget.NestedScrollView> </androidx.core.widget.NestedScrollView>
<RelativeLayout <RelativeLayout