pub repository
mirror.p-hatan.irapp_links
6.0.1Android App Links, Deep Links, iOs Universal Links and Custom URL schemes handler for Flutter (desktop included).
Readme
app_links
Android App Links, Deep Links, iOS Universal Links and Custom URL schemes handler (desktop included).
This plugin allows you to:
- catch HTTPS URLs to open your app instead of the browser (App Link / Universal Link).
- catch custom schemes to open your app (Deep Link / Custom URL scheme).
Getting Started
Before using the plugin, you'll need to setup each platforms you target.
All those configurations below are accessible in the example project.
Android
- App Links: Documentation
- Deep Links: Documentation
Notes:
- By default, flutter Activity is set with
android:launchMode="singleTop". This is perfectly fine and expected, but this launches another instance of your app, specifically for the requested view.
If you don't want this behaviour, you can setandroid:launchMode="singleInstance"in yourAndroidManifest.xmland avoid another flutter warmup.
In AndroidManifest.xml
<!-- App Link sample -->
<intent-filter android:autoVerify="true">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="https" android:host="www.example.com" android:pathPrefix="/foo" />
</intent-filter>
<!-- Deep Link sample -->
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<!-- Add optional android:host to distinguish your app
from others in case of conflicting scheme name -->
<data android:scheme="sample" android:host="open.my.app" />
<!-- <data android:scheme="sample" /> -->
</intent-filter>
iOS
- Universal Links: Documentation
- Custom URL schemes: Documentation
Warning:
If you have a custom AppDelegate with overridden methods either:
application(_:willFinishLaunchingWithOptions:)- or
application(_:didFinishLaunchingWithOptions:) - or another package also dealing with Universal Links or Custom URL schemes.
Both methods must call super and return true to enable app link workflow. If you can't respect those two constraints or you need a specific process.
import app_links
@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
GeneratedPluginRegistrant.register(with: self)
// Retrieve the link from parameters
if let url = AppLinks.shared.getLink(launchOptions: launchOptions) {
// We have a link, propagate it to your Flutter app or not
AppLinks.shared.handleLink(url: url)
return true // Returning true will stop the propagation to other packages
}
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
}
import app_links
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) {
for context in URLContexts {
AppLinks.shared.handleLink(url: context.url)
}
}
func scene(_ scene: UIScene, continue userActivity: NSUserActivity) {
if let url = userActivity.webpageURL {
AppLinks.shared.handleLink(url: url)
}
}
}
Windows
Add this inclusion in <PROJECT_DIR>\windows\runner\main.cpp
#include "app_links/app_links_plugin_c_api.h"
Add this method before wWinMain
bool SendAppLinkToInstance(const std::wstring& title) {
// Find our exact window
HWND hwnd = ::FindWindow(L"FLUTTER_RUNNER_WIN32_WINDOW", title.c_str());
if (hwnd) {
// Dispatch new link to current window
SendAppLink(hwnd);
// (Optional) Restore our window to front in same state
WINDOWPLACEMENT place = { sizeof(WINDOWPLACEMENT) };
GetWindowPlacement(hwnd, &place);
switch(place.showCmd) {
case SW_SHOWMAXIMIZED:
ShowWindow(hwnd, SW_SHOWMAXIMIZED);
break;
case SW_SHOWMINIMIZED:
ShowWindow(hwnd, SW_RESTORE);
break;
default:
ShowWindow(hwnd, SW_NORMAL);
break;
}
SetWindowPos(0, HWND_TOP, 0, 0, 0, 0, SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOMOVE);
SetForegroundWindow(hwnd);
// END Restore
// Window has been found, don't create another one.
return true;
}
return false;
}
Add the call to the previous method in wWinMain
int APIENTRY wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev,
_In_ wchar_t *command_line, _In_ int show_command) {
// Replace "example" with the generated title found as parameter of `window.Create` in this file.
// You may ignore the result if you need to create another window.
if (SendAppLinkToInstance(L"example")) {
return EXIT_SUCCESS;
}
...
Great!
Now you can register your own scheme. On Windows, URL protocols are setup in the Windows registry.
This package won't do it for you (and will never sorry).
You may achieve it with using the win32_registry package with the following code to register the URL protocol
or copy what's in the example project to get rid of another dependency.
Future<void> register(String scheme) async {
String appPath = Platform.resolvedExecutable;
String protocolRegKey = 'Software\\Classes\\$scheme';
RegistryValue protocolRegValue = const RegistryValue(
'URL Protocol',
RegistryValueType.string,
'',
);
String protocolCmdRegKey = 'shell\\open\\command';
RegistryValue protocolCmdRegValue = RegistryValue(
'',
RegistryValueType.string,
'"$appPath" "%1"',
);
final regKey = Registry.currentUser.createKey(protocolRegKey);
regKey.createValue(protocolRegValue);
regKey.createKey(protocolCmdRegKey).createValue(protocolCmdRegValue);
}
macOS
Add this XML chapter in your macos/Runner/Info.plist inside <plist version="1.0"><dict> chapter:
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLName</key>
<!-- abstract name for this URL type (you can leave it blank) -->
<string>sample_name</string>
<key>CFBundleURLSchemes</key>
<array>
<!-- your schemes -->
<string>sample</string>
</array>
</dict>
</array>
Done!
Linux
Apply the following changes to your linux/my_application.cc file:
diff --git a/example/linux/my_application.cc b/example/linux/my_application.cc
index 0ba8f43..f07f765 100644
--- a/example/linux/my_application.cc
+++ b/example/linux/my_application.cc
@@ -17,6 +17,13 @@ G_DEFINE_TYPE(MyApplication, my_application, GTK_TYPE_APPLICATION)
// Implements GApplication::activate.
static void my_application_activate(GApplication* application) {
MyApplication* self = MY_APPLICATION(application);
+
+ GList* windows = gtk_application_get_windows(GTK_APPLICATION(application));
+ if (windows) {
+ gtk_window_present(GTK_WINDOW(windows->data));
+ return;
+ }
+
GtkWindow* window =
GTK_WINDOW(gtk_application_window_new(GTK_APPLICATION(application)));
@@ -78,7 +85,7 @@ static gboolean my_application_local_command_line(GApplication* application, gch
g_application_activate(application);
*exit_status = 0;
- return TRUE;
+ return FALSE;
}
// Implements GObject::dispose.
@@ -99,6 +106,6 @@ static void my_application_init(MyApplication* self) {}
MyApplication* my_application_new() {
return MY_APPLICATION(g_object_new(my_application_get_type(),
"application-id", APPLICATION_ID,
- "flags", G_APPLICATION_NON_UNIQUE,
+ "flags", G_APPLICATION_HANDLES_COMMAND_LINE | G_APPLICATION_HANDLES_OPEN,
nullptr));
Notes:
- Please ensure your
APPLICATION_IDis the same as your desktop file name if you're using Flathub. - Please ensure you have added this section in your
snapcraft.yamlfile if you're using SnapStore:
slots:
dbus-appflowy:
interface: dbus
bus: session
name: `APPLICATION_ID`
- You can refer to these two repositories for more details: FlatHub setup and Snapcraft setup.
Done!
AppLinks usage
Please, ensure to instantiate AppLinks early in your app to catch the very first link when the app is in cold state.
final _appLinks = AppLinks(); // AppLinks is singleton
// Subscribe to all events (initial link and further)
_appLinks.uriLinkStream.listen((uri) {
// Do something (navigation, ...)
});
Tests
The following commands will help you to test links.
Test on Android
adb shell am start -a android.intent.action.VIEW \
-d "sample://open.my.app/#/book/hello-world"
For App Links, you can also test it from Android Studio: Documentation.
Android 13 and beyond:
- While in development, you may need to manually activate your links.
- Go to your app info/settings: Open by default > Add link > (your links should be already filled).
Test on iOS
/usr/bin/xcrun simctl openurl booted "app://www.example.com/#/book/hello-world"
Test on windows & macOS
Open your browser and type in your address bar:
sample://foo/#/book/hello-world2
Changelog
6.0.1
- fix(linux): Initialization process.
6.0.0
- Breaking: Replaced
allStringLinkStreambystringLinkStreamandallUriLinkStreambyuriLinkStream. - Breaking: Removed
allStringLinkStream,allUriLinkStream.
The changes above should clarify the usage of the plugin. Both streams handle initial and further links. - Breaking: Renamed
getInitialApp*andgetLatestApp*methods togetInitialLink*andgetLatestLink*. - chore(QoL): The plugin should not send again initial link when restarting, reloading the app or subscribing again to the stream.
- fix(macOS): Handle link from cold state (i.e. terminated).
- fix(linux): Refactor code to not store all URIs.
- fix(linux): Stream is not filled anymore when there's no listener.
5.0.0
- Breaking iOs: Application Delegate now returns
truefor both Universal Links and Custom URL schemes. If you have other packages which could conflict with it, report to the README.md for custom handling. This change is motived by the basic deep linking provided by Flutter and the fact that there is now a workaround for such cases.
4.0.1
- fix(Android): Reworked capture by explicitly discarding
ACTION_SEND*and let other basic actions succeed (NFC for example).
4.0.0
- Breaking fix(Windows): Updated setup to be more resilient to Flutter changes. Can work with v3 but mandatory from Flutter 3.19 with new projects.
- Breaking chore(Android): Remove capture of ACTION_SEND to avoid conflicts with others packages.
- Breaking chore(web): move from dart:html to package:web to allow WASM compilation.
- chore: Updated setup for iOS to handle result while other packages are around.
3.5.1
- chore: Add privacy manifest to iOS and macOS platforms.
3.5.0
- feat: Add linux support.
- fix(macOS): Flutter 3.16 broke macOS behaviour.
- fix(iOS): Allow to call AppLinks plugin from outside for custom AppDelegate or SceneDelegate.
- chore: README update.
3.4.5
- fix(Android): Code improvements and correctly skip event firing when comming from history.
3.4.4
- fix: Add missing
allUriLinkStreamandallStringLinkStreammethods web platform.
3.4.3
- chore: Add support for Flutter 3.10.
- chore(Android): Add support for AGP 8.0.
- fix(iOS): Code improvements (Thanks to michalsrutek)
3.4.2
- chore: Merge platform interface in main project.
3.4.1
- fix(macOS): wrong plugin definition resulting in build errors.
3.4.0
- feat(Android): Allow ACTION_SEND with Intent.EXTRA_STREAM, Intent.EXTRA_TEXT. (thanks to espresso3389)
- feat: Add single stream for all links (See README for updated usage).
- chore: Unify platform packages in app_links main package (Windows #include directive must be updated!).
- chore: Remove duplicated code in windows implementation.
3.3.0
- feat: Triggering Firebase dynamic links for Android >= 12 (behaviour changes). (thanks to AdrienAudouard)
3.2.0
- feat: Add macOS support.
3.1.0
- feat: Add Windows support.
3.0.2
- fix: iOS
applicationcallbacks do not returntrueanymore.
3.0.1
- core: Improve Android code.
3.0.0
- core: Breaking API changed to use stream instead of callback.
- fix: Consistent behaviour between iOS & Android with (deffered) stream usage (for onAppLink vs. getInitialLink "duplicated" links).
- fix: remove example splashscreen deprecation.
2.2.2
- core: Add linter.
- fix: Get rid of Android LocalBroadcastReceiver deprecation (removed dependency & import...).
2.2.1
- fix: Duplicated iOS call when app is on terminated status.
- fix: iOS
applicationcallback does not returntrueanymore. - fix: Get rid of Android LocalBroadcastReceiver deprecation.
- core: Updated dependencies.
2.2.0
- Add web support. (getInitialAppLink() only).
2.1.0
- Breaking: String uri added on
onAppLinkfor custom handling like uppercased uri. - Feat:
getInitialAppLinkStringandgetLatestAppLinkStringadded to reflect the above change.
2.0.0+1
- Minimal sample added (Thanks to @JamesCullum).
2.0.0
- Add null safety support.
1.0.0
- Same as 0.2.0.
- No known issue. Bumping to 1.0 to be prepared for null safety version.
0.2.0
- Add configurations in example.
0.1.0+2
- Update README.md.
0.1.0+1
- Add documentation.
- Format dart source code.
0.1.0
- Initial release.
- Android App Links, Deep Links, iOS Universal Links and Custom URL schemes.
Installing
export PUB_HOSTED_URL=https://pub.mirror.p-hatan.ir
flutter pub add app_linkspubspec.yaml
name: app_links
description: Android App Links, Deep Links, iOs Universal Links and Custom URL schemes handler for Flutter (desktop included).
version: 6.0.1
homepage: https://github.com/llfbandit/app_links
environment:
sdk: ">=3.2.0 <4.0.0"
flutter: ">=3.16.0"
dependencies:
flutter:
sdk: flutter
# https://pub.dev/packages/plugin_platform_interface
plugin_platform_interface: ^2.0.0
web: ">=0.3.0 <0.6.0"
flutter_web_plugins:
sdk: flutter
gtk: ^2.1.0
dev_dependencies:
flutter_test:
sdk: flutter
# https://pub.dev/packages/lints
lints: ^3.0.0
flutter:
plugin:
platforms:
android:
package: com.llfbandit.app_links
pluginClass: AppLinksPlugin
ios:
pluginClass: AppLinksPlugin
web:
pluginClass: AppLinksPluginWeb
fileName: src/app_links_web.dart
windows:
pluginClass: AppLinksPluginCApi
macos:
pluginClass: AppLinksMacosPlugin
linux:
dartPluginClass: AppLinksPluginLinux
Version history
| Version | Published | Archive | SHA-256 |
|---|---|---|---|
| 0.1.0 | 2020-11-26T17:21:15.583592Z | Download | 07891d9d2c85d1ce15745bd5e018b90924e89c43ad0d3f29983dd828c88285a8 |
| 0.1.0+1 | 2020-11-26T17:40:51.307309Z | Download | 86542ee42e6152d35264f0d3f87a08a9088615489ade05e29b33d85f6750d501 |
| 0.1.0+2 | 2020-11-26T19:08:30.370087Z | Download | 2ec3d04c172ad43e31d6ff3737d70b672f168f5c4345fafc318ce382532af9d4 |
| 0.2.0 | 2020-12-02T15:01:01.249049Z | Download | becd089384b3581cd07acc14e375db251e0f8b344111217c527c5d5cce97c3d0 |
| 1.0.0 | 2021-02-13T12:45:17.509896Z | Download | 2c0b508b92dfab7ec0368efdead57684acc635dc3c2df9ac4f33dfe152c91682 |
| 2.0.0 | 2021-03-04T15:46:37.423728Z | Download | a3bc0cfb0ef13e669cb3f01b592552f7685e5cc5d9a21da0f8622817ca9a8176 |
| 2.0.0+1 | 2021-04-15T19:07:17.535095Z | Download | cf0bb21377a55d0be49e64202cf78122b8e081cb087382d54d83d5a2bf342014 |
| 2.1.0 | 2021-05-07T08:13:15.806372Z | Download | 8952ce086fd9c1e6a4fdeeedfeae85ab82ccb6fd24c6fcfd16b84095b0a65c01 |
| 2.2.0 | 2021-06-13T15:34:35.203035Z | Download | 02d5b116c72782522133a5cf6edac4520b41041af29511e1caf1e3b055dd18f7 |
| 2.2.1 | 2022-02-18T13:48:35.364711Z | Download | 4af01185a7a3ca1a36b4f576acd6e54dd5061087e3c3305999b36c148bc78234 |
| 2.2.2 | 2022-02-25T16:35:19.983875Z | Download | de064ea9dca1c590a414662caf65a48a32dbeb2d7a24365baa74f1ac84db2f1c |
| 3.0.0 | 2022-02-27T17:04:13.430661Z | Download | fcf08826775e58bf23073f59f5ad3ccd67f097d3e6135e00d0f7b7e2abf3bb35 |
| 3.0.1 | 2022-02-28T08:06:32.719242Z | Download | bbe434aa035165cf654490ecfb4d52b0b4407b4f0dd8d392df0d5d0a8bd35163 |
| 3.0.2 | 2022-04-25T16:47:14.883349Z | Download | 24feda5b64e5fdc3e02f52c4ede446bcd838b6a3c3dc120eae753dc348787688 |
| 3.1.0 | 2022-04-28T14:37:02.480899Z | Download | 7a28970b667c02d2ed950ea11a2ddb116f023c52e0ec85a4fb1256ce008db7f2 |
| 3.2.0 | 2022-04-29T10:07:51.675207Z | Download | cbf1dbb4d39f2b7c36f5751ee9ba2dac03f4bb2e7309f590a856a9302333ecfe |
| 3.3.0 | 2022-09-28T18:51:01.141895Z | Download | d1b2cf9ad5568cc5b9036cb3f8c42705b4ada26c4ef57de75323186eafe36a0d |
| 3.4.0 | 2022-12-12T12:54:46.207118Z | Download | a669e117df216208daa42266366af59bf2d69fb0780d081715f7e064a1da4df2 |
| 3.4.1 | 2022-12-14T14:54:50.554417Z | Download | 0ae672961f4fdc1424c6a5d11b7a4e3791bb07a9332f26c8314546365a0d1e8e |
| 3.4.2 | 2023-02-23T17:06:20.530984Z | Download | d572dcdff49c4cfcfa6f315e2683e518ec6eb54e084d01e51d9631a4dcc1b5e8 |
| 3.4.3 | 2023-05-22T09:12:41.325350Z | Download | 16725e716afd0634a5441654b1dda2b6c5557aa230884b5e1f41a5aa546a4cb6 |
| 3.4.4 | 2023-09-23T23:05:10.166833Z | Download | f41abc506363dee2515db66155dbb1c247328c683ba925acb7d625cf6780abd5 |
| 3.4.5 | 2023-09-23T23:43:06.723483Z | Download | eb83c2b15b78a66db04e95132678e910fcdb8dc3a9b0aed0c138f50b2bef0dae |
| 3.5.0-beta.1 | 2023-11-30T11:20:15.542483Z | Download | b577f5afe4121a778056fc02eeea7ac8eef0ef4dfac9e60d263e037a3f703122 |
| 3.5.0-beta.2 | 2023-11-30T12:27:13.388233Z | Download | 6604788ccddaa18502aa1adffe44c253a5f30ac51e5fce7f41d58da22f0ac535 |
| 3.5.0-beta.3 | 2023-12-11T13:47:41.323986Z | Download | 1e1e917ed211d867e69c125ead63f0cb2c8dc5cf54b8a58ad6bf27647ce5cef8 |
| 3.5.0 | 2023-12-14T13:48:40.083051Z | Download | 4e392b5eba997df356ca6021f28431ce1cfeb16758699553a94b13add874a3bb |
| 3.5.1 | 2024-03-05T13:21:45.202807Z | Download | 3ced568a5d9e309e99af71285666f1f3117bddd0bd5b3317979dccc1a40cada4 |
| 4.0.0 | 2024-03-13T20:50:11.390495Z | Download | fd7fc1569870b4b0d90d17a9f36661a6ff92400fecb6e4adab4abe0f0488bb5f |
| 4.0.1 | 2024-03-19T12:44:46.766102Z | Download | 42dc15aecf2618ace4ffb74a2e58a50e45cd1b9f2c17c8f0cafe4c297f08c815 |
| 5.0.0 | 2024-04-25T14:04:31.283609Z | Download | 0fd41f0501f131d931251e0942ac63d6216096a0052aeca037915c2c1deeb121 |
| 6.0.0 | 2024-05-04T20:25:55.234774Z | Download | f57cf3889e11f927fbc92ec1e74079614ff652179d0be06d34f2488873ca3a9f |
| 6.0.1 | 2024-05-05T12:48:35.165345Z | Download | 1c2b9e9c56d80d17610bcbd111b37187875c5d0ded8654caa1bda14ea753d001 |
| 6.0.2 | 2024-05-13T13:30:30.699014Z | Download | 8c6ef5ba9e26b720d4c9073826befb87df2ab5e7a81c22b6c3145080b5e736c9 |
| 6.1.0 | 2024-05-21T13:14:41.919625Z | Download | c7b2c4466992ed824da0d994a293670b704c13ec9f1f4f3c8c4b4fc2869a0cc1 |
| 6.1.1 | 2024-05-21T13:18:32.027245Z | Download | 96e677810b83707ff5e10fac11e4839daa0ea4e0123c35864c092699165eb3db |
| 6.1.2 | 2024-06-25T14:12:27.281771Z | Download | 49117eefee46a97cf5037bb5baacc882556b22e631e18087b0a18b29379e7a14 |
| 6.1.3 | 2024-06-25T20:25:54.292175Z | Download | a9905d6a60e814503fabc7523a9ed161b812d7ca69c99ad8ceea14279dc4f06b |
| 6.1.4 | 2024-07-03T16:03:46.851547Z | Download | ae5f9a1b7d40d26178f605414be81ed4260350b4fae8259fe5ca4f89fe70c4af |
| 6.2.0 | 2024-08-09T20:36:31.752963Z | Download | 4acba851087b25136e8f6e32a53bd4536eb3bec69947ddb66e7b9a5792ceb0c7 |
| 6.2.1 | 2024-08-21T20:32:27.436722Z | Download | f04c3ca96426baba784c736a201926bd4145524c36a1b38942a351b033305e21 |
| 6.3.0 | 2024-08-24T17:46:13.448682Z | Download | 50437e5916e6f56c1ca53e967cbfd6d53b3451465b41eef05ba1533bf1e1c5ea |
| 6.3.1 | 2024-08-31T13:08:09.678260Z | Download | 7e058edbc78bd40b6a8227941b955f38320a4e799bc0983c8146bda41593a491 |
| 6.3.2 | 2024-09-05T15:46:09.276658Z | Download | ad1a6d598e7e39b46a34f746f9a8b011ee147e4c275d407fa457e7a62f84dd99 |
| 6.3.3 | 2024-12-12T12:54:18.099238Z | Download | 433df2e61b10519407475d7f69e470789d23d593f28224c38ba1068597be7950 |
| 6.4.0 | 2025-02-18T18:27:06.347969Z | Download | 85ed8fc1d25a76475914fff28cc994653bd900bc2c26e4b57a49e097febb54ba |
| 6.4.1 | 2025-08-14T10:08:20.009276Z | Download | 5f88447519add627fe1cbcab4fd1da3d4fed15b9baf29f28b22535c95ecee3e8 |
| 7.0.0 | 2025-11-17T12:30:46.082817Z | Download | 3462d9defc61565fde4944858b59bec5be2b9d5b05f20aed190adb3ad08a7abc |
| 7.1.0 | 2026-05-26T16:54:01.747342Z | Download | a408901c5d33e2b5f33064e5db849ce20176e46c5cddb2bf518a5c4c9e7a4e4f |
| 7.1.1 | 2026-05-27T11:34:59.470595Z | Download | a350a5b37579b7227aaf9a59c07114617cd4283852e193f743b2b3d2d7483c18 |
| 7.1.2 | 2026-06-11T08:44:25.717971Z | Download | 4ec328cd9fd51fd0e7eb8870a9612c1fde0f091901932238c4f4e60b5f7f1315 |
| 7.2.0 | 2026-06-23T20:33:13.191601Z | Download | 9d3c82f634c7f5b5c752f7ee46b67724246043f5e1d5fc1b433dd5b38d780dbe |
| 7.2.1 | 2026-07-09T13:35:28.512394Z | Download | f8db46d2ea9ff6f3a37191a7fd5b7813da1253ace8c32c1b9eadace41d1188ea |
| 7.2.2 | 2026-10-06T13:54:36.730853Z | Download | 08ba88bf19d9edea33130cb71c8ced2cb982b4e00b82efef4a434d1357bc69c3 |
Dependencies
flutter {
"sdk": "flutter"
}
flutter_web_plugins {
"sdk": "flutter"
}
gtk "^2.1.0"
plugin_platform_interface "^2.0.0"
web "\u003e=0.3.0 \u003c0.6.0"