-
Notifications
You must be signed in to change notification settings - Fork 3.5k
[url_launcher] Add Android support for externalNonBrowserApplication #9993
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
[url_launcher] Add Android support for externalNonBrowserApplication #9993
Conversation
Sets `FLAG_ACTIVITY_REQUIRE_NON_BROWSER` on the launch intent when `externalNonBrowserApplication` is requested. This only works on API 30+, but since that's already >80% of devices, and launch modes are already documented to be best-effort based on platform capabilities, that should be enough. (A fallback is possible, as demonstrated in flutter/plugins#5953, but it's not fully reliable, adds complexity, and relies on adding extra query permissions to the app bundle in order to work, so I am not including that approach.) Fixes flutter/flutter#66721
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Code Review
This pull request adds support for launching URLs in an external, non-browser application on Android by using the FLAG_ACTIVITY_REQUIRE_NON_BROWSER
intent flag. The changes include updating the Pigeon interface to pass a new boolean flag, implementing the logic in the Android native code, and adding corresponding tests and an example usage. My review identifies a bug in the test implementation, a potential improvement in the native Android code for API level compatibility, and a correction for the example app's UI logic.
packages/url_launcher/url_launcher_android/test/url_launcher_android_test.dart
Show resolved
Hide resolved
if (requireNonBrowser) { | ||
launchIntent.addFlags(Intent.FLAG_ACTIVITY_REQUIRE_NON_BROWSER); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The FLAG_ACTIVITY_REQUIRE_NON_BROWSER
flag was introduced in API level 30. While the system may ignore unknown flags on older versions, it's best practice to explicitly check the device's API level before adding a flag that is not available on all supported versions. This makes the code more robust and self-documenting about its API level dependency. You may need to add an import for android.os.Build
.
if (requireNonBrowser) {
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.R) {
launchIntent.addFlags(Intent.FLAG_ACTIVITY_REQUIRE_NON_BROWSER);
}
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@gmackall @reidbaker Does the Android team have a preference here? I had considered adding this but then didn't because presumably adding a flag that didn't exist in old versions should be harmless, so I figured it didn't add any value. I guess the self-documenting aspect is worth considering though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't have a strong preference here, but slightly lean towards including it just for readability.
onPressed: _hasCustomTabSupport | ||
? () => setState(() { | ||
_launched = _launchInNonBrowserExternalApp(toLaunch); | ||
}) | ||
: null, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The onPressed
callback for the 'Launch in non-browser app' button is conditioned on _hasCustomTabSupport
. However, the ability to launch an external non-browser application is not dependent on Custom Tabs support. This condition seems to be incorrectly copied from another button and could prevent users from testing this feature on devices that don't support Custom Tabs but can handle the intent. The button should likely be enabled unconditionally.
onPressed: () => setState(() {
_launched = _launchInNonBrowserExternalApp(toLaunch);
}),
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ha, this was wrong because the code I copied from also shouldn't have had it; it had incorrectly been set up to gate the "launch in browser" button rather than the "launch in custom tab" button.
Fixed my copypasta and the pre-existing bug.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
Sets
FLAG_ACTIVITY_REQUIRE_NON_BROWSER
on the launch intent whenexternalNonBrowserApplication
is requested.This only works on API 30+, but since that's already >80% of devices, and launch modes are already documented to be best-effort based on platform capabilities, that should be enough.
(A fallback is possible, as demonstrated in
flutter/plugins#5953, but it's not fully reliable, adds complexity, and relies on adding extra query permissions to the app bundle in order to work, so I am not including that approach.)
Fixes flutter/flutter#66721
Pre-Review Checklist
[shared_preferences]
pubspec.yaml
with an appropriate new version according to the pub versioning philosophy, or I have commented below to indicate which version change exemption this PR falls under1.CHANGELOG.md
to add a description of the change, following repository CHANGELOG style, or I have commented below to indicate which CHANGELOG exemption this PR falls under1.///
).Footnotes
Regular contributors who have demonstrated familiarity with the repository guidelines only need to comment if the PR is not auto-exempted by repo tooling. ↩ ↩2 ↩3