From d24985f680cd88d06a2201647b1f87ea0f87956f Mon Sep 17 00:00:00 2001 From: Hai Zhang Date: Thu, 18 Apr 2024 01:52:18 -0700 Subject: [PATCH] Feat: Add root ID and path editing for external storage shortcut Fixes: #1206 --- app/src/main/AndroidManifest.xml | 8 +- .../zhanghai/android/files/app/AppUpgrader.kt | 4 + .../android/files/app/AppUpgraders.kt | 89 +++++++++++++++++++ .../android/files/file/DocumentUri.kt | 3 + .../android/files/file/ExternalStorageUri.kt | 55 ++++++++++++ ... => AddExternalStorageShortcutActivity.kt} | 8 +- ... => AddExternalStorageShortcutFragment.kt} | 22 ++--- .../files/storage/AddStorageDialogFragment.kt | 18 ++-- ...tExternalStorageShortcutDialogActivity.kt} | 8 +- ...tExternalStorageShortcutDialogFragment.kt} | 71 ++++++++------- ...Shortcut.kt => ExternalStorageShortcut.kt} | 19 ++-- .../android/files/util/IntentExtensions.kt | 2 +- ...edit_external_storage_shortcut_dialog.xml} | 26 ++++-- app/src/main/res/values-ar/strings.xml | 4 - app/src/main/res/values-bg/strings.xml | 4 - app/src/main/res/values-ca/strings.xml | 4 - app/src/main/res/values-cs/strings.xml | 2 - app/src/main/res/values-de/strings.xml | 4 - app/src/main/res/values-el/strings.xml | 4 - app/src/main/res/values-es/strings.xml | 4 - app/src/main/res/values-fi/strings.xml | 4 - app/src/main/res/values-fr/strings.xml | 4 - app/src/main/res/values-hu/strings.xml | 4 - app/src/main/res/values-in/strings.xml | 4 - app/src/main/res/values-is/strings.xml | 4 - app/src/main/res/values-it/strings.xml | 4 - app/src/main/res/values-iw/strings.xml | 4 - app/src/main/res/values-ja/strings.xml | 4 - app/src/main/res/values-ko/strings.xml | 4 - app/src/main/res/values-lt/strings.xml | 4 - app/src/main/res/values-nb/strings.xml | 4 - app/src/main/res/values-nl/strings.xml | 4 - app/src/main/res/values-pl/strings.xml | 4 - app/src/main/res/values-pt-rBR/strings.xml | 4 - app/src/main/res/values-pt-rPT/strings.xml | 4 - app/src/main/res/values-ro/strings.xml | 4 - app/src/main/res/values-ru/strings.xml | 4 - app/src/main/res/values-uk/strings.xml | 4 - app/src/main/res/values-zh-rCN/strings.xml | 9 +- app/src/main/res/values-zh-rTW/strings.xml | 9 +- app/src/main/res/values/strings.xml | 9 +- 41 files changed, 265 insertions(+), 193 deletions(-) create mode 100644 app/src/main/java/me/zhanghai/android/files/file/ExternalStorageUri.kt rename app/src/main/java/me/zhanghai/android/files/storage/{AddDocumentManagerShortcutActivity.kt => AddExternalStorageShortcutActivity.kt} (73%) rename app/src/main/java/me/zhanghai/android/files/storage/{AddDocumentManagerShortcutFragment.kt => AddExternalStorageShortcutFragment.kt} (56%) rename app/src/main/java/me/zhanghai/android/files/storage/{EditDocumentManagerShortcutDialogActivity.kt => EditExternalStorageShortcutDialogActivity.kt} (74%) rename app/src/main/java/me/zhanghai/android/files/storage/{EditDocumentManagerShortcutDialogFragment.kt => EditExternalStorageShortcutDialogFragment.kt} (56%) rename app/src/main/java/me/zhanghai/android/files/storage/{DocumentManagerShortcut.kt => ExternalStorageShortcut.kt} (64%) rename app/src/main/res/layout/{edit_document_manager_shortcut_dialog.xml => edit_external_storage_shortcut_dialog.xml} (69%) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index ef2e940b5..4479e3e09 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -179,13 +179,13 @@ android:theme="@style/Theme.MaterialFiles.Translucent" /> + Parcel.obtain().use { oldParcel -> + oldParcel.unmarshall(oldBytes, 0, oldBytes.size) + oldParcel.setDataPosition(0) + newParcel.writeInt(oldParcel.readInt()) + readWriteLengthPrefixedValue(oldParcel, newParcel) { + val size = oldParcel.readInt() + newParcel.writeInt(size) + repeat(size) { + val oldPosition = oldParcel.dataPosition() + oldParcel.readInt() + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { + // Skip prefix length. + oldParcel.readInt() + } + val className = oldParcel.readString() + oldParcel.setDataPosition(oldPosition) + when (className) { + "me.zhanghai.android.files.storage.DocumentManagerShortcut" -> { + newParcel.writeInt(oldParcel.readInt()) + readWriteLengthPrefixedValue(oldParcel, newParcel) { + oldParcel.readString() + newParcel.writeString( + "me.zhanghai.android.files.storage" + + ".ExternalStorageShortcut" + ) + val id = oldParcel.readLong() + newParcel.writeLong(id) + val customName = oldParcel.readString() + newParcel.writeString(customName) + var uri = StableUriParceler.create(oldParcel)!! + if (uri.asExternalStorageUriOrNull() == null) { + // Reset to a valid external storage URI. + uri = + ExternalStorageProviderHacks + .DOCUMENT_URI_ANDROID_DATA + } + with(StableUriParceler) { uri.write(newParcel, 0) } + } + } + else -> { + val storage = oldParcel.readValue(appClassLoader) + newParcel.writeValue(storage) + } + } + } + } + } + newParcel.marshall() + } + } catch (e: Exception) { + e.printStackTrace() + null + } + defaultSharedPreferences.edit { putString(key, newBytes?.toBase64()?.value) } +} + +private fun readWriteLengthPrefixedValue(oldParcel: Parcel, newParcel: Parcel, block: () -> Unit) { + var lengthPosition = 0 + var startPosition = 0 + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { + oldParcel.readInt() + lengthPosition = newParcel.dataPosition() + newParcel.writeInt(-1) + startPosition = newParcel.dataPosition() + } + block() + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { + val endPosition = newParcel.dataPosition() + newParcel.setDataPosition(lengthPosition) + newParcel.writeInt(endPosition - startPosition) + newParcel.setDataPosition(endPosition) + } +} diff --git a/app/src/main/java/me/zhanghai/android/files/file/DocumentUri.kt b/app/src/main/java/me/zhanghai/android/files/file/DocumentUri.kt index 704008edb..fac458337 100644 --- a/app/src/main/java/me/zhanghai/android/files/file/DocumentUri.kt +++ b/app/src/main/java/me/zhanghai/android/files/file/DocumentUri.kt @@ -17,6 +17,9 @@ import me.zhanghai.android.files.util.StableUriParceler @Parcelize @JvmInline value class DocumentUri(val value: @WriteWith Uri) : Parcelable { + val treeDocumentId: String + get() = DocumentsContract.getTreeDocumentId(value) + val documentId: String get() = DocumentsContract.getDocumentId(value) } diff --git a/app/src/main/java/me/zhanghai/android/files/file/ExternalStorageUri.kt b/app/src/main/java/me/zhanghai/android/files/file/ExternalStorageUri.kt new file mode 100644 index 000000000..35607d206 --- /dev/null +++ b/app/src/main/java/me/zhanghai/android/files/file/ExternalStorageUri.kt @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2024 Hai Zhang + * All Rights Reserved. + */ + +package me.zhanghai.android.files.file + +import android.net.Uri +import android.os.Parcelable +import android.provider.DocumentsContract +import kotlinx.parcelize.Parcelize +import kotlinx.parcelize.WriteWith +import me.zhanghai.android.files.compat.DocumentsContractCompat +import me.zhanghai.android.files.util.StableUriParceler + +@Parcelize +@JvmInline +value class ExternalStorageUri(val value: @WriteWith Uri) : Parcelable { + constructor(rootId: String, path: String) : this( + DocumentsContract.buildDocumentUriUsingTree( + DocumentsContract.buildTreeDocumentUri( + DocumentsContractCompat.EXTERNAL_STORAGE_PROVIDER_AUTHORITY, rootId + ), "$rootId:$path" + ) + ) + + val rootId: String + get() = DocumentsContract.getTreeDocumentId(value) + + val path: String + get() = DocumentsContract.getDocumentId(value).removePrefix("$rootId:") +} + +fun Uri.asExternalStorageUriOrNull(): ExternalStorageUri? = + if (isExternalStorageUri) ExternalStorageUri(this) else null + +fun Uri.asExternalStorageUri(): ExternalStorageUri { + require(isExternalStorageUri) + return ExternalStorageUri(this) +} + +/** @see DocumentsContractCompat.isDocumentUri */ +private val Uri.isExternalStorageUri: Boolean + get() = + DocumentsContractCompat.isDocumentUri(this) && + authority == DocumentsContractCompat.EXTERNAL_STORAGE_PROVIDER_AUTHORITY && + pathSegments.size == 4 + +val ExternalStorageUri.displayName: String + get() = + if (rootId == DocumentsContractCompat.EXTERNAL_STORAGE_PRIMARY_EMULATED_ROOT_ID) { + path + } else { + DocumentsContract.getDocumentId(value) + } diff --git a/app/src/main/java/me/zhanghai/android/files/storage/AddDocumentManagerShortcutActivity.kt b/app/src/main/java/me/zhanghai/android/files/storage/AddExternalStorageShortcutActivity.kt similarity index 73% rename from app/src/main/java/me/zhanghai/android/files/storage/AddDocumentManagerShortcutActivity.kt rename to app/src/main/java/me/zhanghai/android/files/storage/AddExternalStorageShortcutActivity.kt index 8cb975f84..0f8a68db1 100644 --- a/app/src/main/java/me/zhanghai/android/files/storage/AddDocumentManagerShortcutActivity.kt +++ b/app/src/main/java/me/zhanghai/android/files/storage/AddExternalStorageShortcutActivity.kt @@ -12,8 +12,8 @@ import me.zhanghai.android.files.app.AppActivity import me.zhanghai.android.files.util.args import me.zhanghai.android.files.util.putArgs -class AddDocumentManagerShortcutActivity : AppActivity() { - private val args by args() +class AddExternalStorageShortcutActivity : AppActivity() { + private val args by args() override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -21,9 +21,9 @@ class AddDocumentManagerShortcutActivity : AppActivity() { // Calls ensureSubDecor(). findViewById(android.R.id.content) if (savedInstanceState == null) { - val fragment = AddDocumentManagerShortcutFragment().putArgs(args) + val fragment = AddExternalStorageShortcutFragment().putArgs(args) supportFragmentManager.commit { - add(fragment, AddDocumentManagerShortcutFragment::class.java.name) + add(fragment, AddExternalStorageShortcutFragment::class.java.name) } } } diff --git a/app/src/main/java/me/zhanghai/android/files/storage/AddDocumentManagerShortcutFragment.kt b/app/src/main/java/me/zhanghai/android/files/storage/AddExternalStorageShortcutFragment.kt similarity index 56% rename from app/src/main/java/me/zhanghai/android/files/storage/AddDocumentManagerShortcutFragment.kt rename to app/src/main/java/me/zhanghai/android/files/storage/AddExternalStorageShortcutFragment.kt index c598bccc4..eeaefa1e6 100644 --- a/app/src/main/java/me/zhanghai/android/files/storage/AddDocumentManagerShortcutFragment.kt +++ b/app/src/main/java/me/zhanghai/android/files/storage/AddExternalStorageShortcutFragment.kt @@ -6,32 +6,29 @@ package me.zhanghai.android.files.storage import android.os.Bundle -import androidx.annotation.StringRes import androidx.fragment.app.Fragment import kotlinx.parcelize.Parcelize import me.zhanghai.android.files.R import me.zhanghai.android.files.app.packageManager -import me.zhanghai.android.files.file.DocumentUri +import me.zhanghai.android.files.file.ExternalStorageUri import me.zhanghai.android.files.util.ParcelableArgs import me.zhanghai.android.files.util.args -import me.zhanghai.android.files.util.createDocumentManagerViewDirectoryIntent +import me.zhanghai.android.files.util.createDocumentsUiViewDirectoryIntent import me.zhanghai.android.files.util.finish import me.zhanghai.android.files.util.showToast -class AddDocumentManagerShortcutFragment : Fragment() { +class AddExternalStorageShortcutFragment : Fragment() { private val args by args() override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) val uri = args.uri - val hasDocumentManager = uri.value.createDocumentManagerViewDirectoryIntent() + val hasDocumentsUi = uri.value.createDocumentsUiViewDirectoryIntent() .resolveActivity(packageManager) != null - if (hasDocumentManager) { - val documentManagerShortcut = DocumentManagerShortcut( - null, args.customNameRes?.let { getString(it) }, uri - ) - Storages.addOrReplace(documentManagerShortcut) + if (hasDocumentsUi) { + val externalStorageShortcut = ExternalStorageShortcut(null, null, uri) + Storages.addOrReplace(externalStorageShortcut) } else { showToast(R.string.activity_not_found) } @@ -39,8 +36,5 @@ class AddDocumentManagerShortcutFragment : Fragment() { } @Parcelize - class Args( - @StringRes val customNameRes: Int?, - val uri: DocumentUri - ) : ParcelableArgs + class Args(val uri: ExternalStorageUri) : ParcelableArgs } diff --git a/app/src/main/java/me/zhanghai/android/files/storage/AddStorageDialogFragment.kt b/app/src/main/java/me/zhanghai/android/files/storage/AddStorageDialogFragment.kt index 2d2c0ee36..d0f3085ae 100644 --- a/app/src/main/java/me/zhanghai/android/files/storage/AddStorageDialogFragment.kt +++ b/app/src/main/java/me/zhanghai/android/files/storage/AddStorageDialogFragment.kt @@ -12,7 +12,7 @@ import android.os.Bundle import androidx.appcompat.app.AppCompatDialogFragment import com.google.android.material.dialog.MaterialAlertDialogBuilder import me.zhanghai.android.files.R -import me.zhanghai.android.files.file.asDocumentUri +import me.zhanghai.android.files.file.asExternalStorageUri import me.zhanghai.android.files.provider.document.resolver.ExternalStorageProviderHacks import me.zhanghai.android.files.util.createIntent import me.zhanghai.android.files.util.finish @@ -42,19 +42,19 @@ class AddStorageDialogFragment : AppCompatDialogFragment() { private val STORAGE_TYPES = listOfNotNull( if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { R.string.storage_add_storage_android_data to - AddDocumentManagerShortcutActivity ::class.createIntent().putArgs( - AddDocumentManagerShortcutFragment.Args( - R.string.storage_add_storage_android_data, - ExternalStorageProviderHacks.DOCUMENT_URI_ANDROID_DATA.asDocumentUri() + AddExternalStorageShortcutActivity ::class.createIntent().putArgs( + AddExternalStorageShortcutFragment.Args( + ExternalStorageProviderHacks.DOCUMENT_URI_ANDROID_DATA + .asExternalStorageUri() ) ) } else null, if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { R.string.storage_add_storage_android_obb to - AddDocumentManagerShortcutActivity ::class.createIntent().putArgs( - AddDocumentManagerShortcutFragment.Args( - R.string.storage_add_storage_android_obb, - ExternalStorageProviderHacks.DOCUMENT_URI_ANDROID_OBB.asDocumentUri() + AddExternalStorageShortcutActivity ::class.createIntent().putArgs( + AddExternalStorageShortcutFragment.Args( + ExternalStorageProviderHacks.DOCUMENT_URI_ANDROID_OBB + .asExternalStorageUri() ) ) } else null, diff --git a/app/src/main/java/me/zhanghai/android/files/storage/EditDocumentManagerShortcutDialogActivity.kt b/app/src/main/java/me/zhanghai/android/files/storage/EditExternalStorageShortcutDialogActivity.kt similarity index 74% rename from app/src/main/java/me/zhanghai/android/files/storage/EditDocumentManagerShortcutDialogActivity.kt rename to app/src/main/java/me/zhanghai/android/files/storage/EditExternalStorageShortcutDialogActivity.kt index fb572849b..30da5915c 100644 --- a/app/src/main/java/me/zhanghai/android/files/storage/EditDocumentManagerShortcutDialogActivity.kt +++ b/app/src/main/java/me/zhanghai/android/files/storage/EditExternalStorageShortcutDialogActivity.kt @@ -12,8 +12,8 @@ import me.zhanghai.android.files.app.AppActivity import me.zhanghai.android.files.util.args import me.zhanghai.android.files.util.putArgs -class EditDocumentManagerShortcutDialogActivity : AppActivity() { - private val args by args() +class EditExternalStorageShortcutDialogActivity : AppActivity() { + private val args by args() override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -21,9 +21,9 @@ class EditDocumentManagerShortcutDialogActivity : AppActivity() { // Calls ensureSubDecor(). findViewById(android.R.id.content) if (savedInstanceState == null) { - val fragment = EditDocumentManagerShortcutDialogFragment().putArgs(args) + val fragment = EditExternalStorageShortcutDialogFragment().putArgs(args) supportFragmentManager.commit { - add(fragment, EditDocumentManagerShortcutDialogFragment::class.java.name) + add(fragment, EditExternalStorageShortcutDialogFragment::class.java.name) } } } diff --git a/app/src/main/java/me/zhanghai/android/files/storage/EditDocumentManagerShortcutDialogFragment.kt b/app/src/main/java/me/zhanghai/android/files/storage/EditExternalStorageShortcutDialogFragment.kt similarity index 56% rename from app/src/main/java/me/zhanghai/android/files/storage/EditDocumentManagerShortcutDialogFragment.kt rename to app/src/main/java/me/zhanghai/android/files/storage/EditExternalStorageShortcutDialogFragment.kt index dfd81b6e6..9fd868ea0 100644 --- a/app/src/main/java/me/zhanghai/android/files/storage/EditDocumentManagerShortcutDialogFragment.kt +++ b/app/src/main/java/me/zhanghai/android/files/storage/EditExternalStorageShortcutDialogFragment.kt @@ -7,17 +7,18 @@ package me.zhanghai.android.files.storage import android.app.Dialog import android.content.DialogInterface -import android.net.Uri import android.os.Bundle import android.view.WindowManager import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AppCompatDialogFragment +import androidx.core.widget.doAfterTextChanged import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.google.android.material.textfield.TextInputEditText import kotlinx.parcelize.Parcelize import me.zhanghai.android.files.R -import me.zhanghai.android.files.databinding.EditDocumentManagerShortcutDialogBinding -import me.zhanghai.android.files.file.asDocumentUriOrNull +import me.zhanghai.android.files.databinding.EditExternalStorageShortcutDialogBinding +import me.zhanghai.android.files.file.ExternalStorageUri +import me.zhanghai.android.files.file.displayName import me.zhanghai.android.files.util.ParcelableArgs import me.zhanghai.android.files.util.args import me.zhanghai.android.files.util.finish @@ -26,25 +27,27 @@ import me.zhanghai.android.files.util.layoutInflater import me.zhanghai.android.files.util.setTextWithSelection import me.zhanghai.android.files.util.takeIfNotEmpty -class EditDocumentManagerShortcutDialogFragment : AppCompatDialogFragment() { +class EditExternalStorageShortcutDialogFragment : AppCompatDialogFragment() { private val args by args() - private lateinit var binding: EditDocumentManagerShortcutDialogBinding + private lateinit var binding: EditExternalStorageShortcutDialogBinding override fun onCreateDialog(savedInstanceState: Bundle?): Dialog = MaterialAlertDialogBuilder(requireContext(), theme) - .setTitle(R.string.storage_edit_document_manager_shortcut_title) + .setTitle(R.string.storage_edit_external_storage_shortcut_title) .apply { - binding = EditDocumentManagerShortcutDialogBinding.inflate(context.layoutInflater) - val documentManagerShortcut = args.documentManagerShortcut - binding.nameLayout.placeholderText = - documentManagerShortcut.getDefaultName(binding.nameLayout.context) - binding.uriEdit.hideTextInputLayoutErrorOnTextChange(binding.uriLayout) + binding = EditExternalStorageShortcutDialogBinding.inflate(context.layoutInflater) + val externalStorageShortcut = args.externalStorageShortcut + binding.rootIdEdit.hideTextInputLayoutErrorOnTextChange(binding.rootIdLayout) + binding.rootIdEdit.doAfterTextChanged { updateNamePlaceholder() } + binding.pathEdit.doAfterTextChanged { updateNamePlaceholder() } if (savedInstanceState == null) { binding.nameEdit.setTextWithSelection( - documentManagerShortcut.getName(binding.nameEdit.context) + externalStorageShortcut.getName(binding.nameEdit.context) ) - binding.uriEdit.setText(documentManagerShortcut.uri.value.toString()) + val uri = externalStorageShortcut.uri + binding.rootIdEdit.setText(uri.rootId) + binding.pathEdit.setText(uri.path) } setView(binding.root) } @@ -60,41 +63,45 @@ class EditDocumentManagerShortcutDialogFragment : AppCompatDialogFragment() { } } + private fun updateNamePlaceholder() { + val rootId = binding.rootIdEdit.text.toString().takeIfNotEmpty() + val path = binding.pathEdit.text.toString().dropWhile { it == '/' } + binding.nameLayout.placeholderText = if (rootId != null) { + ExternalStorageUri(rootId, path).displayName + } else { + path + } + } + private fun save() { - val documentManagerShortcut = getDocumentManagerShortcutOrSetError() ?: return - Storages.replace(documentManagerShortcut) + val externalStorageShortcut = getExternalStorageShortcutOrSetError() ?: return + Storages.replace(externalStorageShortcut) finish() } - private fun getDocumentManagerShortcutOrSetError(): DocumentManagerShortcut? { + private fun getExternalStorageShortcutOrSetError(): ExternalStorageShortcut? { var errorEdit: TextInputEditText? = null val customName = binding.nameEdit.text.toString() .takeIf { it.isNotEmpty() && it != binding.nameLayout.placeholderText } - val uriText = binding.uriEdit.text.toString().takeIfNotEmpty() - if (uriText == null) { - binding.uriLayout.error = - getString(R.string.storage_edit_document_manager_shortcut_uri_error_empty) - if (errorEdit == null) { - errorEdit = binding.uriEdit - } - } - val uri = uriText?.let { Uri.parse(it).asDocumentUriOrNull() } - if (uriText != null && uri == null) { - binding.uriLayout.error = - getString(R.string.storage_edit_document_manager_shortcut_uri_error_invalid) + val rootId = binding.rootIdEdit.text.toString().takeIfNotEmpty() + if (rootId == null) { + binding.rootIdLayout.error = + getString(R.string.storage_edit_external_storage_shortcut_root_id_error_empty) if (errorEdit == null) { - errorEdit = binding.uriEdit + errorEdit = binding.rootIdEdit } } + val path = binding.pathEdit.text.toString().dropWhile { it == '/' } + val uri = rootId?.let { ExternalStorageUri(rootId, path) } if (errorEdit != null) { errorEdit.requestFocus() return null } - return DocumentManagerShortcut(args.documentManagerShortcut.id, customName, uri!!) + return ExternalStorageShortcut(args.externalStorageShortcut.id, customName, uri!!) } private fun remove() { - Storages.remove(args.documentManagerShortcut) + Storages.remove(args.externalStorageShortcut) finish() } @@ -105,5 +112,5 @@ class EditDocumentManagerShortcutDialogFragment : AppCompatDialogFragment() { } @Parcelize - class Args(val documentManagerShortcut: DocumentManagerShortcut) : ParcelableArgs + class Args(val externalStorageShortcut: ExternalStorageShortcut) : ParcelableArgs } diff --git a/app/src/main/java/me/zhanghai/android/files/storage/DocumentManagerShortcut.kt b/app/src/main/java/me/zhanghai/android/files/storage/ExternalStorageShortcut.kt similarity index 64% rename from app/src/main/java/me/zhanghai/android/files/storage/DocumentManagerShortcut.kt rename to app/src/main/java/me/zhanghai/android/files/storage/ExternalStorageShortcut.kt index 526f540fd..0aee55cd8 100644 --- a/app/src/main/java/me/zhanghai/android/files/storage/DocumentManagerShortcut.kt +++ b/app/src/main/java/me/zhanghai/android/files/storage/ExternalStorageShortcut.kt @@ -9,27 +9,26 @@ import android.content.Context import android.content.Intent import java8.nio.file.Path import kotlinx.parcelize.Parcelize -import me.zhanghai.android.files.file.DocumentUri +import me.zhanghai.android.files.file.ExternalStorageUri import me.zhanghai.android.files.file.displayName -import me.zhanghai.android.files.util.createDocumentManagerViewDirectoryIntent +import me.zhanghai.android.files.util.createDocumentsUiViewDirectoryIntent import me.zhanghai.android.files.util.createIntent import me.zhanghai.android.files.util.putArgs import kotlin.random.Random @Parcelize -data class DocumentManagerShortcut( +data class ExternalStorageShortcut( override val id: Long, override val customName: String?, - val uri: DocumentUri + val uri: ExternalStorageUri ) : Storage() { constructor( id: Long?, customName: String?, - uri: DocumentUri + uri: ExternalStorageUri ) : this(id ?: Random.nextLong(), customName, uri) - override fun getDefaultName(context: Context): String = - uri.displayName ?: uri.value.lastPathSegment ?: uri.value.toString() + override fun getDefaultName(context: Context): String = uri.displayName override val description: String get() = uri.value.toString() @@ -37,9 +36,9 @@ data class DocumentManagerShortcut( override val path: Path? get() = null - override fun createIntent(): Intent = uri.value.createDocumentManagerViewDirectoryIntent() + override fun createIntent(): Intent = uri.value.createDocumentsUiViewDirectoryIntent() override fun createEditIntent(): Intent = - EditDocumentManagerShortcutDialogActivity::class.createIntent() - .putArgs(EditDocumentManagerShortcutDialogFragment.Args(this)) + EditExternalStorageShortcutDialogActivity::class.createIntent() + .putArgs(EditExternalStorageShortcutDialogFragment.Args(this)) } diff --git a/app/src/main/java/me/zhanghai/android/files/util/IntentExtensions.kt b/app/src/main/java/me/zhanghai/android/files/util/IntentExtensions.kt index 95e7251c7..e7a0551ac 100644 --- a/app/src/main/java/me/zhanghai/android/files/util/IntentExtensions.kt +++ b/app/src/main/java/me/zhanghai/android/files/util/IntentExtensions.kt @@ -154,7 +154,7 @@ fun Collection.createSendStreamIntent(mimeTypes: Collection): Int removeFlagsCompat(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET) } -fun Uri.createDocumentManagerViewDirectoryIntent(): Intent = +fun Uri.createDocumentsUiViewDirectoryIntent(): Intent = createViewIntent(MimeType.DIRECTORY) .apply { DocumentsContractCompat.getDocumentsUiPackage()?.let { setPackage(it) } } diff --git a/app/src/main/res/layout/edit_document_manager_shortcut_dialog.xml b/app/src/main/res/layout/edit_external_storage_shortcut_dialog.xml similarity index 69% rename from app/src/main/res/layout/edit_document_manager_shortcut_dialog.xml rename to app/src/main/res/layout/edit_external_storage_shortcut_dialog.xml index ec18f9093..427669abf 100644 --- a/app/src/main/res/layout/edit_document_manager_shortcut_dialog.xml +++ b/app/src/main/res/layout/edit_external_storage_shortcut_dialog.xml @@ -30,7 +30,9 @@ android:id="@+id/nameLayout" android:layout_width="match_parent" android:layout_height="wrap_content" - android:hint="@string/storage_edit_document_tree_name"> + android:hint="@string/storage_edit_document_tree_name" + app:errorEnabled="true" + app:expandedHintEnabled="false"> + + + + + diff --git a/app/src/main/res/values-ar/strings.xml b/app/src/main/res/values-ar/strings.xml index 0146f5350..e99494975 100644 --- a/app/src/main/res/values-ar/strings.xml +++ b/app/src/main/res/values-ar/strings.xml @@ -545,10 +545,6 @@ تحرير وحدة تخزين الجهاز الاسم المسار - إضافة اختصار واجهة المستخدم للوثائق - تعديل اختصار واجهة المستخدم للوثائق - أدخل URI - URI غير صالح أضف وحدة تخزين خارجية تحرير وحدة التخزين الخارجية الاسم diff --git a/app/src/main/res/values-bg/strings.xml b/app/src/main/res/values-bg/strings.xml index 0c68b4bc3..26c9ea0cf 100644 --- a/app/src/main/res/values-bg/strings.xml +++ b/app/src/main/res/values-bg/strings.xml @@ -435,10 +435,6 @@ Редактиране на хранилище Име Път - Добавяне на пряк път за DocumentsUI - Променяне на пряк път за DocumentsUI - Въведете адрес - Неприемлив адрес Добавяне на външно хранилище Редакция на външно хранилище Име diff --git a/app/src/main/res/values-ca/strings.xml b/app/src/main/res/values-ca/strings.xml index 897a3f020..83b216c7e 100644 --- a/app/src/main/res/values-ca/strings.xml +++ b/app/src/main/res/values-ca/strings.xml @@ -435,10 +435,6 @@ Edita l\'emmagatzematge del dispositiu Nom Camí - Afegeix la drecera DocumentsUI - Edita la drecera DocumentsUI - Introduïu un URI - L\'URI no és vàlid Afegeix un emmagatzematge extern Edita l\'emmagatzematge extern Nom diff --git a/app/src/main/res/values-cs/strings.xml b/app/src/main/res/values-cs/strings.xml index c51e03780..2d97c57e0 100644 --- a/app/src/main/res/values-cs/strings.xml +++ b/app/src/main/res/values-cs/strings.xml @@ -493,8 +493,6 @@ Upravit úložiště zařízení Název Cesta - Zadejte URI - Neplatná URI Přidat externí úložiště Upravit externí úložiště Název diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index d04e3888f..f0d09fd43 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -435,10 +435,6 @@ Gerätespeicher bearbeiten Name Pfad - DocumentsUI Verknüpfung hinzufügen - DocumentsUI Verknüpfung bearbeiten - Gib eine URI ein - Ungültige URI Externen Speicher hinzufügen Externen Speicher bearbeiten Name diff --git a/app/src/main/res/values-el/strings.xml b/app/src/main/res/values-el/strings.xml index 8022f8f71..4f464a138 100644 --- a/app/src/main/res/values-el/strings.xml +++ b/app/src/main/res/values-el/strings.xml @@ -424,10 +424,6 @@ Επεξεργασία αποθήκευσης συσκευής Όνομα Διαδρομή - Προσθήκη συντόμευσης DocumentsUI - Επεξεργασία συντόμευσης DocumentsUI - Εισάγετε ένα URI - Μη έγκυρο URI Προσθήκη εξωτερικής αποθήκευσης Επεξεργασία εξωτερικής αποθήκευσης Όνομα diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index 0d8c0352c..32e35f19d 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -465,10 +465,6 @@ Editar dispositivo de almacenamiento Nombre Ruta - Añadir atajo a DocumentsUI - Editar atajo a DocumentsUI - Ingrese un URI - URL inválida Agregar almacenamiento externo Editar almacenamiento externo Nombre diff --git a/app/src/main/res/values-fi/strings.xml b/app/src/main/res/values-fi/strings.xml index 39f6fe9f0..41736e931 100644 --- a/app/src/main/res/values-fi/strings.xml +++ b/app/src/main/res/values-fi/strings.xml @@ -405,10 +405,6 @@ Muokkaa laitteen tallennustilaa Nimi polku - Lisää DocumentsUI-pikakuvake - Muokkaa DocumentsUI-pikakuvaketta - Syötä URI - Virheellinen URI Lisää ulkoinen tallennustila Muokkaa ulkoista tallennustilaa Nimi diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index c4e2e51c4..d331a783d 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -467,10 +467,6 @@ Modifier le stockage de l\'appareil Nom Chemin - Ajouter un raccourci DocumentsUI - Modifier le raccourci DocumentsUI - Entrez un URI - URI invalide Ajouter un support de stockage externe Modifier le support de stockage externe Nom diff --git a/app/src/main/res/values-hu/strings.xml b/app/src/main/res/values-hu/strings.xml index 65fdfab16..b0c4bcdfa 100644 --- a/app/src/main/res/values-hu/strings.xml +++ b/app/src/main/res/values-hu/strings.xml @@ -425,10 +425,6 @@ Tárolóeszköz szerkesztése Név Útvonal - DocumentsUI parancsikon hozzáadása - DocumentsUI parancsikon szerkesztése - Adjon meg URI-t - Érvénytelen URI Külső tároló hozzáadása Külső tároló szerkesztése Név diff --git a/app/src/main/res/values-in/strings.xml b/app/src/main/res/values-in/strings.xml index 34d4ea30f..b78712dab 100644 --- a/app/src/main/res/values-in/strings.xml +++ b/app/src/main/res/values-in/strings.xml @@ -404,10 +404,6 @@ Sunting penyimpanan perangkat Nama Jalur - Tambahkan pintasan DocumentsUI - Sunting pintasan DocumentsUI - Masukkan URI - URI tidak valid Tambah penyimpanan eksternal Sunting penyimpanan eksternal Nama diff --git a/app/src/main/res/values-is/strings.xml b/app/src/main/res/values-is/strings.xml index 7a92a0446..41cdc3050 100644 --- a/app/src/main/res/values-is/strings.xml +++ b/app/src/main/res/values-is/strings.xml @@ -437,10 +437,6 @@ Breyta geymslurými tækis Nafn Slóð - Bæta við DocumentsUI-flýtileið - Breyta DocumentsUI-flýtileið - Settu inn slóð - Ógild slóð Bæta við ytra geymslurými Breyta ytra geymslurými Nafn diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml index 926ceca43..d933eb01e 100644 --- a/app/src/main/res/values-it/strings.xml +++ b/app/src/main/res/values-it/strings.xml @@ -465,10 +465,6 @@ Modifica archiviazione dispositivo Nome Percorso - Aggiungi la scorciatoia DocumentsUI - Modifica la scorciatoia DocumentsUI - Inserisci un URI - URI non valido Aggiungi archiviazione esterna Modifica archiviazione esterna Nome diff --git a/app/src/main/res/values-iw/strings.xml b/app/src/main/res/values-iw/strings.xml index 866963c46..7944b62ee 100644 --- a/app/src/main/res/values-iw/strings.xml +++ b/app/src/main/res/values-iw/strings.xml @@ -494,10 +494,6 @@ עריכת אחסון ההתקן שם נתיב - הוספת קיצור דרך ל־DocumentsUI - עריכת קיצור דרך ל־DocumentsUI - נא למלא כתובת - כתובת שגויה הוספת אחסון חיצוני עריכת אחסון חיצוני שם diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml index d36f335bd..38c255387 100644 --- a/app/src/main/res/values-ja/strings.xml +++ b/app/src/main/res/values-ja/strings.xml @@ -405,10 +405,6 @@ デバイスのストレージを編集 名前 パス - ドキュメント UI ショートカットを追加 - ドキュメント UI ショートカットを編集 - URI を入力してください - 無効な URI です 外部ストレージを追加 外部ストレージを編集 名前 diff --git a/app/src/main/res/values-ko/strings.xml b/app/src/main/res/values-ko/strings.xml index a871eb8eb..9f4c24078 100644 --- a/app/src/main/res/values-ko/strings.xml +++ b/app/src/main/res/values-ko/strings.xml @@ -405,10 +405,6 @@ 기기 저장소 편집 이름 경로 - DocumentsUI 바로가기 추가 - DocumentsUI 바로가기 편집 - URI를 입력하세요 - 올바르지 않은 URI 외부 저장소 추가 외부 저장소 편집 이름 diff --git a/app/src/main/res/values-lt/strings.xml b/app/src/main/res/values-lt/strings.xml index a6dd9cdc0..dd88f31f6 100644 --- a/app/src/main/res/values-lt/strings.xml +++ b/app/src/main/res/values-lt/strings.xml @@ -487,10 +487,6 @@ Redaguoti įrenginio saugylką Pavadinimas Kelias - Pridėti DocumentsUI nuorodą - Redaguoti DocumentsUI nuorodą - Įvesk URI - Neteisingas URI Pridėti išorinę saugyklą Redaguoti išorinę saugyklą Pavadinimas diff --git a/app/src/main/res/values-nb/strings.xml b/app/src/main/res/values-nb/strings.xml index 5558cb0a9..5759880d3 100644 --- a/app/src/main/res/values-nb/strings.xml +++ b/app/src/main/res/values-nb/strings.xml @@ -435,10 +435,6 @@ Rediger lagring på enheten Navn Bane - Legg til DocumentsUI-snarvei - Rediger DocumentsUI-snarvei - Skriv inn en URI - Ugyldig URI Legg til ekstern lagring Rediger ekstern lagring Navn diff --git a/app/src/main/res/values-nl/strings.xml b/app/src/main/res/values-nl/strings.xml index f49e8181d..bfe3918ee 100644 --- a/app/src/main/res/values-nl/strings.xml +++ b/app/src/main/res/values-nl/strings.xml @@ -435,10 +435,6 @@ Apparaatopslag bewerken Naam Locatie - Documentsnelkoppeling maken - Documentsnelkoppeling bewerken - Voer een uri in - Ongeldige uri Externe opslag toevoegen Externe opslag bewerken Naam diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml index b2c7c4342..fbfc95f44 100644 --- a/app/src/main/res/values-pl/strings.xml +++ b/app/src/main/res/values-pl/strings.xml @@ -495,10 +495,6 @@ Edytuj pamięć urządzenia Nazwa Ścieżka - Dodaj skrót DocumentsUI - Edytuj skrót DocumentsUI - Podaj URI - Nieprawidłowy URI Dodaj nośnik zewnętrzny Edytuj nośnik zewnętrzny Nazwa diff --git a/app/src/main/res/values-pt-rBR/strings.xml b/app/src/main/res/values-pt-rBR/strings.xml index 767d764d7..fd0f22758 100644 --- a/app/src/main/res/values-pt-rBR/strings.xml +++ b/app/src/main/res/values-pt-rBR/strings.xml @@ -465,10 +465,6 @@ Editar armazenamento do dispositivo Nome Caminho - Adicionar atalho DocumentsUI - Editar atalho do DocumentsUI - Insira um URI - URI inválida Adicionar armazenamento externo Editar armazenamento externo Nome diff --git a/app/src/main/res/values-pt-rPT/strings.xml b/app/src/main/res/values-pt-rPT/strings.xml index 743eb0e8e..b1e873822 100644 --- a/app/src/main/res/values-pt-rPT/strings.xml +++ b/app/src/main/res/values-pt-rPT/strings.xml @@ -467,10 +467,6 @@ Editar armazenamento Nome Caminho - Adicionar atalho \'DocumentsUI\' - Editar atalho \'DocumentsUI\' - Indique um URI - URI inválido Adicionar armazenamento externo Editar armazenamento externo Nome diff --git a/app/src/main/res/values-ro/strings.xml b/app/src/main/res/values-ro/strings.xml index aa6b8825c..9ae02b96e 100644 --- a/app/src/main/res/values-ro/strings.xml +++ b/app/src/main/res/values-ro/strings.xml @@ -464,10 +464,6 @@ Editează stocarea dispozitivului Nume Cale - Adaugă o scurtătură pentru DocumentUI - Editează scurtătura pentru DocumentsUI - Introdu un URI - URI invalid Adaugă stocare externă Editează stocarea externă Nume diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index 1cccfaba9..eff548967 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -497,10 +497,6 @@ Редактировать накопитель Имя Путь - Создать ярлык DocumentsUI - Редактировать ярлык DocumentsUI - Введите URI - Недопустимый URI Добавить внешний накопитель Редактировать внешний накопитель Имя diff --git a/app/src/main/res/values-uk/strings.xml b/app/src/main/res/values-uk/strings.xml index d969f4b13..8cf032b52 100644 --- a/app/src/main/res/values-uk/strings.xml +++ b/app/src/main/res/values-uk/strings.xml @@ -496,10 +496,6 @@ Змінити сховище пристрою Назва Шлях - Додати ярлик DocumentsUI - Редагувати ярлик DocumentsUI - Введіть URI - Невірний URI Додати зовнішнє сховище Змінити зовнішнє сховище Назва diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index c18d21a96..c067c70d4 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -412,10 +412,11 @@ 编辑设备存储空间 名称 路径 - 添加 DocumentsUI 快捷方式 - 编辑 DocumentsUI 快捷方式 - 输入 URI - 无效 URI + 添加外部存储空间快捷方式 + 编辑外部存储空间快捷方式 + 存储卷 + 输入存储卷 + 路径 添加外部存储空间 编辑外部存储空间 名称 diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index e7f657812..9344c4075 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -412,10 +412,11 @@ 編輯裝置儲存空間 名稱 路徑 - 新增 DocumentsUI 捷徑 - 編輯 DocumentsUI 捷徑 - 輸入 URI - 無效的 URI + 新增外部儲存空間捷徑 + 編輯外部儲存空間捷徑 + 儲存空間 + 輸入儲存空間 + 路徑 新增外部儲存空間 編輯外部儲存空間 名稱 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 5c204fbeb..964179529 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -540,10 +540,11 @@ Edit device storage Name Path - Add DocumentsUI shortcut - Edit DocumentsUI shortcut - Enter a URI - Invalid URI + Add external storage shortcut + Edit external storage shortcut + Storage volume + Enter a storage volume + Path Add external storage Edit external storage Name