Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit e2ff310

Browse files
committed
Seems to work whether Flutter is the first acitivty or not
1 parent 543078c commit e2ff310

File tree

2 files changed

+75
-0
lines changed

2 files changed

+75
-0
lines changed

shell/platform/android/io/flutter/embedding/android/FlutterFragment.java

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
import android.view.View;
1515
import android.view.ViewGroup;
1616
import android.view.ViewTreeObserver.OnWindowFocusChangeListener;
17+
import android.window.OnBackInvokedCallback;
18+
import android.window.OnBackInvokedDispatcher;
1719
import androidx.activity.OnBackPressedCallback;
1820
import androidx.annotation.NonNull;
1921
import androidx.annotation.Nullable;
@@ -170,6 +172,8 @@ public class FlutterFragment extends Fragment
170172
protected static final String ARG_SHOULD_AUTOMATICALLY_HANDLE_ON_BACK_PRESSED =
171173
"should_automatically_handle_on_back_pressed";
172174

175+
private boolean hasRegisteredBackCallback = false;
176+
173177
@RequiresApi(18)
174178
private final OnWindowFocusChangeListener onWindowFocusChangeListener =
175179
Build.VERSION.SDK_INT >= 18
@@ -1023,6 +1027,20 @@ public void handleOnBackPressed() {
10231027
}
10241028
};
10251029

1030+
private final OnBackInvokedCallback onBackInvokedCallback =
1031+
Build.VERSION.SDK_INT >= 33
1032+
? new OnBackInvokedCallback() {
1033+
// TODO(garyq): Remove SuppressWarnings annotation. This was added to workaround
1034+
// a google3 bug where the linter is not properly running against API 33, causing
1035+
// a failure here. See b/243609613 and https://github.com/flutter/flutter/issues/111295
1036+
@SuppressWarnings("Override")
1037+
@Override
1038+
public void onBackInvoked() {
1039+
onBackPressed();
1040+
}
1041+
}
1042+
: null;
1043+
10261044
public FlutterFragment() {
10271045
// Ensure that we at least have an empty Bundle of arguments so that we don't
10281046
// need to continually check for null arguments before grabbing one.
@@ -1060,9 +1078,11 @@ public void onAttach(@NonNull Context context) {
10601078
super.onAttach(context);
10611079
delegate = delegateFactory.createDelegate(this);
10621080
delegate.onAttach(context);
1081+
/*
10631082
if (getArguments().getBoolean(ARG_SHOULD_AUTOMATICALLY_HANDLE_ON_BACK_PRESSED, false)) {
10641083
requireActivity().getOnBackPressedDispatcher().addCallback(this, onBackPressedCallback);
10651084
}
1085+
*/
10661086
context.registerComponentCallbacks(this);
10671087
}
10681088

@@ -1684,6 +1704,59 @@ public boolean popSystemNavigator() {
16841704
return false;
16851705
}
16861706

1707+
@Override
1708+
public void setFrameworkHandlesBack(boolean frameworkHandlesBack) {
1709+
Log.e(
1710+
"justin",
1711+
"setFrameworkHandlesBack in FlutterFragment! setEnabled: " + frameworkHandlesBack);
1712+
// TODO(justinmc): Doesn't quite work.
1713+
// Home route: pback works (good)
1714+
// Second route: pback doesn't work (good)
1715+
// Home route again: pback still doesn't work (bad) though I received the right call here...
1716+
if (frameworkHandlesBack && !hasRegisteredBackCallback) {
1717+
registerOnBackInvokedCallback();
1718+
} else if (!frameworkHandlesBack && hasRegisteredBackCallback) {
1719+
unregisterOnBackInvokedCallback();
1720+
}
1721+
}
1722+
1723+
/**
1724+
* Registers the callback with OnBackPressedDispatcher to capture back navigation gestures and
1725+
* pass them to the framework.
1726+
*
1727+
* <p>This replaces the deprecated onBackPressed method override in order to support API 33's
1728+
* predictive back navigation feature.
1729+
*
1730+
* <p>The callback must be unregistered in order to prevent unpredictable behavior once outside
1731+
* the Flutter app.
1732+
*/
1733+
@VisibleForTesting
1734+
public void registerOnBackInvokedCallback() {
1735+
if (Build.VERSION.SDK_INT >= 33) {
1736+
getActivity()
1737+
.getOnBackInvokedDispatcher()
1738+
.registerOnBackInvokedCallback(
1739+
OnBackInvokedDispatcher.PRIORITY_DEFAULT, onBackInvokedCallback);
1740+
hasRegisteredBackCallback = true;
1741+
}
1742+
}
1743+
1744+
/**
1745+
* Unregisters the callback from OnBackPressedDispatcher.
1746+
*
1747+
* <p>This should be called when the activity is no longer in use to prevent unpredictable
1748+
* behavior such as being stuck and unable to press back.
1749+
*/
1750+
@VisibleForTesting
1751+
public void unregisterOnBackInvokedCallback() {
1752+
if (Build.VERSION.SDK_INT >= 33) {
1753+
getActivity()
1754+
.getOnBackInvokedDispatcher()
1755+
.unregisterOnBackInvokedCallback(onBackInvokedCallback);
1756+
hasRegisteredBackCallback = false;
1757+
}
1758+
}
1759+
16871760
@VisibleForTesting
16881761
@NonNull
16891762
boolean shouldDelayFirstAndroidViewDraw() {

shell/platform/android/io/flutter/embedding/android/FlutterFragmentActivity.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -545,6 +545,8 @@ protected FlutterFragment createFlutterFragment() {
545545
.shouldAttachEngineToActivity(shouldAttachEngineToActivity())
546546
.destroyEngineWithFragment(shouldDestroyEngineWithHost())
547547
.shouldDelayFirstAndroidViewDraw(shouldDelayFirstAndroidViewDraw)
548+
// TODO(justinmc): Unsure whether this is relevant to predictive back.
549+
// .shouldAutomaticallyHandleOnBackPressed(Build.VERSION.SDK_INT >= 33)
548550
.build();
549551
} else {
550552
Log.v(

0 commit comments

Comments
 (0)