diff --git a/app/build.gradle b/app/build.gradle index 130a60d1c1..a5ee9b086a 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -327,7 +327,7 @@ dependencies { def annotation_version_experimental = "1.2.0" def core_version = "1.8.0" // 1.9.0-alpha03 def shortcuts_version = "1.0.1" - def appcompat_version = "1.4.2" // 1.6.0-alpha01 + def appcompat_version = "1.6.0-alpha04" def emoji_version = "1.2.0-alpha04" def activity_version = "1.5.0-rc01" // 1.6.0-alpha03 def fragment_version = "1.5.0-rc01" diff --git a/app/src/amazon/AndroidManifest.xml b/app/src/amazon/AndroidManifest.xml index 2adf63766c..20a369edb2 100644 --- a/app/src/amazon/AndroidManifest.xml +++ b/app/src/amazon/AndroidManifest.xml @@ -99,7 +99,7 @@ android:allowBackup="false" android:appCategory="productivity" android:description="@string/app_name" - android:enableOnBackInvokedCallback="false" + android:enableOnBackInvokedCallback="true" android:extractNativeLibs="true" android:forceDarkAllowed="false" android:icon="@mipmap/ic_launcher" diff --git a/app/src/fdroid/AndroidManifest.xml b/app/src/fdroid/AndroidManifest.xml index 0535225e5a..aabac4262b 100644 --- a/app/src/fdroid/AndroidManifest.xml +++ b/app/src/fdroid/AndroidManifest.xml @@ -99,7 +99,7 @@ android:allowBackup="false" android:appCategory="productivity" android:description="@string/app_name" - android:enableOnBackInvokedCallback="false" + android:enableOnBackInvokedCallback="true" android:extractNativeLibs="true" android:forceDarkAllowed="false" android:icon="@mipmap/ic_launcher" diff --git a/app/src/github/AndroidManifest.xml b/app/src/github/AndroidManifest.xml index 679148feee..0fa9fd3659 100644 --- a/app/src/github/AndroidManifest.xml +++ b/app/src/github/AndroidManifest.xml @@ -99,7 +99,7 @@ android:allowBackup="false" android:appCategory="productivity" android:description="@string/app_name" - android:enableOnBackInvokedCallback="false" + android:enableOnBackInvokedCallback="true" android:extractNativeLibs="true" android:forceDarkAllowed="false" android:icon="@mipmap/ic_launcher" diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index a3512e5b1f..426d2484b6 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -99,7 +99,7 @@ android:allowBackup="false" android:appCategory="productivity" android:description="@string/app_name" - android:enableOnBackInvokedCallback="false" + android:enableOnBackInvokedCallback="true" android:extractNativeLibs="true" android:forceDarkAllowed="false" android:icon="@mipmap/ic_launcher" diff --git a/app/src/main/java/eu/faircode/email/ActivityBase.java b/app/src/main/java/eu/faircode/email/ActivityBase.java index ac1a39e6aa..fe42707f08 100644 --- a/app/src/main/java/eu/faircode/email/ActivityBase.java +++ b/app/src/main/java/eu/faircode/email/ActivityBase.java @@ -48,6 +48,7 @@ import android.widget.Toast; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import androidx.appcompat.app.ActionBar; import androidx.appcompat.app.AppCompatActivity; import androidx.core.content.FileProvider; import androidx.core.graphics.ColorUtils; @@ -599,13 +600,6 @@ abstract class ActivityBase extends AppCompatActivity implements SharedPreferenc }); } - @Override - public void onBackPressed() { - if (backHandled()) - return; - super.onBackPressed(); - } - public boolean dispatchKeyEvent(KeyEvent event) { for (IKeyPressedListener listener : keyPressedListeners) if (listener.onKeyPressed(event)) @@ -755,18 +749,22 @@ abstract class ActivityBase extends AppCompatActivity implements SharedPreferenc @Override public boolean onOptionsItemSelected(@NonNull MenuItem item) { if (item.getItemId() == android.R.id.home) { - if (getLifecycle().getCurrentState().isAtLeast(Lifecycle.State.STARTED)) - onBackPressed(); + performBack(); return true; } return super.onOptionsItemSelected(item); } - protected boolean backHandled() { - for (IKeyPressedListener listener : keyPressedListeners) - if (listener.onBackPressed()) - return true; - return false; + public void performBack() { + if (getLifecycle().getCurrentState().isAtLeast(Lifecycle.State.STARTED)) { + ActionBar ab = getSupportActionBar(); + if (ab != null && ab.collapseActionView()) + return; + FragmentManager fm = getSupportFragmentManager(); + if (!fm.isStateSaved() && fm.popBackStackImmediate()) + return; + } + finish(); } @Override @@ -867,7 +865,5 @@ abstract class ActivityBase extends AppCompatActivity implements SharedPreferenc public interface IKeyPressedListener { boolean onKeyPressed(KeyEvent event); - - boolean onBackPressed(); } } diff --git a/app/src/main/java/eu/faircode/email/ActivitySetup.java b/app/src/main/java/eu/faircode/email/ActivitySetup.java index 27bce63d85..efa85a2701 100644 --- a/app/src/main/java/eu/faircode/email/ActivitySetup.java +++ b/app/src/main/java/eu/faircode/email/ActivitySetup.java @@ -21,6 +21,8 @@ package eu.faircode.email; import static eu.faircode.email.ServiceAuthenticator.AUTH_TYPE_GMAIL; +import android.Manifest; +import android.app.Activity; import android.app.Dialog; import android.app.NotificationChannel; import android.app.NotificationChannelGroup; @@ -54,6 +56,7 @@ import android.widget.CompoundButton; import android.widget.TextView; import android.widget.Toast; +import androidx.activity.OnBackPressedCallback; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.appcompat.app.ActionBarDrawerToggle; @@ -312,6 +315,13 @@ public class ActivitySetup extends ActivityBase implements FragmentManager.OnBac getSupportFragmentManager().addOnBackStackChangedListener(this); + getOnBackPressedDispatcher().addCallback(this, new OnBackPressedCallback(true) { + @Override + public void handleOnBackPressed() { + onExit(); + } + }); + if (getSupportFragmentManager().getFragments().size() == 0) { Intent intent = getIntent(); String target = intent.getStringExtra("target"); @@ -418,12 +428,29 @@ public class ActivitySetup extends ActivityBase implements FragmentManager.OnBac drawerToggle.onConfigurationChanged(newConfig); } - @Override - public void onBackPressed() { + public void onExit() { if (drawerLayout.isDrawerOpen(drawerContainer)) drawerLayout.closeDrawer(drawerContainer); - else - super.onBackPressed(); + else { + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this); + boolean setup_reminder = prefs.getBoolean("setup_reminder", true); + + boolean hasContactPermissions = + hasPermission(android.Manifest.permission.READ_CONTACTS); + boolean hasNotificationPermissions = + (Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU || + hasPermission(Manifest.permission.POST_NOTIFICATIONS)); + boolean isIgnoring = !Boolean.FALSE.equals(Helper.isIgnoringOptimizations(this)); + + if (!setup_reminder || + (hasContactPermissions && hasNotificationPermissions && isIgnoring)) + performBack(); + else { + FragmentDialogPermissions fragment = new FragmentDialogPermissions(); + fragment.setTargetActivity(this, REQUEST_STILL); + fragment.show(getSupportFragmentManager(), "setup:still"); + } + } } @Override @@ -474,6 +501,14 @@ public class ActivitySetup extends ActivityBase implements FragmentManager.OnBac if (resultCode == RESULT_OK && data != null) handleImportProviders(data); break; + case ActivitySetup.REQUEST_STILL: + if (resultCode == Activity.RESULT_OK) { + Bundle result = new Bundle(); + result.putInt("page", 0); + getSupportFragmentManager().setFragmentResult("options:tab", result); + } else + performBack(); + break; } } catch (Throwable ex) { Log.e(ex); @@ -482,7 +517,7 @@ public class ActivitySetup extends ActivityBase implements FragmentManager.OnBac private void onMenuClose() { drawerLayout.closeDrawer(drawerContainer, false); - onBackPressed(); + onExit(); } private void onMenuExport() { diff --git a/app/src/main/java/eu/faircode/email/ActivitySignature.java b/app/src/main/java/eu/faircode/email/ActivitySignature.java index c2d6f39a5a..27a40cae75 100644 --- a/app/src/main/java/eu/faircode/email/ActivitySignature.java +++ b/app/src/main/java/eu/faircode/email/ActivitySignature.java @@ -34,7 +34,6 @@ import android.text.Spanned; import android.text.TextUtils; import android.text.TextWatcher; import android.text.style.ImageSpan; -import android.view.KeyEvent; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuInflater; @@ -45,6 +44,7 @@ import android.widget.EditText; import android.widget.ImageButton; import android.widget.TextView; +import androidx.activity.OnBackPressedCallback; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.appcompat.app.AlertDialog; @@ -157,14 +157,9 @@ public class ActivitySignature extends ActivityBase { } }); - addKeyPressedListener(new IKeyPressedListener() { + getOnBackPressedDispatcher().addCallback(this, new OnBackPressedCallback(true) { @Override - public boolean onKeyPressed(KeyEvent event) { - return false; - } - - @Override - public boolean onBackPressed() { + public void handleOnBackPressed() { String prev = getIntent().getStringExtra("html"); String current = getHtml(); boolean dirty = !Objects.equals(prev, current) && @@ -178,7 +173,7 @@ public class ActivitySignature extends ActivityBase { @Override public void onClick(DialogInterface dialog, int which) { save(); - finish(); + performBack(); } }) .setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() { @@ -189,11 +184,9 @@ public class ActivitySignature extends ActivityBase { }) .show(); else - finish(); - - return true; + performBack(); } - }, this); + }); // Initialize FragmentDialogTheme.setBackground(this, view, true); diff --git a/app/src/main/java/eu/faircode/email/ActivityView.java b/app/src/main/java/eu/faircode/email/ActivityView.java index 49c3907aa0..04105a6087 100644 --- a/app/src/main/java/eu/faircode/email/ActivityView.java +++ b/app/src/main/java/eu/faircode/email/ActivityView.java @@ -54,6 +54,7 @@ import android.widget.LinearLayout; import android.widget.TextView; import android.widget.Toast; +import androidx.activity.OnBackPressedCallback; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.appcompat.app.ActionBarDrawerToggle; @@ -695,6 +696,13 @@ public class ActivityView extends ActivityBilling implements FragmentManager.OnB getSupportFragmentManager().addOnBackStackChangedListener(this); + getOnBackPressedDispatcher().addCallback(this, new OnBackPressedCallback(true) { + @Override + public void handleOnBackPressed() { + onExit(); + } + }); + // Initialize if (content_pane != null) { @@ -1242,8 +1250,7 @@ public class ActivityView extends ActivityBilling implements FragmentManager.OnB return (getDrawerWidthPinned() >= dp200); } - @Override - public void onBackPressed() { + private void onExit() { int count = getSupportFragmentManager().getBackStackEntryCount(); if (!nav_pinned && drawerLayout.isDrawerOpen(drawerContainer) && @@ -1251,15 +1258,15 @@ public class ActivityView extends ActivityBilling implements FragmentManager.OnB drawerLayout.closeDrawer(drawerContainer); else { if (exit || count > 1) - super.onBackPressed(); - else if (!backHandled()) { + performBack(); + else { SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(ActivityView.this); boolean double_back = prefs.getBoolean("double_back", false); if (searching || !double_back) - super.onBackPressed(); + performBack(); else { exit = true; - ToastEx.makeText(this, R.string.app_exit, Toast.LENGTH_SHORT).show(); + ToastEx.makeText(ActivityView.this, R.string.app_exit, Toast.LENGTH_SHORT).show(); getMainHandler().postDelayed(new Runnable() { @Override public void run() { @@ -1308,7 +1315,7 @@ public class ActivityView extends ActivityBilling implements FragmentManager.OnB public boolean onOptionsItemSelected(MenuItem item) { if (drawerToggle.onOptionsItemSelected(item)) { if (nav_pinned) - onBackPressed(); + onExit(); else { int count = getSupportFragmentManager().getBackStackEntryCount(); if (count == 1 && drawerLayout.isLocked(drawerContainer)) diff --git a/app/src/main/java/eu/faircode/email/FragmentAccount.java b/app/src/main/java/eu/faircode/email/FragmentAccount.java index 98761bf85d..d993d269e4 100644 --- a/app/src/main/java/eu/faircode/email/FragmentAccount.java +++ b/app/src/main/java/eu/faircode/email/FragmentAccount.java @@ -38,7 +38,6 @@ import android.text.Editable; import android.text.TextUtils; import android.text.TextWatcher; import android.text.method.LinkMovementMethod; -import android.view.KeyEvent; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuInflater; @@ -56,6 +55,7 @@ import android.widget.ScrollView; import android.widget.Spinner; import android.widget.TextView; +import androidx.activity.OnBackPressedCallback; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.appcompat.widget.PopupMenu; @@ -490,16 +490,10 @@ public class FragmentAccount extends FragmentBase { } }); - addKeyPressedListener(new ActivityBase.IKeyPressedListener() { + getActivity().getOnBackPressedDispatcher().addCallback(getViewLifecycleOwner(), new OnBackPressedCallback(true) { @Override - public boolean onKeyPressed(KeyEvent event) { - return false; - } - - @Override - public boolean onBackPressed() { + public void handleOnBackPressed() { onSave(true); - return true; } }); @@ -1383,9 +1377,9 @@ public class FragmentAccount extends FragmentBase { if (context != null) WidgetUnified.updateData(context); // Update color stripe - if (getLifecycle().getCurrentState().isAtLeast(Lifecycle.State.STARTED)) { - getParentFragmentManager().popBackStack(); + finish(); + if (getLifecycle().getCurrentState().isAtLeast(Lifecycle.State.STARTED)) { boolean saved = args.getBoolean("saved"); if (saved && cbIdentity.isChecked()) { Bundle aargs = new Bundle(); @@ -1689,7 +1683,8 @@ public class FragmentAccount extends FragmentBase { fragment.setArguments(aargs); - getParentFragmentManager().popBackStack(); + finish(); + FragmentTransaction fragmentTransaction = getParentFragmentManager().beginTransaction(); fragmentTransaction.replace(R.id.content_frame, fragment).addToBackStack("quick"); fragmentTransaction.commit(); @@ -1826,8 +1821,8 @@ public class FragmentAccount extends FragmentBase { onSave(false); else onCheck(); - } else if (getLifecycle().getCurrentState().isAtLeast(Lifecycle.State.STARTED)) - getParentFragmentManager().popBackStack(); + } else + finish(); break; case REQUEST_DELETE: if (resultCode == RESULT_OK) @@ -1864,8 +1859,7 @@ public class FragmentAccount extends FragmentBase { @Override protected void onExecuted(Bundle args, Void data) { - if (getLifecycle().getCurrentState().isAtLeast(Lifecycle.State.STARTED)) - getParentFragmentManager().popBackStack(); + finish(); } @Override diff --git a/app/src/main/java/eu/faircode/email/FragmentBase.java b/app/src/main/java/eu/faircode/email/FragmentBase.java index 937a6777f3..6cb6d52c6e 100644 --- a/app/src/main/java/eu/faircode/email/FragmentBase.java +++ b/app/src/main/java/eu/faircode/email/FragmentBase.java @@ -188,7 +188,7 @@ public class FragmentBase extends Fragment { finished = true; if (getLifecycle().getCurrentState().isAtLeast(Lifecycle.State.STARTED)) - getParentFragmentManager().popBackStack(); + getParentFragmentManager().popBackStackImmediate(); else finish = true; } diff --git a/app/src/main/java/eu/faircode/email/FragmentCompose.java b/app/src/main/java/eu/faircode/email/FragmentCompose.java index 7743bdfbc0..6b54c9cb63 100644 --- a/app/src/main/java/eu/faircode/email/FragmentCompose.java +++ b/app/src/main/java/eu/faircode/email/FragmentCompose.java @@ -117,6 +117,7 @@ import android.widget.SpinnerAdapter; import android.widget.TextView; import android.widget.Toast; +import androidx.activity.OnBackPressedCallback; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.appcompat.app.ActionBar; @@ -1051,6 +1052,7 @@ public class FragmentCompose extends FragmentBase { }); addKeyPressedListener(onKeyPressedListener); + getActivity().getOnBackPressedDispatcher().addCallback(getViewLifecycleOwner(), backPressedCallback); // Initialize setHasOptionsMenu(true); @@ -7200,14 +7202,12 @@ public class FragmentCompose extends FragmentBase { return false; } + }; + private OnBackPressedCallback backPressedCallback = new OnBackPressedCallback(true) { @Override - public boolean onBackPressed() { - if (getLifecycle().getCurrentState().isAtLeast(Lifecycle.State.STARTED)) { - onExit(); - return true; - } else - return false; + public void handleOnBackPressed() { + onExit(); } }; diff --git a/app/src/main/java/eu/faircode/email/FragmentFolder.java b/app/src/main/java/eu/faircode/email/FragmentFolder.java index c25e86b495..a6404dda57 100644 --- a/app/src/main/java/eu/faircode/email/FragmentFolder.java +++ b/app/src/main/java/eu/faircode/email/FragmentFolder.java @@ -28,7 +28,6 @@ import android.database.sqlite.SQLiteConstraintException; import android.graphics.Color; import android.os.Bundle; import android.text.TextUtils; -import android.view.KeyEvent; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuInflater; @@ -43,6 +42,7 @@ import android.widget.ImageButton; import android.widget.ScrollView; import android.widget.TextView; +import androidx.activity.OnBackPressedCallback; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.constraintlayout.widget.Group; @@ -238,16 +238,10 @@ public class FragmentFolder extends FragmentBase { } }); - addKeyPressedListener(new ActivityBase.IKeyPressedListener() { + getActivity().getOnBackPressedDispatcher().addCallback(getViewLifecycleOwner(), new OnBackPressedCallback(true) { @Override - public boolean onKeyPressed(KeyEvent event) { - return false; - } - - @Override - public boolean onBackPressed() { + public void handleOnBackPressed() { onSave(true); - return true; } }); @@ -406,8 +400,8 @@ public class FragmentFolder extends FragmentBase { } }); onSave(false); - } else if (getLifecycle().getCurrentState().isAtLeast(Lifecycle.State.STARTED)) - getParentFragmentManager().popBackStack(); + } else + finish(); break; case REQUEST_DELETE_FOLDER: @@ -693,7 +687,7 @@ public class FragmentFolder extends FragmentBase { else prefs.edit().putInt(key, color).apply(); - getParentFragmentManager().popBackStack(); + finish(); } } @@ -750,8 +744,7 @@ public class FragmentFolder extends FragmentBase { @Override protected void onExecuted(Bundle args, Void data) { - if (getLifecycle().getCurrentState().isAtLeast(Lifecycle.State.STARTED)) - getParentFragmentManager().popBackStack(); + finish(); } @Override diff --git a/app/src/main/java/eu/faircode/email/FragmentIdentity.java b/app/src/main/java/eu/faircode/email/FragmentIdentity.java index 32c1c8525d..7e213812a5 100644 --- a/app/src/main/java/eu/faircode/email/FragmentIdentity.java +++ b/app/src/main/java/eu/faircode/email/FragmentIdentity.java @@ -36,7 +36,6 @@ import android.text.Editable; import android.text.TextUtils; import android.text.TextWatcher; import android.text.method.LinkMovementMethod; -import android.view.KeyEvent; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuInflater; @@ -55,6 +54,7 @@ import android.widget.ScrollView; import android.widget.Spinner; import android.widget.TextView; +import androidx.activity.OnBackPressedCallback; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.appcompat.widget.PopupMenu; @@ -491,16 +491,10 @@ public class FragmentIdentity extends FragmentBase { } }); - addKeyPressedListener(new ActivityBase.IKeyPressedListener() { + getActivity().getOnBackPressedDispatcher().addCallback(getViewLifecycleOwner(), new OnBackPressedCallback(true) { @Override - public boolean onKeyPressed(KeyEvent event) { - return false; - } - - @Override - public boolean onBackPressed() { + public void handleOnBackPressed() { onSave(true); - return true; } }); @@ -1045,7 +1039,7 @@ public class FragmentIdentity extends FragmentBase { fragment.setTargetFragment(FragmentIdentity.this, REQUEST_SAVE); fragment.show(getParentFragmentManager(), "identity:save"); } else if (getLifecycle().getCurrentState().isAtLeast(Lifecycle.State.STARTED)) - getParentFragmentManager().popBackStack(); + finish(); } @Override @@ -1419,8 +1413,8 @@ public class FragmentIdentity extends FragmentBase { } }); onSave(false); - } else if (getLifecycle().getCurrentState().isAtLeast(Lifecycle.State.STARTED)) - getParentFragmentManager().popBackStack(); + } else + finish(); break; case REQUEST_DELETE: if (resultCode == RESULT_OK) @@ -1461,8 +1455,7 @@ public class FragmentIdentity extends FragmentBase { @Override protected void onExecuted(Bundle args, Void data) { - if (getLifecycle().getCurrentState().isAtLeast(Lifecycle.State.STARTED)) - getParentFragmentManager().popBackStack(); + finish(); } @Override diff --git a/app/src/main/java/eu/faircode/email/FragmentMessages.java b/app/src/main/java/eu/faircode/email/FragmentMessages.java index c111ecbb27..894f6c0dc7 100644 --- a/app/src/main/java/eu/faircode/email/FragmentMessages.java +++ b/app/src/main/java/eu/faircode/email/FragmentMessages.java @@ -123,6 +123,7 @@ import android.widget.SeekBar; 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; @@ -1626,7 +1627,8 @@ public class FragmentMessages extends FragmentBase implements SharedPreferences. } }); - addKeyPressedListener(onBackPressedListener); + addKeyPressedListener(keyPressedListener); + getActivity().getOnBackPressedDispatcher().addCallback(getViewLifecycleOwner(), backPressedCallback); // Initialize FragmentDialogTheme.setBackground(getContext(), view, false); @@ -7189,7 +7191,7 @@ public class FragmentMessages extends FragmentBase implements SharedPreferences. searchView.clearComposingText(); } - private ActivityBase.IKeyPressedListener onBackPressedListener = new ActivityBase.IKeyPressedListener() { + private ActivityBase.IKeyPressedListener keyPressedListener = new ActivityBase.IKeyPressedListener() { @Override public boolean onKeyPressed(KeyEvent event) { Context context = getContext(); @@ -7267,44 +7269,6 @@ public class FragmentMessages extends FragmentBase implements SharedPreferences. return holder.onKeyPressed(event); } - @Override - public boolean onBackPressed() { - if (isSearching()) { - endSearch(); - return true; - } - - if (selectionTracker != null && selectionTracker.hasSelection()) { - selectionTracker.clearSelection(); - return true; - } - - if (!getLifecycle().getCurrentState().isAtLeast(Lifecycle.State.STARTED)) - return true; - - SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getContext()); - boolean collapse_multiple = prefs.getBoolean("collapse_multiple", true); - - int count = 0; - for (int i = 0; i < adapter.getItemCount(); i++) { - TupleMessageEx message = adapter.getItemAtPosition(i); - if (message != null && !message.duplicate) - count++; - } - - int expanded = (values.containsKey("expanded") ? values.get("expanded").size() : 0); - if (collapse_multiple && expanded > 0 && count > 1) { - values.get("expanded").clear(); - updateExpanded(); - iProperties.refresh(); - return true; - } - - handleExit(); - - return false; - } - private boolean onNext(Context context) { if (next == null) { Animation bounce = AnimationUtils.loadAnimation(context, R.anim.bounce_left); @@ -7375,6 +7339,45 @@ public class FragmentMessages extends FragmentBase implements SharedPreferences. } }; + private OnBackPressedCallback backPressedCallback = new OnBackPressedCallback(true) { + @Override + public void handleOnBackPressed() { + if (isSearching()) { + endSearch(); + return; + } + + if (selectionTracker != null && selectionTracker.hasSelection()) { + selectionTracker.clearSelection(); + return; + } + + if (!getLifecycle().getCurrentState().isAtLeast(Lifecycle.State.STARTED)) + return; + + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getContext()); + boolean collapse_multiple = prefs.getBoolean("collapse_multiple", true); + + int count = 0; + for (int i = 0; i < adapter.getItemCount(); i++) { + TupleMessageEx message = adapter.getItemAtPosition(i); + if (message != null && !message.duplicate) + count++; + } + + int expanded = (values.containsKey("expanded") ? values.get("expanded").size() : 0); + if (collapse_multiple && expanded > 0 && count > 1) { + values.get("expanded").clear(); + updateExpanded(); + iProperties.refresh(); + return; + } + + handleExit(); + finish(); + } + }; + @Override public Animation onCreateAnimation(int transit, boolean enter, int nextAnim) { Bundle args = getArguments(); diff --git a/app/src/main/java/eu/faircode/email/FragmentOptions.java b/app/src/main/java/eu/faircode/email/FragmentOptions.java index 8f40f1af31..2b3045c628 100644 --- a/app/src/main/java/eu/faircode/email/FragmentOptions.java +++ b/app/src/main/java/eu/faircode/email/FragmentOptions.java @@ -19,22 +19,17 @@ package eu.faircode.email; Copyright 2018-2022 by Marcel Bokhorst (M66B) */ -import android.Manifest; -import android.app.Activity; import android.content.Context; import android.content.DialogInterface; -import android.content.Intent; import android.content.SharedPreferences; import android.database.Cursor; import android.database.MatrixCursor; import android.graphics.PorterDuff; import android.graphics.drawable.Drawable; -import android.os.Build; import android.os.Bundle; import android.text.SpannableStringBuilder; import android.text.TextUtils; import android.text.style.RelativeSizeSpan; -import android.view.KeyEvent; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuInflater; @@ -52,6 +47,7 @@ import androidx.cursoradapter.widget.CursorAdapter; import androidx.cursoradapter.widget.SimpleCursorAdapter; import androidx.fragment.app.Fragment; import androidx.fragment.app.FragmentManager; +import androidx.fragment.app.FragmentResultListener; import androidx.fragment.app.FragmentStatePagerAdapter; import androidx.lifecycle.Lifecycle; import androidx.lifecycle.LifecycleObserver; @@ -222,19 +218,11 @@ public class FragmentOptions extends FragmentBase { } }); - addKeyPressedListener(new ActivityBase.IKeyPressedListener() { + getParentFragmentManager().setFragmentResultListener("options:tab", this, new FragmentResultListener() { @Override - public boolean onKeyPressed(KeyEvent event) { - return false; - } - - @Override - public boolean onBackPressed() { - if (getLifecycle().getCurrentState().isAtLeast(Lifecycle.State.STARTED)) { - onExit(); - return true; - } else - return false; + public void onFragmentResult(@NonNull String requestKey, @NonNull Bundle result) { + int page = result.getInt("page"); + pager.setCurrentItem(page); } }); @@ -268,11 +256,6 @@ public class FragmentOptions extends FragmentBase { } } - @Override - protected void finish() { - onExit(); - } - @Override public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { inflater.inflate(R.menu.menu_setup, menu); @@ -465,46 +448,6 @@ public class FragmentOptions extends FragmentBase { super.onCreateOptionsMenu(menu, inflater); } - @Override - public void onActivityResult(int requestCode, int resultCode, Intent data) { - super.onActivityResult(requestCode, resultCode, data); - - try { - switch (requestCode) { - case ActivitySetup.REQUEST_STILL: - if (resultCode == Activity.RESULT_OK) - pager.setCurrentItem(0); - else - super.finish(); - break; - } - } catch (Throwable ex) { - Log.e(ex); - } - } - - private void onExit() { - final Context context = getContext(); - SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); - boolean setup_reminder = prefs.getBoolean("setup_reminder", true); - - boolean hasContactPermissions = - hasPermission(Manifest.permission.READ_CONTACTS); - boolean hasNotificationPermissions = - (Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU || - hasPermission(Manifest.permission.POST_NOTIFICATIONS)); - boolean isIgnoring = !Boolean.FALSE.equals(Helper.isIgnoringOptimizations(context)); - - if (!setup_reminder || - (hasContactPermissions && hasNotificationPermissions && isIgnoring)) - super.finish(); - else { - FragmentDialogPermissions fragment = new FragmentDialogPermissions(); - fragment.setTargetFragment(this, ActivitySetup.REQUEST_STILL); - fragment.show(getParentFragmentManager(), "setup:still"); - } - } - static void reset(Context context, String[] options, Runnable confirmed) { new AlertDialog.Builder(context) .setIcon(R.drawable.twotone_help_24) diff --git a/app/src/main/java/eu/faircode/email/FragmentPop.java b/app/src/main/java/eu/faircode/email/FragmentPop.java index b3132ebb7a..a6cce19b0a 100644 --- a/app/src/main/java/eu/faircode/email/FragmentPop.java +++ b/app/src/main/java/eu/faircode/email/FragmentPop.java @@ -34,7 +34,6 @@ import android.os.Bundle; import android.text.Editable; import android.text.TextUtils; import android.text.TextWatcher; -import android.view.KeyEvent; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuInflater; @@ -51,6 +50,7 @@ import android.widget.ScrollView; import android.widget.Spinner; import android.widget.TextView; +import androidx.activity.OnBackPressedCallback; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.constraintlayout.widget.Group; @@ -275,16 +275,10 @@ public class FragmentPop extends FragmentBase { } }); - addKeyPressedListener(new ActivityBase.IKeyPressedListener() { + getActivity().getOnBackPressedDispatcher().addCallback(getViewLifecycleOwner(), new OnBackPressedCallback(true) { @Override - public boolean onKeyPressed(KeyEvent event) { - return false; - } - - @Override - public boolean onBackPressed() { + public void handleOnBackPressed() { onSave(true); - return true; } }); @@ -641,9 +635,9 @@ public class FragmentPop extends FragmentBase { if (context != null) WidgetUnified.updateData(context); // Update color stripe - if (getLifecycle().getCurrentState().isAtLeast(Lifecycle.State.STARTED)) { - getParentFragmentManager().popBackStack(); + finish(); + if (getLifecycle().getCurrentState().isAtLeast(Lifecycle.State.STARTED)) { boolean saved = args.getBoolean("saved"); if (saved && cbIdentity.isChecked()) { Bundle aargs = new Bundle(); @@ -878,8 +872,8 @@ public class FragmentPop extends FragmentBase { } }); onSave(false); - } else if (getLifecycle().getCurrentState().isAtLeast(Lifecycle.State.STARTED)) - getParentFragmentManager().popBackStack(); + } else + finish(); break; case REQUEST_DELETE: if (resultCode == RESULT_OK) @@ -916,8 +910,7 @@ public class FragmentPop extends FragmentBase { @Override protected void onExecuted(Bundle args, Void data) { - if (getLifecycle().getCurrentState().isAtLeast(Lifecycle.State.STARTED)) - getParentFragmentManager().popBackStack(); + finish(); } @Override diff --git a/app/src/play/AndroidManifest.xml b/app/src/play/AndroidManifest.xml index b14b767fc6..ee4969ac6b 100644 --- a/app/src/play/AndroidManifest.xml +++ b/app/src/play/AndroidManifest.xml @@ -99,7 +99,7 @@ android:allowBackup="false" android:appCategory="productivity" android:description="@string/app_name" - android:enableOnBackInvokedCallback="false" + android:enableOnBackInvokedCallback="true" android:extractNativeLibs="true" android:forceDarkAllowed="false" android:icon="@mipmap/ic_launcher"