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

Commit 89629fb

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

File tree

2 files changed

+71
-0
lines changed

2 files changed

+71
-0
lines changed

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

Lines changed: 69 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,55 @@ 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+
if (frameworkHandlesBack && !hasRegisteredBackCallback) {
1713+
registerOnBackInvokedCallback();
1714+
} else if (!frameworkHandlesBack && hasRegisteredBackCallback) {
1715+
unregisterOnBackInvokedCallback();
1716+
}
1717+
}
1718+
1719+
/**
1720+
* Registers the callback with OnBackPressedDispatcher to capture back navigation gestures and
1721+
* pass them to the framework.
1722+
*
1723+
* <p>This replaces the deprecated onBackPressed method override in order to support API 33's
1724+
* predictive back navigation feature.
1725+
*
1726+
* <p>The callback must be unregistered in order to prevent unpredictable behavior once outside
1727+
* the Flutter app.
1728+
*/
1729+
@VisibleForTesting
1730+
public void registerOnBackInvokedCallback() {
1731+
if (Build.VERSION.SDK_INT >= 33) {
1732+
getActivity()
1733+
.getOnBackInvokedDispatcher()
1734+
.registerOnBackInvokedCallback(
1735+
OnBackInvokedDispatcher.PRIORITY_DEFAULT, onBackInvokedCallback);
1736+
hasRegisteredBackCallback = true;
1737+
}
1738+
}
1739+
1740+
/**
1741+
* Unregisters the callback from OnBackPressedDispatcher.
1742+
*
1743+
* <p>This should be called when the activity is no longer in use to prevent unpredictable
1744+
* behavior such as being stuck and unable to press back.
1745+
*/
1746+
@VisibleForTesting
1747+
public void unregisterOnBackInvokedCallback() {
1748+
if (Build.VERSION.SDK_INT >= 33) {
1749+
getActivity()
1750+
.getOnBackInvokedDispatcher()
1751+
.unregisterOnBackInvokedCallback(onBackInvokedCallback);
1752+
hasRegisteredBackCallback = false;
1753+
}
1754+
}
1755+
16871756
@VisibleForTesting
16881757
@NonNull
16891758
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)