From 2fe98d731d97974ca57dbb3449f2a2e2b8a1c0f5 Mon Sep 17 00:00:00 2001 From: daniele-verducci Date: Thu, 5 Nov 2026 14:58:29 +0100 Subject: [PATCH 1/2] Meaningful storage name in picker Signed-off-by: daniele-verducci --- .../com/nextcloud/utils/extensions/FileExtensions.kt | 12 ++++++++++++ .../android/ui/activity/UploadFilesActivity.kt | 11 +++++++++-- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/com/nextcloud/utils/extensions/FileExtensions.kt b/app/src/main/java/com/nextcloud/utils/extensions/FileExtensions.kt index ba28525f7ae7..49ef56ca4f94 100644 --- a/app/src/main/java/com/nextcloud/utils/extensions/FileExtensions.kt +++ b/app/src/main/java/com/nextcloud/utils/extensions/FileExtensions.kt @@ -7,7 +7,9 @@ package com.nextcloud.utils.extensions +import android.content.Context import android.graphics.Bitmap +import android.os.storage.StorageManager import android.util.Log import androidx.exifinterface.media.ExifInterface import com.nextcloud.utils.HumanReadableFormatter @@ -59,6 +61,16 @@ fun File?.logFileSize(tag: String) { Log_OC.d(tag, "onSaveInstanceState: $size, raw byte $rawByte") } +/** + * Returns a user-readable name for the storage containing this file + */ +fun File.getStorageMeaningfulName(context: Context): String? { + val storageManager = context.getSystemService(Context.STORAGE_SERVICE) as StorageManager + val cFile = canonicalFile // resolves symlinks, i.e. /sdcard is a symlink to /storage/emulated/0 + val volume = storageManager.getStorageVolume(cFile) + return volume?.getDescription(context) +} + fun Path.toLocalPath(): String = toAbsolutePath().toString() /** diff --git a/app/src/main/java/com/owncloud/android/ui/activity/UploadFilesActivity.kt b/app/src/main/java/com/owncloud/android/ui/activity/UploadFilesActivity.kt index 4c450af20f75..6821736b56ef 100644 --- a/app/src/main/java/com/owncloud/android/ui/activity/UploadFilesActivity.kt +++ b/app/src/main/java/com/owncloud/android/ui/activity/UploadFilesActivity.kt @@ -35,6 +35,7 @@ import com.nextcloud.client.core.Clock import com.nextcloud.client.di.Injectable import com.nextcloud.client.jobs.upload.FileUploadHelper import com.nextcloud.client.jobs.upload.FileUploadWorker +import com.nextcloud.utils.extensions.getStorageMeaningfulName import com.nextcloud.utils.extensions.hasEnabledParent import com.owncloud.android.R import com.owncloud.android.databinding.UploadFilesLayoutBinding @@ -485,10 +486,16 @@ class UploadFilesActivity : } private fun ArrayAdapter.addDirectoryHierarchy(directory: File?) { + // Add subfolder generateSequence(directory) { it.parentFile } - .takeWhile { it.parentFile != null } + .takeWhile { it.parentFile?.canRead() == true } .forEach { add(it.name) } - add(File.separator) + + // Add current storage root folder + directory ?: return + directory.getStorageMeaningfulName(this@UploadFilesActivity)?.apply { + add(this) + } } companion object { From cd96bb9bf7e4f16cc2cb78f817112ad651dd1f3c Mon Sep 17 00:00:00 2001 From: daniele-verducci Date: Fri, 6 Nov 2026 17:58:02 +0100 Subject: [PATCH 2/2] Fix null volume edge case causing activity finish() Signed-off-by: daniele-verducci --- .../utils/extensions/FileExtensions.kt | 12 --------- .../ui/activity/UploadFilesActivity.kt | 26 +++++++++++++------ 2 files changed, 18 insertions(+), 20 deletions(-) diff --git a/app/src/main/java/com/nextcloud/utils/extensions/FileExtensions.kt b/app/src/main/java/com/nextcloud/utils/extensions/FileExtensions.kt index 49ef56ca4f94..ba28525f7ae7 100644 --- a/app/src/main/java/com/nextcloud/utils/extensions/FileExtensions.kt +++ b/app/src/main/java/com/nextcloud/utils/extensions/FileExtensions.kt @@ -7,9 +7,7 @@ package com.nextcloud.utils.extensions -import android.content.Context import android.graphics.Bitmap -import android.os.storage.StorageManager import android.util.Log import androidx.exifinterface.media.ExifInterface import com.nextcloud.utils.HumanReadableFormatter @@ -61,16 +59,6 @@ fun File?.logFileSize(tag: String) { Log_OC.d(tag, "onSaveInstanceState: $size, raw byte $rawByte") } -/** - * Returns a user-readable name for the storage containing this file - */ -fun File.getStorageMeaningfulName(context: Context): String? { - val storageManager = context.getSystemService(Context.STORAGE_SERVICE) as StorageManager - val cFile = canonicalFile // resolves symlinks, i.e. /sdcard is a symlink to /storage/emulated/0 - val volume = storageManager.getStorageVolume(cFile) - return volume?.getDescription(context) -} - fun Path.toLocalPath(): String = toAbsolutePath().toString() /** diff --git a/app/src/main/java/com/owncloud/android/ui/activity/UploadFilesActivity.kt b/app/src/main/java/com/owncloud/android/ui/activity/UploadFilesActivity.kt index 6821736b56ef..70fd0488b30c 100644 --- a/app/src/main/java/com/owncloud/android/ui/activity/UploadFilesActivity.kt +++ b/app/src/main/java/com/owncloud/android/ui/activity/UploadFilesActivity.kt @@ -20,6 +20,7 @@ import android.app.Activity import android.content.Intent import android.os.Bundle import android.os.Environment +import android.os.storage.StorageManager import android.view.Menu import android.view.MenuInflater import android.view.MenuItem @@ -35,7 +36,6 @@ import com.nextcloud.client.core.Clock import com.nextcloud.client.di.Injectable import com.nextcloud.client.jobs.upload.FileUploadHelper import com.nextcloud.client.jobs.upload.FileUploadWorker -import com.nextcloud.utils.extensions.getStorageMeaningfulName import com.nextcloud.utils.extensions.hasEnabledParent import com.owncloud.android.R import com.owncloud.android.databinding.UploadFilesLayoutBinding @@ -95,6 +95,7 @@ class UploadFilesActivity : private var optionsMenu: Menu? = null private var searchView: SearchView? = null private var chosenFilePaths: Array? = null + private val androidStorageManager by lazy { getSystemService(StorageManager::class.java) } private val isRoot: Boolean get() = currentDir?.absolutePath == ROOT_DIR @@ -486,16 +487,25 @@ class UploadFilesActivity : } private fun ArrayAdapter.addDirectoryHierarchy(directory: File?) { - // Add subfolder + val volume = directory?.let { androidStorageManager.getStorageVolume(it) } + + // Fallback to full path + if (volume == null) { + generateSequence(directory) { it.parentFile } + .takeWhile { it.parentFile != null } + .forEach { add(it.name) } + add(File.separator) + return + } + + // Show user-readable path generateSequence(directory) { it.parentFile } - .takeWhile { it.parentFile?.canRead() == true } + .takeWhile { dir -> + dir.parentFile?.let { androidStorageManager.getStorageVolume(it) } == volume + } .forEach { add(it.name) } - // Add current storage root folder - directory ?: return - directory.getStorageMeaningfulName(this@UploadFilesActivity)?.apply { - add(this) - } + add(volume.getDescription(this@UploadFilesActivity)) } companion object {