diff --git a/flutter/android/app/src/main/AndroidManifest.xml b/flutter/android/app/src/main/AndroidManifest.xml
index b3c655917..1b99801bf 100644
--- a/flutter/android/app/src/main/AndroidManifest.xml
+++ b/flutter/android/app/src/main/AndroidManifest.xml
@@ -61,6 +61,14 @@
+
+
+
+
+
+
+
+
-
\ No newline at end of file
+
diff --git a/flutter/ios/Runner/Info.plist b/flutter/ios/Runner/Info.plist
index 892561ae7..496fb17c2 100644
--- a/flutter/ios/Runner/Info.plist
+++ b/flutter/ios/Runner/Info.plist
@@ -24,6 +24,21 @@
????
CFBundleVersion
$(FLUTTER_BUILD_NUMBER)
+ CFBundleURLTypes
+
+
+ CFBundleTypeRole
+ Editor
+ CFBundleURLIconFile
+
+ CFBundleURLName
+ com.carriez.rustdesk
+ CFBundleURLSchemes
+
+ rustdesk
+
+
+
LSRequiresIPhoneOS
UIApplicationSupportsIndirectInputEvents
diff --git a/flutter/lib/common.dart b/flutter/lib/common.dart
index 9c8404c56..4d23614ca 100644
--- a/flutter/lib/common.dart
+++ b/flutter/lib/common.dart
@@ -1955,6 +1955,7 @@ bool handleUriLink({List? cmdArgs, Uri? uri, String? uriString}) {
List? urlLinkToCmdArgs(Uri uri) {
String? command;
String? id;
+ final options = ["connect", "play", "file-transfer", "port-forward", "rdp"];
if (uri.authority.isEmpty &&
uri.path.split('').every((char) => char == '/')) {
return [];
@@ -1962,18 +1963,33 @@ List? urlLinkToCmdArgs(Uri uri) {
// For compatibility
command = '--connect';
id = uri.path.substring("/new/".length);
- } else if (['connect', "play", 'file-transfer', 'port-forward', 'rdp']
- .contains(uri.authority)) {
+ } else if (options.contains(uri.authority)) {
+ final optionIndex = options.indexOf(uri.authority);
command = '--${uri.authority}';
if (uri.path.length > 1) {
id = uri.path.substring(1);
}
+ if (isMobile && id != null) {
+ if (optionIndex == 0 || optionIndex == 1) {
+ connect(Get.context!, id);
+ } else if (optionIndex == 2) {
+ connect(Get.context!, id, isFileTransfer: true);
+ }
+ return null;
+ }
} else if (uri.authority.length > 2 && uri.path.length <= 1) {
// rustdesk://
command = '--connect';
id = uri.authority;
}
+ if (isMobile){
+ if (id != null){
+ connect(Get.context!, id);
+ return null;
+ }
+ }
+
List args = List.empty(growable: true);
if (command != null && id != null) {
args.add(command);
diff --git a/flutter/lib/main.dart b/flutter/lib/main.dart
index d7dd5acee..b8a7a8e45 100644
--- a/flutter/lib/main.dart
+++ b/flutter/lib/main.dart
@@ -156,6 +156,7 @@ void runMobileApp() async {
await Future.wait([gFFI.abModel.loadCache(), gFFI.groupModel.loadCache()]);
gFFI.userModel.refreshCurrentUser();
runApp(App());
+ await initUniLinks();
}
void runMultiWindow(
diff --git a/flutter/lib/mobile/pages/connection_page.dart b/flutter/lib/mobile/pages/connection_page.dart
index a4e3c7f4d..824ceafec 100644
--- a/flutter/lib/mobile/pages/connection_page.dart
+++ b/flutter/lib/mobile/pages/connection_page.dart
@@ -54,10 +54,12 @@ class _ConnectionPageState extends State {
}
bool isPeersLoading = false;
bool isPeersLoaded = false;
+ StreamSubscription? _uniLinksSubscription;
@override
void initState() {
super.initState();
+ _uniLinksSubscription = listenUniLinks();
if (_idController.text.isEmpty) {
() async {
final lastRemoteId = await bind.mainGetLastRemoteId();
@@ -312,6 +314,7 @@ class _ConnectionPageState extends State {
@override
void dispose() {
+ _uniLinksSubscription?.cancel();
_idController.dispose();
if (Get.isRegistered()) {
Get.delete();