Migrate onBackPressed() to OnBackPressedDispatcher for Android 16+ compatibility (#1541)

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: Catfriend1 <16361913+Catfriend1@users.noreply.github.com>
This commit is contained in:
Copilot 2025-07-14 05:21:25 +02:00 committed by GitHub
parent 52ce2b8c87
commit dfd94e00af
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 150 additions and 93 deletions

View File

@ -25,6 +25,7 @@ import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
import androidx.activity.OnBackPressedCallback;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.SwitchCompat;
@ -125,6 +126,19 @@ public class DeviceActivity extends SyncthingActivity {
private Dialog mDiscardDialog;
private Dialog mCompressionDialog;
private OnBackPressedCallback mBackPressedCallback = new OnBackPressedCallback(true) {
@Override
public void handleOnBackPressed() {
if (mDeviceNeedsToUpdate) {
showDiscardDialog();
} else {
// Let default behavior handle it
setEnabled(false);
getOnBackPressedDispatcher().onBackPressed();
}
}
};
private final DialogInterface.OnClickListener mCompressionEntrySelectedListener = new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
@ -313,6 +327,9 @@ public class DeviceActivity extends SyncthingActivity {
// Show expert options conditionally.
Boolean prefExpertMode = mPreferences.getBoolean(Constants.PREF_EXPERT_MODE, false);
mCompressionContainer.setVisibility(prefExpertMode ? View.VISIBLE : View.GONE);
// Register OnBackPressedCallback
getOnBackPressedDispatcher().addCallback(this, mBackPressedCallback);
}
private void restoreDialogStates(Bundle savedInstanceState) {
@ -363,16 +380,6 @@ public class DeviceActivity extends SyncthingActivity {
}
}
@Override
public void onBackPressed() {
if (mDeviceNeedsToUpdate) {
showDiscardDialog();
}
else {
super.onBackPressed();
}
}
@Override
public void onDestroy() {
super.onDestroy();
@ -489,7 +496,7 @@ public class DeviceActivity extends SyncthingActivity {
showDeleteDialog();
return true;
} else if (itemId == android.R.id.home) {
onBackPressed();
mBackPressedCallback.handleOnBackPressed();
return true;
}
return super.onOptionsItemSelected(item);

View File

@ -27,6 +27,7 @@ import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
import androidx.activity.OnBackPressedCallback;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.SwitchCompat;
@ -144,6 +145,19 @@ public class FolderActivity extends SyncthingActivity {
private Dialog mDeleteDialog;
private Dialog mDiscardDialog;
private OnBackPressedCallback mBackPressedCallback = new OnBackPressedCallback(true) {
@Override
public void handleOnBackPressed() {
if (mFolderNeedsToUpdate) {
showDiscardDialog();
} else {
// Let default behavior handle it
setEnabled(false);
getOnBackPressedDispatcher().onBackPressed();
}
}
};
private final TextWatcher mTextWatcher = new TextWatcherAdapter() {
@Override
public void afterTextChanged(Editable s) {
@ -354,6 +368,9 @@ public class FolderActivity extends SyncthingActivity {
// Open keyboard on label view in edit mode.
mLabelView.requestFocus();
// Register OnBackPressedCallback
getOnBackPressedDispatcher().addCallback(this, mBackPressedCallback);
}
private void restoreDialogStates(Bundle savedInstanceState) {
@ -476,16 +493,6 @@ public class FolderActivity extends SyncthingActivity {
return bundle;
}
@Override
public void onBackPressed() {
if (mFolderNeedsToUpdate) {
showDiscardDialog();
}
else {
super.onBackPressed();
}
}
@Override
public void onDestroy() {
super.onDestroy();
@ -616,7 +623,7 @@ public class FolderActivity extends SyncthingActivity {
showDeleteDialog();
return true;
} else if (itemId == android.R.id.home) {
onBackPressed();
mBackPressedCallback.handleOnBackPressed();
return true;
}
return super.onOptionsItemSelected(item);

View File

@ -22,6 +22,7 @@ import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import androidx.activity.OnBackPressedCallback;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
@ -73,6 +74,14 @@ public class FolderPickerActivity extends SyncthingActivity
*/
private File mLocation;
private OnBackPressedCallback mBackPressedCallback = new OnBackPressedCallback(true) {
@Override
public void handleOnBackPressed() {
setResult(Activity.RESULT_CANCELED);
finish();
}
};
public static Intent createIntent(Context context, String initialDirectory, @Nullable String rootDirectory) {
Intent intent = new Intent(context, FolderPickerActivity.class);
@ -108,6 +117,9 @@ public class FolderPickerActivity extends SyncthingActivity
return;
}
displayRoot();
// Register OnBackPressedCallback
getOnBackPressedDispatcher().addCallback(this, mBackPressedCallback);
}
/**
@ -319,12 +331,6 @@ public class FolderPickerActivity extends SyncthingActivity
* If we already are in the list of roots, or if we are directly in the only
* root folder, we cancel.
*/
@Override
public void onBackPressed() {
setResult(Activity.RESULT_CANCELED);
finish();
super.onBackPressed();
}
/**
* Displays a list of all available roots, or if there is only one root, the

View File

@ -7,6 +7,7 @@ import android.widget.AdapterView;
import android.widget.Button;
import android.widget.Spinner;
import androidx.activity.OnBackPressedCallback;
import androidx.appcompat.app.AppCompatActivity;
import com.nutomic.syncthingandroid.R;
@ -22,6 +23,14 @@ public class FolderTypeDialogActivity extends ThemedAppCompatActivity {
private String selectedType;
private OnBackPressedCallback mBackPressedCallback = new OnBackPressedCallback(true) {
@Override
public void handleOnBackPressed() {
saveConfiguration();
finish();
}
};
private static final List<String> mTypes = Arrays.asList(
Constants.FOLDER_TYPE_SEND_RECEIVE,
Constants.FOLDER_TYPE_SEND_ONLY,
@ -38,6 +47,9 @@ public class FolderTypeDialogActivity extends ThemedAppCompatActivity {
}
initiateFinishBtn();
initiateSpinner();
// Register OnBackPressedCallback
getOnBackPressedDispatcher().addCallback(this, mBackPressedCallback);
}
private void initiateFinishBtn() {
@ -71,10 +83,4 @@ public class FolderTypeDialogActivity extends ThemedAppCompatActivity {
}
});
}
@Override
public void onBackPressed() {
saveConfiguration();
super.onBackPressed();
}
}

View File

@ -28,6 +28,7 @@ import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.TextView;
import androidx.activity.OnBackPressedCallback;
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.ActionBarDrawerToggle;
import androidx.appcompat.app.AlertDialog;
@ -121,6 +122,23 @@ public class MainActivity extends SyncthingActivity
private final Handler mUIRefreshHandler = new Handler();
private OnBackPressedCallback mBackPressedCallback = new OnBackPressedCallback(true) {
@Override
public void handleOnBackPressed() {
if (mDrawerLayout.isDrawerOpen(GravityCompat.START)) {
// Close drawer on back button press.
closeDrawer();
} else {
/**
* Leave MainActivity in its state as the home button was pressed.
* This will avoid waiting for the loading spinner when getting back
* and give changes to do UI updates based on EventProcessor in the future.
*/
moveTaskToBack(true);
}
}
};
private Runnable mUIRefreshRunnable = new Runnable() {
@Override
public void run() {
@ -253,6 +271,9 @@ public class MainActivity extends SyncthingActivity
}
onNewIntent(getIntent());
// Register OnBackPressedCallback
getOnBackPressedDispatcher().addCallback(this, mBackPressedCallback);
}
@ -549,22 +570,6 @@ public class MainActivity extends SyncthingActivity
return super.onKeyDown(keyCode, e);
}
@Override
public void onBackPressed() {
if (mDrawerLayout.isDrawerOpen(GravityCompat.START)) {
// Close drawer on back button press.
closeDrawer();
} else {
/**
* Leave MainActivity in its state as the home button was pressed.
* This will avoid waiting for the loading spinner when getting back
* and give changes to do UI updates based on EventProcessor in the future.
*/
moveTaskToBack(true);
}
super.onBackPressed();
}
/**
* Calculating width based on
* http://www.google.com/design/spec/patterns/navigation-drawer.html#navigation-drawer-specs.

View File

@ -7,6 +7,7 @@ import android.widget.AdapterView;
import android.widget.Button;
import android.widget.Spinner;
import androidx.activity.OnBackPressedCallback;
import androidx.appcompat.app.AppCompatActivity;
import com.nutomic.syncthingandroid.R;
@ -21,6 +22,14 @@ public class PullOrderDialogActivity extends ThemedAppCompatActivity {
private String selectedType;
private OnBackPressedCallback mBackPressedCallback = new OnBackPressedCallback(true) {
@Override
public void handleOnBackPressed() {
saveConfiguration();
finish();
}
};
private static final List<String> mTypes = Arrays.asList(
"random",
"alphabetic",
@ -39,6 +48,9 @@ public class PullOrderDialogActivity extends ThemedAppCompatActivity {
}
initiateFinishBtn();
initiateSpinner();
// Register OnBackPressedCallback
getOnBackPressedDispatcher().addCallback(this, mBackPressedCallback);
}
private void initiateFinishBtn() {
@ -72,10 +84,4 @@ public class PullOrderDialogActivity extends ThemedAppCompatActivity {
}
});
}
@Override
public void onBackPressed() {
saveConfiguration();
super.onBackPressed();
}
}

View File

@ -17,6 +17,8 @@ import android.widget.CompoundButton;
import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.activity.OnBackPressedCallback;
import com.nutomic.syncthingandroid.R;
import com.nutomic.syncthingandroid.SyncthingApp;
import com.nutomic.syncthingandroid.service.Constants;
@ -78,6 +80,14 @@ public class SyncConditionsActivity extends SyncthingActivity {
@Inject
SharedPreferences mPreferences;
private OnBackPressedCallback mBackPressedCallback = new OnBackPressedCallback(true) {
@Override
public void handleOnBackPressed() {
setResult(Activity.RESULT_OK);
finish();
}
};
public static Intent createIntent(Context context, String objectPrefixAndId, String objectReadableName) {
Intent intent = new Intent(context, SyncConditionsActivity.class);
intent.putExtra(EXTRA_OBJECT_PREFIX_AND_ID, objectPrefixAndId);
@ -196,6 +206,9 @@ public class SyncConditionsActivity extends SyncthingActivity {
* the switches here would else not be saved back to the prefs.
*/
mUnsavedChanges = true;
// Register OnBackPressedCallback
getOnBackPressedDispatcher().addCallback(this, mBackPressedCallback);
}
private final CompoundButton.OnCheckedChangeListener mCheckedListener =
@ -263,21 +276,11 @@ public class SyncConditionsActivity extends SyncthingActivity {
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
onBackPressed();
mBackPressedCallback.handleOnBackPressed();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
/**
* Cancel without saving changes.
*/
@Override
public void onBackPressed() {
setResult(Activity.RESULT_OK);
finish();
super.onBackPressed();
}
}

View File

@ -7,6 +7,7 @@ import android.widget.AdapterView;
import android.widget.Button;
import android.widget.Spinner;
import androidx.activity.OnBackPressedCallback;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentTransaction;
@ -29,6 +30,14 @@ public class VersioningDialogActivity extends ThemedAppCompatActivity {
private Bundle mArguments;
private OnBackPressedCallback mBackPressedCallback = new OnBackPressedCallback(true) {
@Override
public void handleOnBackPressed() {
saveConfiguration();
finish();
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@ -43,6 +52,9 @@ public class VersioningDialogActivity extends ThemedAppCompatActivity {
updateFragmentView(mTypes.indexOf(getIntent().getExtras().getString("type")));
initiateFinishBtn();
initiateSpinner();
// Register OnBackPressedCallback
getOnBackPressedDispatcher().addCallback(this, mBackPressedCallback);
}
private void initiateFinishBtn() {
@ -126,10 +138,4 @@ public class VersioningDialogActivity extends ThemedAppCompatActivity {
super.onSaveInstanceState(outState);
outState.putBundle("arguments", mCurrentFragment.getArguments());
}
@Override
public void onBackPressed() {
saveConfiguration();
super.onBackPressed();
}
}

View File

@ -22,6 +22,8 @@ import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.Toast;
import androidx.activity.OnBackPressedCallback;
import com.nutomic.syncthingandroid.R;
import com.nutomic.syncthingandroid.service.Constants;
import com.nutomic.syncthingandroid.service.SyncthingService;
@ -66,6 +68,17 @@ public class WebGuiActivity extends SyncthingActivity
private ConfigXml mConfig;
private OnBackPressedCallback mBackPressedCallback = new OnBackPressedCallback(true) {
@Override
public void handleOnBackPressed() {
if (mWebView.canGoBack()) {
mWebView.goBack();
} else {
finish();
}
}
};
/**
* Hides the loading screen and shows the WebView once it is fully loaded.
*/
@ -158,6 +171,9 @@ public class WebGuiActivity extends SyncthingActivity
} else {
startService(serviceIntent);
}
// Register OnBackPressedCallback
getOnBackPressedDispatcher().addCallback(this, mBackPressedCallback);
}
@Override
@ -187,16 +203,6 @@ public class WebGuiActivity extends SyncthingActivity
}
}
@Override
public void onBackPressed() {
if (mWebView.canGoBack()) {
mWebView.goBack();
} else {
finish();
super.onBackPressed();
}
}
@Override
public void onPause() {
mWebView.onPause();

View File

@ -15,6 +15,7 @@ import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.TextView;
import androidx.activity.OnBackPressedCallback;
import androidx.appcompat.app.AlertDialog;
import com.nutomic.syncthingandroid.R;
@ -39,6 +40,17 @@ public class WebViewActivity extends SyncthingActivity {
private Boolean isRunningOnTV = false;
private String webPageUrl = "";
private OnBackPressedCallback mBackPressedCallback = new OnBackPressedCallback(true) {
@Override
public void handleOnBackPressed() {
if (mWebView.canGoBack()) {
mWebView.goBack();
} else {
finish();
}
}
};
/**
* Hides the loading screen and shows the WebView once it is fully loaded.
*/
@ -111,6 +123,9 @@ public class WebViewActivity extends SyncthingActivity {
mWebView.stopLoading();
mWebView.loadUrl(webPageUrl);
}
// Register the OnBackPressedCallback
getOnBackPressedDispatcher().addCallback(this, mBackPressedCallback);
}
/**
@ -148,16 +163,6 @@ public class WebViewActivity extends SyncthingActivity {
return super.onOptionsItemSelected(item);
}
@Override
public void onBackPressed() {
if (mWebView.canGoBack()) {
mWebView.goBack();
} else {
finish();
super.onBackPressed();
}
}
@Override
public void onPause() {
mWebView.onPause();