diff --git a/shell/platform/android/io/flutter/embedding/android/FlutterActivityAndFragmentDelegate.java b/shell/platform/android/io/flutter/embedding/android/FlutterActivityAndFragmentDelegate.java index 0990604b9ba1b..e3d0235ff621e 100644 --- a/shell/platform/android/io/flutter/embedding/android/FlutterActivityAndFragmentDelegate.java +++ b/shell/platform/android/io/flutter/embedding/android/FlutterActivityAndFragmentDelegate.java @@ -400,7 +400,7 @@ private String maybeGetInitialRouteFromIntent(Intent intent) { Uri data = intent.getData(); if (data != null && !data.getPath().isEmpty()) { String pathAndQuery = data.getPath(); - if (!data.getQuery().isEmpty()) { + if (data.getQuery() != null && !data.getQuery().isEmpty()) { pathAndQuery += "?" + data.getQuery(); } return pathAndQuery; diff --git a/shell/platform/android/test/io/flutter/embedding/android/FlutterActivityAndFragmentDelegateTest.java b/shell/platform/android/test/io/flutter/embedding/android/FlutterActivityAndFragmentDelegateTest.java index 509b97791cd9c..848ad8505495e 100644 --- a/shell/platform/android/test/io/flutter/embedding/android/FlutterActivityAndFragmentDelegateTest.java +++ b/shell/platform/android/test/io/flutter/embedding/android/FlutterActivityAndFragmentDelegateTest.java @@ -456,6 +456,32 @@ public void itForwardsOnRequestPermissionsResultToFlutterEngine() { .setInitialRoute("/custom/route?query=test"); } + @Test + public void + itSendsInitialRouteFromIntentOnStartIfNoInitialRouteFromActivityAndShouldHandleDeeplinkingNoQueryParameter() { + Intent intent = FlutterActivity.createDefaultIntent(RuntimeEnvironment.application); + intent.setData(Uri.parse("http://myApp/custom/route")); + + ActivityController activityController = + Robolectric.buildActivity(FlutterActivity.class, intent); + FlutterActivity flutterActivity = activityController.get(); + + when(mockHost.getActivity()).thenReturn(flutterActivity); + when(mockHost.getInitialRoute()).thenReturn(null); + when(mockHost.shouldHandleDeeplinking()).thenReturn(true); + // Create the real object that we're testing. + FlutterActivityAndFragmentDelegate delegate = new FlutterActivityAndFragmentDelegate(mockHost); + + // --- Execute the behavior under test --- + // The FlutterEngine is setup in onAttach(). + delegate.onAttach(RuntimeEnvironment.application); + // Emulate app start. + delegate.onStart(); + + // Verify that the navigation channel was given the initial route message. + verify(mockFlutterEngine.getNavigationChannel(), times(1)).setInitialRoute("/custom/route"); + } + @Test public void itSendsdefaultInitialRouteOnStartIfNotDeepLinkingFromIntent() { // Creates an empty intent without launch uri. @@ -501,6 +527,25 @@ public void itSendsPushRouteMessageWhenOnNewIntent() { .pushRoute("/custom/route?query=test"); } + @Test + public void itSendsPushRouteMessageWhenOnNewIntentNoQueryParameter() { + when(mockHost.shouldHandleDeeplinking()).thenReturn(true); + // Create the real object that we're testing. + FlutterActivityAndFragmentDelegate delegate = new FlutterActivityAndFragmentDelegate(mockHost); + + // --- Execute the behavior under test --- + // The FlutterEngine is setup in onAttach(). + delegate.onAttach(RuntimeEnvironment.application); + + Intent mockIntent = mock(Intent.class); + when(mockIntent.getData()).thenReturn(Uri.parse("http://myApp/custom/route")); + // Emulate the host and call the method that we expect to be forwarded. + delegate.onNewIntent(mockIntent); + + // Verify that the navigation channel was given the push route message. + verify(mockFlutterEngine.getNavigationChannel(), times(1)).pushRoute("/custom/route"); + } + @Test public void itForwardsOnNewIntentToFlutterEngine() { // Create the real object that we're testing.