diff --git a/app/build.gradle b/app/build.gradle
index 1b7b9f97e8cc..751cd560af91 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -116,8 +116,8 @@ android {
defaultConfig {
applicationId = "com.nextcloud.client"
minSdk = 27
- targetSdk = 35
- compileSdk = 35
+ targetSdk = 36
+ compileSdk = 36
buildConfigField "boolean", "CI", ciBuild.toString()
buildConfigField "boolean", "RUNTIME_PERF_ANALYSIS", perfAnalysis.toString()
diff --git a/app/src/androidTest/java/com/owncloud/android/ui/activity/FileDisplayActivityTest.java b/app/src/androidTest/java/com/owncloud/android/ui/activity/FileDisplayActivityTest.java
index c9ec5e04ad73..8f65ddcd8517 100644
--- a/app/src/androidTest/java/com/owncloud/android/ui/activity/FileDisplayActivityTest.java
+++ b/app/src/androidTest/java/com/owncloud/android/ui/activity/FileDisplayActivityTest.java
@@ -27,8 +27,8 @@ public void testSetupToolbar() {
InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
Activity activity =
ActivityLifecycleMonitorRegistry.getInstance().getActivitiesInStage(RESUMED).iterator().next();
- if (activity instanceof WhatsNewActivity) {
- activity.onBackPressed();
+ if (activity instanceof WhatsNewActivity whatsNewActivity) {
+ whatsNewActivity.getOnBackPressedDispatcher().onBackPressed();
}
});
scenario.recreate();
diff --git a/app/src/androidTest/java/com/owncloud/android/ui/fragment/FileDetailSharingFragmentIT.kt b/app/src/androidTest/java/com/owncloud/android/ui/fragment/FileDetailSharingFragmentIT.kt
index 7fa76a889add..77c204eb31c0 100644
--- a/app/src/androidTest/java/com/owncloud/android/ui/fragment/FileDetailSharingFragmentIT.kt
+++ b/app/src/androidTest/java/com/owncloud/android/ui/fragment/FileDetailSharingFragmentIT.kt
@@ -822,7 +822,7 @@ class FileDetailSharingFragmentIT : AbstractIT() {
val processFragment =
activity.supportFragmentManager.findFragmentByTag(FileDetailsSharingProcessFragment.TAG) as
FileDetailsSharingProcessFragment
- processFragment.onBackPressed()
+ processFragment.activity?.onBackPressedDispatcher?.onBackPressed()
}
}
}
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 8331fb591ae1..1ca3e4966c69 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -121,7 +121,7 @@
android:requestLegacyExternalStorage="true"
android:roundIcon="@mipmap/ic_launcher"
android:supportsRtl="true"
- android:enableOnBackInvokedCallback="false"
+ android:enableOnBackInvokedCallback="true"
android:theme="@style/Theme.ownCloud.Toolbar"
android:usesCleartextTraffic="true"
tools:ignore="UnusedAttribute"
@@ -353,6 +353,7 @@
{
- onBackPressed()
+ onBackPressedDispatcher.onBackPressed()
true
}
else -> false
diff --git a/app/src/main/java/com/nextcloud/client/etm/EtmActivity.kt b/app/src/main/java/com/nextcloud/client/etm/EtmActivity.kt
index 9d5b72a43f7c..61fbe2736e2a 100644
--- a/app/src/main/java/com/nextcloud/client/etm/EtmActivity.kt
+++ b/app/src/main/java/com/nextcloud/client/etm/EtmActivity.kt
@@ -10,6 +10,7 @@ import android.content.Context
import android.content.Intent
import android.os.Bundle
import android.view.MenuItem
+import androidx.activity.OnBackPressedCallback
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProvider
import com.nextcloud.client.di.Injectable
@@ -46,6 +47,7 @@ class EtmActivity :
onPageChanged(it)
}
)
+ handleOnBackPressed()
}
override fun onOptionsItemSelected(item: MenuItem): Boolean = when (item.itemId) {
@@ -58,11 +60,17 @@ class EtmActivity :
else -> super.onOptionsItemSelected(item)
}
- @Deprecated("Deprecated in Java")
- override fun onBackPressed() {
- if (!vm.onBackPressed()) {
- super.onBackPressed()
- }
+ private fun handleOnBackPressed() {
+ onBackPressedDispatcher.addCallback(object : OnBackPressedCallback(true) {
+ override fun handleOnBackPressed() {
+ val handledByVm = vm.onBackPressed()
+
+ if (!handledByVm) {
+ isEnabled = false
+ onBackPressedDispatcher.onBackPressed()
+ }
+ }
+ })
}
private fun onPageChanged(page: EtmMenuEntry?) {
diff --git a/app/src/main/java/com/nextcloud/client/onboarding/WhatsNewActivity.kt b/app/src/main/java/com/nextcloud/client/onboarding/WhatsNewActivity.kt
index a824c7ca41b1..dd51319fc54f 100644
--- a/app/src/main/java/com/nextcloud/client/onboarding/WhatsNewActivity.kt
+++ b/app/src/main/java/com/nextcloud/client/onboarding/WhatsNewActivity.kt
@@ -132,6 +132,7 @@ class WhatsNewActivity :
object : OnBackPressedCallback(true) {
override fun handleOnBackPressed() {
onFinish()
+ isEnabled = false
onBackPressedDispatcher.onBackPressed()
}
}
diff --git a/app/src/main/java/com/nextcloud/utils/extensions/DrawerActivityExtensions.kt b/app/src/main/java/com/nextcloud/utils/extensions/DrawerActivityExtensions.kt
index d09660301611..899d9ed5a241 100644
--- a/app/src/main/java/com/nextcloud/utils/extensions/DrawerActivityExtensions.kt
+++ b/app/src/main/java/com/nextcloud/utils/extensions/DrawerActivityExtensions.kt
@@ -1,7 +1,7 @@
/*
* Nextcloud - Android Client
*
- * SPDX-FileCopyrightText: 2024 Alper Ozturk
+ * SPDX-FileCopyrightText: 2025 Alper Ozturk
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
@@ -10,22 +10,10 @@ package com.nextcloud.utils.extensions
import android.content.Intent
import com.owncloud.android.MainApp
import com.owncloud.android.R
-import com.owncloud.android.datamodel.OCFile
import com.owncloud.android.ui.activity.DrawerActivity
import com.owncloud.android.ui.activity.FileDisplayActivity
-@Suppress("ReturnCount")
-fun DrawerActivity.handleBackButtonEvent(currentDir: OCFile): Boolean {
- if (DrawerActivity.menuItemId == R.id.nav_all_files && currentDir.isRootDirectory) {
- moveTaskToBack(true)
- return true
- }
-
- val isParentDirExists = (storageManager.getFileById(currentDir.parentId) != null)
- if (isParentDirExists) {
- return false
- }
-
+fun DrawerActivity.navigateToAllFiles() {
DrawerActivity.menuItemId = R.id.nav_all_files
setNavigationViewItemChecked()
@@ -38,6 +26,4 @@ fun DrawerActivity.handleBackButtonEvent(currentDir: OCFile): Boolean {
}.run {
startActivity(this)
}
-
- return true
}
diff --git a/app/src/main/java/com/owncloud/android/ui/activity/DrawerActivity.java b/app/src/main/java/com/owncloud/android/ui/activity/DrawerActivity.java
index 29aa804614f2..2b0d1c0d2c2e 100644
--- a/app/src/main/java/com/owncloud/android/ui/activity/DrawerActivity.java
+++ b/app/src/main/java/com/owncloud/android/ui/activity/DrawerActivity.java
@@ -31,6 +31,7 @@
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
+import android.os.PersistableBundle;
import android.os.SystemClock;
import android.text.TextUtils;
import android.view.Menu;
@@ -115,6 +116,7 @@
import javax.inject.Inject;
+import androidx.activity.OnBackPressedCallback;
import androidx.annotation.IdRes;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
@@ -206,6 +208,12 @@ public abstract class DrawerActivity extends ToolbarActivity
@Inject
ClientFactory clientFactory;
+ @Override
+ public void onCreate(@Nullable Bundle savedInstanceState, @Nullable PersistableBundle persistentState) {
+ super.onCreate(savedInstanceState, persistentState);
+ addOnBackPressedCallback();
+ }
+
/**
* Initializes the drawer and its content. This method needs to be called after the content view has been set.
*/
@@ -1153,19 +1161,24 @@ public void onConfigurationChanged(@NonNull Configuration newConfig) {
}
}
- @Override
- public void onBackPressed() {
- if (isDrawerOpen()) {
- closeDrawer();
- return;
- }
- Fragment fileDetailsSharingProcessFragment =
- getSupportFragmentManager().findFragmentByTag(FileDetailsSharingProcessFragment.TAG);
- if (fileDetailsSharingProcessFragment != null) {
- ((FileDetailsSharingProcessFragment) fileDetailsSharingProcessFragment).onBackPressed();
- } else {
- super.onBackPressed();
- }
+ public void addOnBackPressedCallback() {
+ getOnBackPressedDispatcher().addCallback(new OnBackPressedCallback(true) {
+ @Override
+ public void handleOnBackPressed() {
+ if (isDrawerOpen()) {
+ closeDrawer();
+ return;
+ }
+
+ final var fragment = getSupportFragmentManager().findFragmentByTag(FileDetailsSharingProcessFragment.TAG);
+ if (fragment instanceof FileDetailsSharingProcessFragment fileDetailsSharingProcessFragment) {
+ fileDetailsSharingProcessFragment.onBackPressed();
+ } else {
+ setEnabled(false);
+ getOnBackPressedDispatcher().onBackPressed();
+ }
+ }
+ });
}
@Override
diff --git a/app/src/main/java/com/owncloud/android/ui/activity/FileDisplayActivity.kt b/app/src/main/java/com/owncloud/android/ui/activity/FileDisplayActivity.kt
index 301c4e6d67a2..88807ba9fc82 100644
--- a/app/src/main/java/com/owncloud/android/ui/activity/FileDisplayActivity.kt
+++ b/app/src/main/java/com/owncloud/android/ui/activity/FileDisplayActivity.kt
@@ -40,6 +40,7 @@ import android.view.MenuItem
import android.view.View
import android.view.ViewTreeObserver.OnGlobalLayoutListener
import android.view.WindowManager.BadTokenException
+import androidx.activity.OnBackPressedCallback
import androidx.annotation.VisibleForTesting
import androidx.appcompat.widget.SearchView
import androidx.core.view.MenuItemCompat
@@ -82,6 +83,7 @@ import com.nextcloud.utils.extensions.getParcelableArgument
import com.nextcloud.utils.extensions.isActive
import com.nextcloud.utils.extensions.lastFragment
import com.nextcloud.utils.extensions.logFileSize
+import com.nextcloud.utils.extensions.navigateToAllFiles
import com.nextcloud.utils.fileNameValidator.FileNameValidator.checkFolderPath
import com.nextcloud.utils.view.FastScrollUtils
import com.owncloud.android.MainApp
@@ -155,7 +157,6 @@ import com.owncloud.android.utils.PermissionUtil.requestNotificationPermission
import com.owncloud.android.utils.PushUtils
import com.owncloud.android.utils.StringUtils
import com.owncloud.android.utils.theme.CapabilityUtils
-import edu.umd.cs.findbugs.annotations.SuppressFBWarnings
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
@@ -278,6 +279,7 @@ class FileDisplayActivity :
initSyncBroadcastReceiver()
observeWorkerState()
startMetadataSyncForRoot()
+ handleBackPress()
}
private fun loadSavedInstanceState(savedInstanceState: Bundle?) {
@@ -935,7 +937,7 @@ class FileDisplayActivity :
) {
openDrawer()
} else {
- onBackPressed()
+ onBackPressedDispatcher.onBackPressed()
}
} else if (itemId == R.id.action_select_all) {
val fragment = this.listOfFilesFragment
@@ -1136,40 +1138,59 @@ class FileDisplayActivity :
}
}
- private val isRootDirectory: Boolean
- get() {
- val currentDir = getCurrentDir()
- return (currentDir == null || currentDir.parentId == FileDataStorageManager.ROOT_PARENT_ID.toLong())
- }
-
- /*
- * BackPressed priority/hierarchy:
- * 1. close search view if opened
- * 2. close drawer if opened
- * 3. if it is OCFileListFragment and it's in Root -> (finish Activity) or it's not Root -> (browse up)
- * 4. otherwise pop up the fragment and sortGroup view visibility and call super.onBackPressed()
+ /**
+ * Sets up a custom back-press handler for this activity.
+ *
+ * This callback determines how the back button behaves based on the current UI state:
+ * - If the search view is open, it closes it.
+ * - If the navigation drawer is open, it closes it.
+ * - If the left fragment is an [OCFileListFragment]:
+ * - If in the root directory, it either navigates to "All Files" or finishes the activity.
+ * - Otherwise, it navigates one level up.
+ * - Otherwise, it pops the current fragment from the back stack.
+ *
+ * ### About `isEnabled`
+ * `isEnabled` is a property of [OnBackPressedCallback].
+ * When `isEnabled = false`, this callback is **temporarily disabled**,
+ * allowing the system or other callbacks to handle the back press instead.
*/
- @SuppressFBWarnings("ITC_INHERITANCE_TYPE_CHECKING") // TODO Apply fail fast principle
- override fun onBackPressed() {
- if (isSearchOpen()) {
- resetSearchAction()
- return
- }
+ private fun handleBackPress() {
+ onBackPressedDispatcher.addCallback(
+ this,
+ object : OnBackPressedCallback(true) {
+ override fun handleOnBackPressed() {
+ when {
+ isSearchOpen() -> {
+ isEnabled = false
+ resetSearchAction()
+ }
- if (isDrawerOpen) {
- super.onBackPressed()
- return
- }
+ isDrawerOpen -> {
+ isEnabled = false
+ onBackPressedDispatcher.onBackPressed()
+ }
- if (this.leftFragment is OCFileListFragment) {
- if (isRoot(getCurrentDir())) {
- finish()
- } else {
- browseUp(leftFragment as OCFileListFragment)
+ leftFragment is OCFileListFragment -> {
+ val fragment = leftFragment as OCFileListFragment
+ if (isRoot(getCurrentDir())) {
+ if (fragment.shouldNavigateBackToAllFiles()) {
+ navigateToAllFiles()
+ } else {
+ finish()
+ }
+ } else {
+ browseUp(fragment)
+ }
+ }
+
+ else -> {
+ isEnabled = false
+ popBack()
+ }
+ }
+ }
}
- } else {
- popBack()
- }
+ )
}
private fun browseUp(listOfFiles: OCFileListFragment) {
@@ -1210,20 +1231,20 @@ class FileDisplayActivity :
if (leftFragment is UnifiedSearchFragment) {
showSortListGroup(false)
- super.onBackPressed()
+ onBackPressedDispatcher.onBackPressed()
}
}
/**
* Use this method when want to pop the fragment on back press. It resets Scrolling (See
* [with true][.resetScrolling] and pop the visibility for sortListGroup (See
- * [with false][.showSortListGroup]. At last call to super.onBackPressed()
+ * [with false][.showSortListGroup]. At last call to onBackPressedDispatcher.onBackPressed()
*/
private fun popBack() {
binding.fabMain.setImageResource(R.drawable.ic_plus)
resetScrolling(true)
showSortListGroup(false)
- super.onBackPressed()
+ onBackPressedDispatcher.onBackPressed()
}
override fun onSaveInstanceState(outState: Bundle) {
@@ -1645,7 +1666,7 @@ class FileDisplayActivity :
if (uploadWasFine || file != null && file.fileExists()) {
fileDetailFragment.updateFileDetails(false, true)
} else {
- onBackPressed()
+ onBackPressedDispatcher.onBackPressed()
}
// Force the preview if the file is an image or text file
diff --git a/app/src/main/java/com/owncloud/android/ui/activity/FolderPickerActivity.kt b/app/src/main/java/com/owncloud/android/ui/activity/FolderPickerActivity.kt
index 85ead7b2c9b8..a9a2a2adfb13 100644
--- a/app/src/main/java/com/owncloud/android/ui/activity/FolderPickerActivity.kt
+++ b/app/src/main/java/com/owncloud/android/ui/activity/FolderPickerActivity.kt
@@ -106,7 +106,7 @@ open class FolderPickerActivity :
updateActionBarTitleAndHomeButtonByString(captionText)
setBackgroundText()
- handleOnBackPressed()
+ handleBackPress()
}
override fun onDestroy() {
@@ -151,7 +151,7 @@ open class FolderPickerActivity :
}
}
- private fun handleOnBackPressed() {
+ private fun handleBackPress() {
onBackPressedDispatcher.addCallback(
this,
object : OnBackPressedCallback(true) {
@@ -327,7 +327,7 @@ open class FolderPickerActivity :
} else if (itemId == android.R.id.home) {
val currentDir = currentFolder
if (currentDir != null && currentDir.parentId != 0L) {
- onBackPressed()
+ onBackPressedDispatcher.onBackPressed()
}
} else {
retval = super.onOptionsItemSelected(item)
diff --git a/app/src/main/java/com/owncloud/android/ui/activity/InternalTwoWaySyncActivity.kt b/app/src/main/java/com/owncloud/android/ui/activity/InternalTwoWaySyncActivity.kt
index 8ae77e6986bf..89d37b84da4d 100644
--- a/app/src/main/java/com/owncloud/android/ui/activity/InternalTwoWaySyncActivity.kt
+++ b/app/src/main/java/com/owncloud/android/ui/activity/InternalTwoWaySyncActivity.kt
@@ -201,7 +201,7 @@ class InternalTwoWaySyncActivity :
override fun onOptionsItemSelected(item: MenuItem): Boolean {
when (item.itemId) {
android.R.id.home -> {
- onBackPressed()
+ onBackPressedDispatcher.onBackPressed()
}
R.id.action_dismiss_two_way_sync -> {
disableTwoWaySyncAndWorkers()
diff --git a/app/src/main/java/com/owncloud/android/ui/activity/ManageAccountsActivity.kt b/app/src/main/java/com/owncloud/android/ui/activity/ManageAccountsActivity.kt
index 65c4d0715bb1..ef3526ecdcfd 100644
--- a/app/src/main/java/com/owncloud/android/ui/activity/ManageAccountsActivity.kt
+++ b/app/src/main/java/com/owncloud/android/ui/activity/ManageAccountsActivity.kt
@@ -91,7 +91,7 @@ class ManageAccountsActivity :
multipleAccountsSupported = multiAccountSupport(this)
setupUserList()
- handleOnBackPressed()
+ handleBackPress()
}
private fun setupUsers() {
@@ -149,7 +149,7 @@ class ManageAccountsActivity :
performAccountRemoval(user)
}
- private fun handleOnBackPressed() {
+ private fun handleBackPress() {
onBackPressedDispatcher.addCallback(
this,
onBackPressedCallback
@@ -160,13 +160,13 @@ class ManageAccountsActivity :
override fun handleOnBackPressed() {
val resultIntent = Intent()
- if (accountManager.allUsers.size > 0) {
+ if (accountManager.allUsers.isNotEmpty()) {
resultIntent.putExtra(KEY_ACCOUNT_LIST_CHANGED, hasAccountListChanged())
resultIntent.putExtra(KEY_CURRENT_ACCOUNT_CHANGED, hasCurrentAccountChanged())
setResult(RESULT_OK, resultIntent)
} else {
val intent = Intent(this@ManageAccountsActivity, AuthenticatorActivity::class.java)
- intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
+ intent.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP
startActivity(intent)
}
@@ -229,7 +229,7 @@ class ManageAccountsActivity :
var result = true
if (item.itemId == android.R.id.home) {
- onBackPressed()
+ onBackPressedDispatcher.onBackPressed()
} else {
result = super.onOptionsItemSelected(item)
}
@@ -331,7 +331,7 @@ class ManageAccountsActivity :
)
recyclerView?.adapter = userListAdapter
} else {
- onBackPressed()
+ onBackPressedDispatcher.onBackPressed()
}
}
@@ -393,8 +393,7 @@ class ManageAccountsActivity :
resultIntent.putExtra(KEY_ACCOUNT_LIST_CHANGED, true)
resultIntent.putExtra(KEY_CURRENT_ACCOUNT_CHANGED, true)
setResult(RESULT_OK, resultIntent)
-
- super.onBackPressed()
+ onBackPressedDispatcher.onBackPressed()
}
}
diff --git a/app/src/main/java/com/owncloud/android/ui/activity/ReceiveExternalFilesActivity.java b/app/src/main/java/com/owncloud/android/ui/activity/ReceiveExternalFilesActivity.java
index c9b4be929b4d..5148c10f52ec 100755
--- a/app/src/main/java/com/owncloud/android/ui/activity/ReceiveExternalFilesActivity.java
+++ b/app/src/main/java/com/owncloud/android/ui/activity/ReceiveExternalFilesActivity.java
@@ -103,6 +103,7 @@
import javax.inject.Inject;
+import androidx.activity.OnBackPressedCallback;
import androidx.annotation.DrawableRes;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
@@ -203,6 +204,8 @@ protected void onCreate(Bundle savedInstanceState) {
fm.beginTransaction()
.add(taskRetainerFragment, TaskRetainerFragment.FTAG_TASK_RETAINER_FRAGMENT).commit();
} // else, Fragment already created and retained across configuration change
+
+ handleBackPress();
}
@Override
@@ -656,14 +659,19 @@ private File createTempFile(String text) {
}
}
- @Override
- public void onBackPressed() {
- if (mParents.size() <= SINGLE_PARENT) {
- super.onBackPressed();
- } else {
- mParents.pop();
- browseToFolderIfItExists();
- }
+ private void handleBackPress() {
+ getOnBackPressedDispatcher().addCallback(this, new OnBackPressedCallback(true) {
+ @Override
+ public void handleOnBackPressed() {
+ if (mParents.size() <= SINGLE_PARENT) {
+ setEnabled(false);
+ getOnBackPressedDispatcher().onBackPressed();
+ } else {
+ mParents.pop();
+ browseToFolderIfItExists();
+ }
+ }
+ });
}
@Override
@@ -1097,7 +1105,7 @@ public boolean onOptionsItemSelected(MenuItem item) {
dialog.show(getSupportFragmentManager(), CreateFolderDialogFragment.CREATE_FOLDER_FRAGMENT);
} else if (itemId == android.R.id.home) {
if (mParents.size() > SINGLE_PARENT) {
- onBackPressed();
+ getOnBackPressedDispatcher().onBackPressed();
}
} else if (itemId == R.id.action_switch_account) {
showAccountChooserDialog();
diff --git a/app/src/main/java/com/owncloud/android/ui/activity/SettingsActivity.java b/app/src/main/java/com/owncloud/android/ui/activity/SettingsActivity.java
index bcbed6b84d77..0790160d7edb 100644
--- a/app/src/main/java/com/owncloud/android/ui/activity/SettingsActivity.java
+++ b/app/src/main/java/com/owncloud/android/ui/activity/SettingsActivity.java
@@ -15,6 +15,7 @@
*/
package com.owncloud.android.ui.activity;
+import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Intent;
import android.content.SharedPreferences;
@@ -354,6 +355,7 @@ private void setupAboutCategory(String appVersion) {
}
}
+ @SuppressLint("GestureBackNavigation")
@Override
public void onBackPressed() {
DrawerActivity.menuItemId = R.id.nav_all_files;
diff --git a/app/src/main/java/com/owncloud/android/ui/activity/UploadFilesActivity.java b/app/src/main/java/com/owncloud/android/ui/activity/UploadFilesActivity.java
index 226bb6d294b2..375458b4bbe4 100644
--- a/app/src/main/java/com/owncloud/android/ui/activity/UploadFilesActivity.java
+++ b/app/src/main/java/com/owncloud/android/ui/activity/UploadFilesActivity.java
@@ -238,7 +238,7 @@ public void onCreate(Bundle savedInstanceState) {
public void onItemSelected(AdapterView> parent, View view, int position, long id) {
int i = position;
while (i-- != 0) {
- onBackPressed();
+ getOnBackPressedDispatcher().onBackPressed();
}
// the next operation triggers a new call to this method, but it's necessary to
// ensure that the name exposed in the action bar is the current directory when the
@@ -311,7 +311,7 @@ public boolean onOptionsItemSelected(MenuItem item) {
if (itemId == android.R.id.home) {
if (mCurrentDir != null && mCurrentDir.getParentFile() != null) {
- onBackPressed();
+ getOnBackPressedDispatcher().onBackPressed();
}
} else if (itemId == R.id.action_select_all) {
mSelectAll = !item.isChecked();
diff --git a/app/src/main/java/com/owncloud/android/ui/activity/UserInfoActivity.java b/app/src/main/java/com/owncloud/android/ui/activity/UserInfoActivity.java
index 613437a25133..44bdca6655b7 100644
--- a/app/src/main/java/com/owncloud/android/ui/activity/UserInfoActivity.java
+++ b/app/src/main/java/com/owncloud/android/ui/activity/UserInfoActivity.java
@@ -158,7 +158,7 @@ public boolean onOptionsItemSelected(MenuItem item) {
int itemId = item.getItemId();
if (itemId == android.R.id.home) {
- onBackPressed();
+ getOnBackPressedDispatcher().onBackPressed();
} else if (itemId == R.id.action_open_account) {
accountClicked(user.hashCode());
} else if (itemId == R.id.action_delete_account) {
diff --git a/app/src/main/java/com/owncloud/android/ui/fragment/ExtendedListFragment.kt b/app/src/main/java/com/owncloud/android/ui/fragment/ExtendedListFragment.kt
index a88da8904661..6224420f5256 100644
--- a/app/src/main/java/com/owncloud/android/ui/fragment/ExtendedListFragment.kt
+++ b/app/src/main/java/com/owncloud/android/ui/fragment/ExtendedListFragment.kt
@@ -25,7 +25,6 @@ import android.os.Handler
import android.os.Looper
import android.os.Parcelable
import android.util.DisplayMetrics
-import android.view.KeyEvent
import android.view.LayoutInflater
import android.view.Menu
import android.view.MenuInflater
@@ -57,7 +56,6 @@ import com.nextcloud.client.di.Injectable
import com.nextcloud.client.preferences.AppPreferences
import com.nextcloud.client.preferences.AppPreferencesImpl
import com.nextcloud.utils.extensions.getTypedActivity
-import com.nextcloud.utils.extensions.handleBackButtonEvent
import com.owncloud.android.MainApp
import com.owncloud.android.R
import com.owncloud.android.databinding.ListFragmentBinding
@@ -65,7 +63,6 @@ import com.owncloud.android.lib.common.utils.Log_OC
import com.owncloud.android.lib.resources.files.SearchRemoteOperation
import com.owncloud.android.lib.resources.status.OwnCloudVersion
import com.owncloud.android.ui.EmptyRecyclerView
-import com.owncloud.android.ui.activity.FileActivity
import com.owncloud.android.ui.activity.FileDisplayActivity
import com.owncloud.android.ui.activity.FolderPickerActivity
import com.owncloud.android.ui.activity.OnEnforceableRefreshListener
@@ -767,19 +764,6 @@ open class ExtendedListFragment :
}
}
- protected fun setupBackButtonRedirectToAllFiles() {
- view?.isFocusableInTouchMode = true
- view?.requestFocus()
- view?.setOnKeyListener { _: View, keyCode: Int, event: KeyEvent ->
- if (event.action == KeyEvent.ACTION_UP && keyCode == KeyEvent.KEYCODE_BACK) {
- val fda = getTypedActivity(FileActivity::class.java)
- val currentDir = fda?.currentDir ?: return@setOnKeyListener false
- return@setOnKeyListener fda.handleBackButtonEvent(currentDir)
- }
- false
- }
- }
-
private data class EmptyListData(val headline: Int, val message: Int, val icon: Int?, val tintIcon: Boolean)
companion object {
diff --git a/app/src/main/java/com/owncloud/android/ui/fragment/FileDetailFragment.java b/app/src/main/java/com/owncloud/android/ui/fragment/FileDetailFragment.java
index 858c02ec128a..f94e553eb7d0 100644
--- a/app/src/main/java/com/owncloud/android/ui/fragment/FileDetailFragment.java
+++ b/app/src/main/java/com/owncloud/android/ui/fragment/FileDetailFragment.java
@@ -197,7 +197,7 @@ public FileDetailActivitiesFragment getFileDetailActivitiesFragment() {
}
public void goBackToOCFileListFragment() {
- requireActivity().onBackPressed();
+ requireActivity().getOnBackPressedDispatcher().onBackPressed();
}
@Override
diff --git a/app/src/main/java/com/owncloud/android/ui/fragment/GalleryFragment.java b/app/src/main/java/com/owncloud/android/ui/fragment/GalleryFragment.java
index 672ca0f2ae64..c44c12168a2a 100644
--- a/app/src/main/java/com/owncloud/android/ui/fragment/GalleryFragment.java
+++ b/app/src/main/java/com/owncloud/android/ui/fragment/GalleryFragment.java
@@ -234,12 +234,6 @@ public void onResume() {
}
}
- @Override
- public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
- super.onViewCreated(view, savedInstanceState);
- setupBackButtonRedirectToAllFiles();
- }
-
@Override
public void onMessageEvent(ChangeMenuEvent changeMenuEvent) {
super.onMessageEvent(changeMenuEvent);
diff --git a/app/src/main/java/com/owncloud/android/ui/fragment/OCFileListFragment.java b/app/src/main/java/com/owncloud/android/ui/fragment/OCFileListFragment.java
index 8961b2fdbbcf..8623c5420cb4 100644
--- a/app/src/main/java/com/owncloud/android/ui/fragment/OCFileListFragment.java
+++ b/app/src/main/java/com/owncloud/android/ui/fragment/OCFileListFragment.java
@@ -277,12 +277,6 @@ public void onResume() {
super.onResume();
}
- @Override
- public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
- super.onViewCreated(view, savedInstanceState);
- setupBackButtonRedirectToAllFiles();
- }
-
@Override
public void onDestroyView() {
super.onDestroyView();
@@ -2325,4 +2319,15 @@ public boolean isEmpty() {
public SearchEvent getSearchEvent() {
return searchEvent;
}
+
+ public boolean isSearchEventFavorite() {
+ if (searchEvent == null) {
+ return false;
+ }
+ return searchEvent.getSearchType() == SearchRemoteOperation.SearchType.FAVORITE_SEARCH;
+ }
+
+ public boolean shouldNavigateBackToAllFiles() {
+ return ((this instanceof GalleryFragment) || isSearchEventFavorite() || DrawerActivity.menuItemId == R.id.nav_favorites);
+ }
}
diff --git a/app/src/main/java/com/owncloud/android/ui/fragment/contactsbackup/BackupListFragment.java b/app/src/main/java/com/owncloud/android/ui/fragment/contactsbackup/BackupListFragment.java
index 03c8f0e52786..99ff53f53368 100644
--- a/app/src/main/java/com/owncloud/android/ui/fragment/contactsbackup/BackupListFragment.java
+++ b/app/src/main/java/com/owncloud/android/ui/fragment/contactsbackup/BackupListFragment.java
@@ -404,7 +404,7 @@ private void importCalendar() {
private void closeFragment() {
ContactsPreferenceActivity contactsPreferenceActivity = (ContactsPreferenceActivity) getActivity();
if (contactsPreferenceActivity != null) {
- contactsPreferenceActivity.onBackPressed();
+ contactsPreferenceActivity.getOnBackPressedDispatcher().onBackPressed();
}
}
diff --git a/app/src/main/java/com/owncloud/android/ui/preview/PreviewBitmapActivity.kt b/app/src/main/java/com/owncloud/android/ui/preview/PreviewBitmapActivity.kt
index c5265015bb21..b6c9e86c2d16 100644
--- a/app/src/main/java/com/owncloud/android/ui/preview/PreviewBitmapActivity.kt
+++ b/app/src/main/java/com/owncloud/android/ui/preview/PreviewBitmapActivity.kt
@@ -54,7 +54,7 @@ class PreviewBitmapActivity :
}
override fun onSupportNavigateUp(): Boolean {
- onBackPressed()
+ onBackPressedDispatcher.onBackPressed()
return true
}
}
diff --git a/app/src/main/java/com/owncloud/android/ui/preview/PreviewImageActivity.kt b/app/src/main/java/com/owncloud/android/ui/preview/PreviewImageActivity.kt
index c71c86bd2930..1d575dd32f5a 100644
--- a/app/src/main/java/com/owncloud/android/ui/preview/PreviewImageActivity.kt
+++ b/app/src/main/java/com/owncloud/android/ui/preview/PreviewImageActivity.kt
@@ -14,6 +14,7 @@ import android.os.Build
import android.os.Bundle
import android.view.MenuItem
import android.view.View
+import androidx.activity.OnBackPressedCallback
import androidx.appcompat.app.ActionBar
import androidx.core.content.ContextCompat
import androidx.drawerlayout.widget.DrawerLayout
@@ -123,6 +124,7 @@ class PreviewImageActivity :
observeWorkerState()
applyDisplayCutOutTopPadding()
+ handleBackPress()
}
private fun applyDisplayCutOutTopPadding() {
@@ -214,9 +216,14 @@ class PreviewImageActivity :
}
}
- override fun onBackPressed() {
- sendRefreshSearchEventBroadcast()
- super.onBackPressed()
+ private fun handleBackPress() {
+ onBackPressedDispatcher.addCallback(object : OnBackPressedCallback(true) {
+ override fun handleOnBackPressed() {
+ sendRefreshSearchEventBroadcast()
+ isEnabled = false
+ onBackPressedDispatcher.onBackPressed()
+ }
+ })
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
diff --git a/app/src/main/java/com/owncloud/android/ui/preview/PreviewTextFragment.kt b/app/src/main/java/com/owncloud/android/ui/preview/PreviewTextFragment.kt
index a3aec178ad48..99b0bffc4bf3 100644
--- a/app/src/main/java/com/owncloud/android/ui/preview/PreviewTextFragment.kt
+++ b/app/src/main/java/com/owncloud/android/ui/preview/PreviewTextFragment.kt
@@ -165,7 +165,7 @@ abstract class PreviewTextFragment :
* Finishes the preview
*/
protected fun finish() {
- requireActivity().runOnUiThread { requireActivity().onBackPressed() }
+ requireActivity().runOnUiThread { requireActivity().onBackPressedDispatcher.onBackPressed() }
}
companion object {
diff --git a/app/src/main/java/com/owncloud/android/ui/preview/PreviewVideoFullscreenDialog.kt b/app/src/main/java/com/owncloud/android/ui/preview/PreviewVideoFullscreenDialog.kt
index 30b9da6a53cb..dd1e6814eccc 100644
--- a/app/src/main/java/com/owncloud/android/ui/preview/PreviewVideoFullscreenDialog.kt
+++ b/app/src/main/java/com/owncloud/android/ui/preview/PreviewVideoFullscreenDialog.kt
@@ -7,15 +7,16 @@
*/
package com.owncloud.android.ui.preview
-import android.app.Activity
import android.app.Dialog
import android.os.Build
import android.view.ViewGroup
import android.view.Window
+import androidx.activity.addCallback
import androidx.annotation.OptIn
import androidx.core.view.WindowCompat
import androidx.core.view.WindowInsetsCompat
import androidx.core.view.WindowInsetsControllerCompat
+import androidx.fragment.app.FragmentActivity
import androidx.media3.common.util.UnstableApi
import androidx.media3.exoplayer.ExoPlayer
import androidx.media3.ui.PlayerView
@@ -35,7 +36,7 @@ import com.owncloud.android.lib.common.utils.Log_OC
*/
@OptIn(UnstableApi::class)
class PreviewVideoFullscreenDialog(
- private val activity: Activity,
+ private val activity: FragmentActivity,
nextcloudClient: NextcloudClient,
private val sourceExoPlayer: ExoPlayer,
private val sourceView: PlayerView
@@ -69,6 +70,7 @@ class PreviewVideoFullscreenDialog(
binding.videoPlayer.player = mExoPlayer
mExoPlayer.prepare()
}
+ handleOnBackPressed()
}
private fun isRotatedVideo(): Boolean {
@@ -95,7 +97,7 @@ class PreviewVideoFullscreenDialog(
setOnShowListener {
enableImmersiveMode()
switchTargetViewFromSource()
- binding.videoPlayer.setFullscreenButtonClickListener { onBackPressed() }
+ binding.videoPlayer.setFullscreenButtonClickListener { activity.onBackPressedDispatcher.onBackPressed() }
if (isPlaying) {
mExoPlayer.play()
}
@@ -111,23 +113,25 @@ class PreviewVideoFullscreenDialog(
}
}
- override fun onBackPressed() {
- val isPlaying = mExoPlayer.isPlaying
- if (isPlaying) {
- mExoPlayer.pause()
- }
- setOnDismissListener {
- disableImmersiveMode()
- playingStateListener?.let {
- mExoPlayer.removeListener(it)
- }
- switchTargetViewToSource()
+ private fun handleOnBackPressed() {
+ activity.onBackPressedDispatcher.addCallback(activity) {
+ val isPlaying = mExoPlayer.isPlaying
if (isPlaying) {
- sourceExoPlayer.play()
+ mExoPlayer.pause()
+ }
+ setOnDismissListener {
+ disableImmersiveMode()
+ playingStateListener?.let {
+ mExoPlayer.removeListener(it)
+ }
+ switchTargetViewToSource()
+ if (isPlaying) {
+ sourceExoPlayer.play()
+ }
+ sourceView.showController()
}
- sourceView.showController()
+ dismiss()
}
- dismiss()
}
private fun switchTargetViewToSource() {
diff --git a/app/src/main/java/com/owncloud/android/ui/trashbin/TrashbinActivity.kt b/app/src/main/java/com/owncloud/android/ui/trashbin/TrashbinActivity.kt
index 9fb6a8fd8eb0..2ceef02b13e3 100644
--- a/app/src/main/java/com/owncloud/android/ui/trashbin/TrashbinActivity.kt
+++ b/app/src/main/java/com/owncloud/android/ui/trashbin/TrashbinActivity.kt
@@ -128,6 +128,7 @@ class TrashbinActivity :
updateActionBarTitleAndHomeButtonByString(getString(R.string.trashbin_activity_title))
setupDrawer()
+ handleBackPress()
}
override fun onStart() {
@@ -179,8 +180,6 @@ class TrashbinActivity :
loadFolder()
- handleOnBackPressed()
-
mMultiChoiceModeListener = MultiChoiceModeListener(
this,
trashbinListAdapter,
@@ -189,7 +188,7 @@ class TrashbinActivity :
addDrawerListener(mMultiChoiceModeListener)
}
- private fun handleOnBackPressed() {
+ private fun handleBackPress() {
onBackPressedDispatcher.addCallback(
this,
onBackPressedCallback
diff --git a/appscan/build.gradle b/appscan/build.gradle
index 2dd65e4eabb9..00984b58de8d 100644
--- a/appscan/build.gradle
+++ b/appscan/build.gradle
@@ -22,8 +22,8 @@ android {
defaultConfig {
minSdk = 27
- targetSdk = 35
- compileSdk = 35
+ targetSdk = 36
+ compileSdk = 36
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
diff --git a/build.gradle b/build.gradle
index 14482f6f01d7..e482d00f8d3b 100644
--- a/build.gradle
+++ b/build.gradle
@@ -10,7 +10,7 @@
*/
buildscript {
ext {
- androidLibraryVersion ="5da34c70da4068ff976cf931b7716fc7a337f32d"
+ androidLibraryVersion ="9b7c9434bf9002a63d5ac911b89b4abf014fabfd"
androidCommonLibraryVersion = "0.28.0"
androidPluginVersion = '8.13.0'
androidxMediaVersion = "1.5.1"
diff --git a/gradle/verification-metadata.xml b/gradle/verification-metadata.xml
index 48465f5b1b02..88bf5cf9ec06 100644
--- a/gradle/verification-metadata.xml
+++ b/gradle/verification-metadata.xml
@@ -16382,6 +16382,14 @@
+
+
+
+
+
+
+
+