diff --git a/OAT.xml b/OAT.xml
new file mode 100644
index 0000000000000000000000000000000000000000..9a90959c6e5110fcb89023d2b99630ddddbacff4
--- /dev/null
+++ b/OAT.xml
@@ -0,0 +1,87 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app_links/ohos/.gitignore b/app_links/ohos/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..ac5aa9893e489c2ce51135893f258c60a475bb7a
--- /dev/null
+++ b/app_links/ohos/.gitignore
@@ -0,0 +1,29 @@
+# Miscellaneous
+*.class
+*.log
+*.pyc
+*.swp
+.DS_Store
+.atom/
+.buildlog/
+.history
+.svn/
+migrate_working_dir/
+
+# IntelliJ related
+*.iml
+*.ipr
+*.iws
+.idea/
+
+# The .vscode folder contains launch configuration and tasks you configure in
+# VS Code which you may wish to be included in version control, so this line
+# is commented out by default.
+#.vscode/
+
+# Flutter/Dart/Pub related
+# Libraries should not include pubspec.lock, per https://dart.dev/guides/libraries/private-files#pubspeclock.
+/pubspec.lock
+**/doc/api/
+.dart_tool/
+build/
diff --git a/app_links/ohos/.metadata b/app_links/ohos/.metadata
new file mode 100644
index 0000000000000000000000000000000000000000..ea72294e78ca44f30a1d80c776a5cde20cd11447
--- /dev/null
+++ b/app_links/ohos/.metadata
@@ -0,0 +1,30 @@
+# This file tracks properties of this Flutter project.
+# Used by Flutter tool to assess capabilities and perform upgrades etc.
+#
+# This file should be version controlled and should not be manually edited.
+
+version:
+ revision: "17f34a33bd784a87bd6a5ea479491b83631fd9e0"
+ channel: "oh-3.22.0"
+
+project_type: plugin
+
+# Tracks metadata for the flutter migrate command
+migration:
+ platforms:
+ - platform: root
+ create_revision: 17f34a33bd784a87bd6a5ea479491b83631fd9e0
+ base_revision: 17f34a33bd784a87bd6a5ea479491b83631fd9e0
+ - platform: ohos
+ create_revision: 17f34a33bd784a87bd6a5ea479491b83631fd9e0
+ base_revision: 17f34a33bd784a87bd6a5ea479491b83631fd9e0
+
+ # User provided section
+
+ # List of Local paths (relative to this file) that should be
+ # ignored by the migrate tool.
+ #
+ # Files that are not part of the templates will be ignored by default.
+ unmanaged_files:
+ - 'lib/main.dart'
+ - 'ios/Runner.xcodeproj/project.pbxproj'
diff --git a/app_links/ohos/CHANGELOG.md b/app_links/ohos/CHANGELOG.md
new file mode 100644
index 0000000000000000000000000000000000000000..abd84ca152910f0f8124ed1c63a1b2b4378c2dc4
--- /dev/null
+++ b/app_links/ohos/CHANGELOG.md
@@ -0,0 +1,3 @@
+## 1.0.0
+
+* Support OpenHarmony.
\ No newline at end of file
diff --git a/app_links/ohos/LICENSE b/app_links/ohos/LICENSE
new file mode 100644
index 0000000000000000000000000000000000000000..261eeb9e9f8b2b4b0d119366dda99c6fd7d35c64
--- /dev/null
+++ b/app_links/ohos/LICENSE
@@ -0,0 +1,201 @@
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
diff --git a/app_links/ohos/README.md b/app_links/ohos/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..bd0e508bafa99581993d290111b98d88241ed59a
--- /dev/null
+++ b/app_links/ohos/README.md
@@ -0,0 +1,46 @@
+# HarmonyOS
+
+HarmonyOS documentation:
+- App Links: [Documentation](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/app-linking-startup-V5)
+- Deep Links: [Documentation](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/deep-linking-startup-V5)
+
+## Usage
+
+```yaml
+dependencies:
+ app_links: 6.3.2
+ app_links_ohos: 1.0.0
+```
+
+## SETUP
+
+Add your setup:
+```sh
+
+ {
+ "module": {
+ // ...
+ "abilities": [
+ {
+ // ...
+ "skills": [
+ {
+ "uris": [
+ {
+ "scheme": "sample",
+ "host": "open.my.app",
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+ }
+```
+
+# Testing
+
+```sh
+"sample://open.my.app/#/book/hello-world"
+```
\ No newline at end of file
diff --git a/app_links/ohos/analysis_options.yaml b/app_links/ohos/analysis_options.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..a5744c1cfbe77ae2daba29c74156c617b5f09b77
--- /dev/null
+++ b/app_links/ohos/analysis_options.yaml
@@ -0,0 +1,4 @@
+include: package:flutter_lints/flutter.yaml
+
+# Additional information about this file can be found at
+# https://dart.dev/guides/language/analysis-options
diff --git a/app_links/ohos/example/.gitignore b/app_links/ohos/example/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..29a3a5017f048d6d8e6a450eef64435ddee44fb7
--- /dev/null
+++ b/app_links/ohos/example/.gitignore
@@ -0,0 +1,43 @@
+# Miscellaneous
+*.class
+*.log
+*.pyc
+*.swp
+.DS_Store
+.atom/
+.buildlog/
+.history
+.svn/
+migrate_working_dir/
+
+# IntelliJ related
+*.iml
+*.ipr
+*.iws
+.idea/
+
+# The .vscode folder contains launch configuration and tasks you configure in
+# VS Code which you may wish to be included in version control, so this line
+# is commented out by default.
+#.vscode/
+
+# Flutter/Dart/Pub related
+**/doc/api/
+**/ios/Flutter/.last_build_id
+.dart_tool/
+.flutter-plugins
+.flutter-plugins-dependencies
+.pub-cache/
+.pub/
+/build/
+
+# Symbolication related
+app.*.symbols
+
+# Obfuscation related
+app.*.map.json
+
+# Android Studio will place build artifacts here
+/android/app/debug
+/android/app/profile
+/android/app/release
diff --git a/app_links/ohos/example/README.md b/app_links/ohos/example/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..8e291c6a0596551011ee1e7b7bb7b8992c10d57c
--- /dev/null
+++ b/app_links/ohos/example/README.md
@@ -0,0 +1,16 @@
+# app_links_ohos_example
+
+Demonstrates how to use the app_links_ohos plugin.
+
+## Getting Started
+
+This project is a starting point for a Flutter application.
+
+A few resources to get you started if this is your first Flutter project:
+
+- [Lab: Write your first Flutter app](https://docs.flutter.dev/get-started/codelab)
+- [Cookbook: Useful Flutter samples](https://docs.flutter.dev/cookbook)
+
+For help getting started with Flutter development, view the
+[online documentation](https://docs.flutter.dev/), which offers tutorials,
+samples, guidance on mobile development, and a full API reference.
diff --git a/app_links/ohos/example/analysis_options.yaml b/app_links/ohos/example/analysis_options.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..0d2902135caece481a035652d88970c80e29cc7e
--- /dev/null
+++ b/app_links/ohos/example/analysis_options.yaml
@@ -0,0 +1,28 @@
+# This file configures the analyzer, which statically analyzes Dart code to
+# check for errors, warnings, and lints.
+#
+# The issues identified by the analyzer are surfaced in the UI of Dart-enabled
+# IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be
+# invoked from the command line by running `flutter analyze`.
+
+# The following line activates a set of recommended lints for Flutter apps,
+# packages, and plugins designed to encourage good coding practices.
+include: package:flutter_lints/flutter.yaml
+
+linter:
+ # The lint rules applied to this project can be customized in the
+ # section below to disable rules from the `package:flutter_lints/flutter.yaml`
+ # included above or to enable additional rules. A list of all available lints
+ # and their documentation is published at https://dart.dev/lints.
+ #
+ # Instead of disabling a lint rule for the entire project in the
+ # section below, it can also be suppressed for a single line of code
+ # or a specific dart file by using the `// ignore: name_of_lint` and
+ # `// ignore_for_file: name_of_lint` syntax on the line or in the file
+ # producing the lint.
+ rules:
+ # avoid_print: false # Uncomment to disable the `avoid_print` rule
+ # prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule
+
+# Additional information about this file can be found at
+# https://dart.dev/guides/language/analysis-options
diff --git a/app_links/ohos/example/integration_test/plugin_integration_test.dart b/app_links/ohos/example/integration_test/plugin_integration_test.dart
new file mode 100644
index 0000000000000000000000000000000000000000..a8c192303cae3824f47a06f8446b0a7216dd31f4
--- /dev/null
+++ b/app_links/ohos/example/integration_test/plugin_integration_test.dart
@@ -0,0 +1,25 @@
+// This is a basic Flutter integration test.
+//
+// Since integration tests run in a full Flutter application, they can interact
+// with the host side of a plugin implementation, unlike Dart unit tests.
+//
+// For more information about Flutter integration tests, please see
+// https://docs.flutter.dev/cookbook/testing/integration/introduction
+
+
+import 'package:flutter_test/flutter_test.dart';
+import 'package:integration_test/integration_test.dart';
+
+import 'package:app_links_ohos/app_links_ohos.dart';
+
+void main() {
+ IntegrationTestWidgetsFlutterBinding.ensureInitialized();
+
+ testWidgets('getPlatformVersion test', (WidgetTester tester) async {
+ final AppLinksOhos plugin = AppLinksOhos();
+ final String? version = await plugin.getPlatformVersion();
+ // The version string depends on the host platform running the test, so
+ // just assert that some non-empty string is returned.
+ expect(version?.isNotEmpty, true);
+ });
+}
diff --git a/app_links/ohos/example/lib/main.dart b/app_links/ohos/example/lib/main.dart
new file mode 100644
index 0000000000000000000000000000000000000000..4212aaab419a8c4b67ca1902356d44a648857ea7
--- /dev/null
+++ b/app_links/ohos/example/lib/main.dart
@@ -0,0 +1,158 @@
+import 'dart:async';
+import 'dart:math';
+
+import 'package:app_links/app_links.dart';
+import 'package:flutter/foundation.dart';
+import 'package:flutter/material.dart';
+import 'url_protocol/api.dart';
+import 'package:app_links_platform_interface/app_links_platform_interface.dart';
+
+///////////////////////////////////////////////////////////////////////////////
+/// Please make sure to follow the setup instructions below
+///
+/// Please take a look at:
+/// - example/android/app/main/AndroidManifest.xml for Android.
+///
+/// - example/ios/Runner/Runner.entitlements for Universal Link sample.
+/// - example/ios/Runner/Info.plist for Custom URL scheme sample.
+///
+/// You can launch an intent on an Android Emulator like this:
+/// adb shell am start -a android.intent.action.VIEW \
+/// -d "sample://open.my.app/#/book/hello-world"
+///
+///
+/// On windows & macOS:
+/// The simplest way to test it is by
+/// opening your browser and type: sample://foo/#/book/hello-world2
+///
+/// On windows:
+/// Outside of a browser, in a email for example, you can use:
+/// https://example.com/#/book/hello-world2
+///////////////////////////////////////////////////////////////////////////////
+
+const kWindowsScheme = 'sample';
+
+void main() {
+ // Register our protocol only on Windows platform
+ // registerProtocolHandler(kWindowsScheme);
+
+ runApp(const MyApp());
+}
+
+class MyApp extends StatefulWidget {
+ const MyApp({Key? key}) : super(key: key);
+
+ @override
+ State createState() => _MyAppState();
+}
+
+class _MyAppState extends State {
+ final _navigatorKey = GlobalKey();
+ late AppLinks _appLinks;
+ StreamSubscription? _linkSubscription;
+
+ @override
+ void initState() {
+ super.initState();
+
+ initDeepLinks();
+ }
+
+ @override
+ void dispose() {
+ _linkSubscription?.cancel();
+
+ super.dispose();
+ }
+
+ Future initDeepLinks() async {
+ _appLinks = AppLinks();
+
+ // Handle links
+ _linkSubscription = _appLinks.uriLinkStream.listen((uri) {
+ debugPrint('onAppLink: $uri');
+ openAppLink(uri);
+ });
+ }
+
+ void openAppLink(Uri uri) {
+ print("测试打印日志");
+ print(AppLinksPlatform.instance.getInitialLinkString());
+ print(AppLinksPlatform.instance.getLatestLinkString());
+ _navigatorKey.currentState?.pushNamed(uri.fragment);
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ return MaterialApp(
+ navigatorKey: _navigatorKey,
+ initialRoute: "/",
+ onGenerateRoute: (RouteSettings settings) {
+ Widget routeWidget = defaultScreen();
+
+ // Mimic web routing
+ final routeName = settings.name;
+ if (routeName != null) {
+ if (routeName.startsWith('/book/')) {
+ // Navigated to /book/:id
+ routeWidget = customScreen(
+ routeName.substring(routeName.indexOf('/book/')),
+ );
+ } else if (routeName == '/book') {
+ // Navigated to /book without other parameters
+ routeWidget = customScreen("None");
+ }
+ }
+
+ return MaterialPageRoute(
+ builder: (context) => routeWidget,
+ settings: settings,
+ fullscreenDialog: true,
+ );
+ },
+ );
+ }
+
+ Widget defaultScreen() {
+ return Scaffold(
+ appBar: AppBar(title: const Text('Default Screen')),
+ body: Center(
+ child: Column(
+ mainAxisSize: MainAxisSize.min,
+ children: [
+ const SelectableText('''
+ Launch an intent to get to the second screen.
+
+ On web:
+ http://localhost:/#/book/1 for example.
+
+ On windows & macOS, open your browser:
+ sample://foo/#/book/hello-deep-linking
+
+ This example code triggers new page from URL fragment.
+ '''),
+ const SizedBox(height: 20),
+ buildWindowsUnregisterBtn(),
+ ],
+ ),
+ ),
+ );
+ }
+
+ Widget customScreen(String bookId) {
+ return Scaffold(
+ appBar: AppBar(title: const Text('Second Screen')),
+ body: Center(child: Text('Opened with parameter: $bookId')),
+ );
+ }
+
+ Widget buildWindowsUnregisterBtn() {
+ if (defaultTargetPlatform == TargetPlatform.windows) {
+ return TextButton(
+ onPressed: () => unregisterProtocolHandler(kWindowsScheme),
+ child: const Text('Remove Windows protocol registration'));
+ }
+
+ return const SizedBox.shrink();
+ }
+}
diff --git a/app_links/ohos/example/lib/url_protocol/api.dart b/app_links/ohos/example/lib/url_protocol/api.dart
new file mode 100644
index 0000000000000000000000000000000000000000..fde211fa44f020fb91b5c0a715e3cdd788bb78c4
--- /dev/null
+++ b/app_links/ohos/example/lib/url_protocol/api.dart
@@ -0,0 +1,43 @@
+import 'protocol.dart';
+import 'windows_protocol.dart'
+ if (dart.library.js_interop) 'web_url_protocol.dart';
+
+/// Registers a protocol by [scheme] to allow for links in the form `://...`
+/// to be processed by this application. By default, opening a link will open
+/// the executable that was used to register the scheme with the URL as the first
+/// argument passed to the executable.
+///
+/// If a protocol is already registered for the given scheme, this function will
+/// attempt to overwrite the previous handler with the current executable information.
+/// However, note that depending on process permissions, this operation may be
+/// disallowed by the underlying platform.
+///
+/// You may pass an [executable] to override the path to the executable to run
+/// when accessing the URL.
+///
+/// [arguments] is a list of arguments to be used when running the executable.
+/// If passed, the list must contain at least one element, and at least one of
+/// those elements must contain the literal value `%s` to denote the URL to open.
+/// Quoting arguments is not necessary, as this will be handled for you.
+/// Escaping the `%s` as an unprocessed literal is currently unsupported.
+void registerProtocolHandler(
+ String scheme, {
+ String? executable,
+ List? arguments,
+}) {
+ WindowsProtocolHandler().register(
+ scheme,
+ executable: executable,
+ arguments: arguments,
+ );
+}
+
+/// Unregisters the protocol handler with the underlying platform. The provided
+/// [scheme] will no longer be used in links.
+///
+/// Note that this will unregister a protocol by scheme regardless of which process
+/// had registered it. Unregistering a scheme that was not registered by this
+/// application is undefined and depends on platform-specific restrictions.
+void unregisterProtocolHandler(String scheme) {
+ WindowsProtocolHandler().unregister(scheme);
+}
diff --git a/app_links/ohos/example/lib/url_protocol/protocol.dart b/app_links/ohos/example/lib/url_protocol/protocol.dart
new file mode 100644
index 0000000000000000000000000000000000000000..882e5560de0fef800efdd921d9e10e7d105ae94d
--- /dev/null
+++ b/app_links/ohos/example/lib/url_protocol/protocol.dart
@@ -0,0 +1,15 @@
+abstract class ProtocolHandler {
+ void register(String scheme, {String? executable, List? arguments});
+
+ void unregister(String scheme);
+
+ List getArguments(List? arguments) {
+ if (arguments == null) return ['%s'];
+
+ if (arguments.isEmpty && !arguments.any((e) => e.contains('%s'))) {
+ throw ArgumentError('arguments must contain at least 1 instance of "%s"');
+ }
+
+ return arguments;
+ }
+}
diff --git a/app_links/ohos/example/lib/url_protocol/web_url_protocol.dart b/app_links/ohos/example/lib/url_protocol/web_url_protocol.dart
new file mode 100644
index 0000000000000000000000000000000000000000..cc17847fba1c0d9ee7f4d8e488cf4903a389c494
--- /dev/null
+++ b/app_links/ohos/example/lib/url_protocol/web_url_protocol.dart
@@ -0,0 +1,9 @@
+import './protocol.dart';
+
+class WindowsProtocolHandler extends ProtocolHandler {
+ @override
+ void register(String scheme, {String? executable, List? arguments}) {}
+
+ @override
+ void unregister(String scheme) {}
+}
diff --git a/app_links/ohos/example/lib/url_protocol/windows_protocol.dart b/app_links/ohos/example/lib/url_protocol/windows_protocol.dart
new file mode 100644
index 0000000000000000000000000000000000000000..5fe605f093cc54b8fe166f594fefbf4d16484735
--- /dev/null
+++ b/app_links/ohos/example/lib/url_protocol/windows_protocol.dart
@@ -0,0 +1,65 @@
+import 'dart:io';
+
+import 'package:ffi/ffi.dart';
+import 'package:flutter/foundation.dart';
+import 'package:win32/win32.dart';
+
+import './protocol.dart';
+
+const _hive = HKEY_CURRENT_USER;
+
+class WindowsProtocolHandler extends ProtocolHandler {
+ @override
+ void register(String scheme, {String? executable, List? arguments}) {
+ if (defaultTargetPlatform != TargetPlatform.windows) return;
+
+ final prefix = _regPrefix(scheme);
+ final capitalized = scheme[0].toUpperCase() + scheme.substring(1);
+ final args = getArguments(arguments).map((a) => _sanitize(a));
+ final cmd =
+ '${executable ?? Platform.resolvedExecutable} ${args.join(' ')}';
+
+ _regCreateStringKey(_hive, prefix, '', 'URL:$capitalized');
+ _regCreateStringKey(_hive, prefix, 'URL Protocol', '');
+ _regCreateStringKey(_hive, '$prefix\\shell\\open\\command', '', cmd);
+ }
+
+ @override
+ void unregister(String scheme) {
+ if (defaultTargetPlatform != TargetPlatform.windows) return;
+
+ final txtKey = TEXT(_regPrefix(scheme));
+ try {
+ RegDeleteTree(HKEY_CURRENT_USER, txtKey);
+ } finally {
+ free(txtKey);
+ }
+ }
+
+ String _regPrefix(String scheme) => 'SOFTWARE\\Classes\\$scheme';
+
+ int _regCreateStringKey(int hKey, String key, String valueName, String data) {
+ final txtKey = TEXT(key);
+ final txtValue = TEXT(valueName);
+ final txtData = TEXT(data);
+ try {
+ return RegSetKeyValue(
+ hKey,
+ txtKey,
+ txtValue,
+ REG_SZ,
+ txtData,
+ txtData.length * 2 + 2,
+ );
+ } finally {
+ free(txtKey);
+ free(txtValue);
+ free(txtData);
+ }
+ }
+
+ String _sanitize(String value) {
+ value = value.replaceAll(r'%s', '%1').replaceAll(r'"', '\\"');
+ return '"$value"';
+ }
+}
diff --git a/app_links/ohos/example/ohos/.gitignore b/app_links/ohos/example/ohos/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..6ca13b3170eec5dd5ac5ad7f1c4dd0118845f473
--- /dev/null
+++ b/app_links/ohos/example/ohos/.gitignore
@@ -0,0 +1,19 @@
+/node_modules
+/oh_modules
+/local.properties
+/.idea
+**/build
+/.hvigor
+.cxx
+/.clangd
+/.clang-format
+/.clang-tidy
+**/.test
+*.har
+**/BuildProfile.ets
+**/oh-package-lock.json5
+
+**/src/main/resources/rawfile/flutter_assets/
+**/libs/arm64-v8a/libapp.so
+**/libs/arm64-v8a/libflutter.so
+**/libs/arm64-v8a/libvmservice_snapshot.so
diff --git a/app_links/ohos/example/ohos/AppScope/app.json5 b/app_links/ohos/example/ohos/AppScope/app.json5
new file mode 100644
index 0000000000000000000000000000000000000000..44498cf93d84542c0661745f965482bcd8b0bf4a
--- /dev/null
+++ b/app_links/ohos/example/ohos/AppScope/app.json5
@@ -0,0 +1,10 @@
+{
+ "app": {
+ "bundleName": "com.llfbandit.app_links.app_links_ohos_example",
+ "vendor": "example",
+ "versionCode": 1000000,
+ "versionName": "1.0.0",
+ "icon": "$media:app_icon",
+ "label": "$string:app_name"
+ }
+}
diff --git a/app_links/ohos/example/ohos/AppScope/resources/base/element/string.json b/app_links/ohos/example/ohos/AppScope/resources/base/element/string.json
new file mode 100644
index 0000000000000000000000000000000000000000..62beaa2c9e615a1d2b5c5a41bbbb7496e45bfe63
--- /dev/null
+++ b/app_links/ohos/example/ohos/AppScope/resources/base/element/string.json
@@ -0,0 +1,8 @@
+{
+ "string": [
+ {
+ "name": "app_name",
+ "value": "app_links_ohos_example"
+ }
+ ]
+}
diff --git a/app_links/ohos/example/ohos/AppScope/resources/base/media/app_icon.png b/app_links/ohos/example/ohos/AppScope/resources/base/media/app_icon.png
new file mode 100644
index 0000000000000000000000000000000000000000..ce307a8827bd75456441ceb57d530e4c8d45d36c
Binary files /dev/null and b/app_links/ohos/example/ohos/AppScope/resources/base/media/app_icon.png differ
diff --git a/app_links/ohos/example/ohos/build-profile.json5 b/app_links/ohos/example/ohos/build-profile.json5
new file mode 100644
index 0000000000000000000000000000000000000000..26bea001ac6999860a2890121e380c122e6b601b
--- /dev/null
+++ b/app_links/ohos/example/ohos/build-profile.json5
@@ -0,0 +1,28 @@
+{
+ "app": {
+ "signingConfigs": [
+ ],
+ "products": [
+ {
+ "name": "default",
+ "signingConfig": "default",
+ "compatibleSdkVersion": "5.0.0(12)",
+ "runtimeOS": "HarmonyOS"
+ }
+ ]
+ },
+ "modules": [
+ {
+ "name": "entry",
+ "srcPath": "./entry",
+ "targets": [
+ {
+ "name": "default",
+ "applyToProducts": [
+ "default"
+ ]
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/app_links/ohos/example/ohos/entry/.gitignore b/app_links/ohos/example/ohos/entry/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..2795a1c5b1fe53659dd1b71d90ba0592eaf7e043
--- /dev/null
+++ b/app_links/ohos/example/ohos/entry/.gitignore
@@ -0,0 +1,7 @@
+
+/node_modules
+/oh_modules
+/.preview
+/build
+/.cxx
+/.test
\ No newline at end of file
diff --git a/app_links/ohos/example/ohos/entry/build-profile.json5 b/app_links/ohos/example/ohos/entry/build-profile.json5
new file mode 100644
index 0000000000000000000000000000000000000000..633d360fbc91a3186a23b66ab71b27e5618944cb
--- /dev/null
+++ b/app_links/ohos/example/ohos/entry/build-profile.json5
@@ -0,0 +1,29 @@
+/*
+* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd.
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+{
+ "apiType": 'stageMode',
+ "buildOption": {
+ },
+ "targets": [
+ {
+ "name": "default",
+ "runtimeOS": "HarmonyOS"
+ },
+ {
+ "name": "ohosTest",
+ }
+ ]
+}
\ No newline at end of file
diff --git a/app_links/ohos/example/ohos/entry/hvigorfile.ts b/app_links/ohos/example/ohos/entry/hvigorfile.ts
new file mode 100644
index 0000000000000000000000000000000000000000..894fc15c6b793f085e6c8506e43d719af658e8ff
--- /dev/null
+++ b/app_links/ohos/example/ohos/entry/hvigorfile.ts
@@ -0,0 +1,17 @@
+/*
+* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd.
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+// Script for compiling build behavior. It is built in the build plug-in and cannot be modified currently.
+export { hapTasks } from '@ohos/hvigor-ohos-plugin';
diff --git a/app_links/ohos/example/ohos/entry/oh-package.json5 b/app_links/ohos/example/ohos/entry/oh-package.json5
new file mode 100644
index 0000000000000000000000000000000000000000..e951e1f2653e93f1502c5b160ca2eb58b84192b5
--- /dev/null
+++ b/app_links/ohos/example/ohos/entry/oh-package.json5
@@ -0,0 +1,12 @@
+{
+ "name": "entry",
+ "version": "1.0.0",
+ "description": "Please describe the basic information.",
+ "main": "",
+ "author": "",
+ "license": "",
+ "dependencies": {
+ "integration_test": "file:..\\har\\integration_test.har",
+ "app_links_ohos": "file:..\\har\\app_links_ohos.har"
+ }
+}
\ No newline at end of file
diff --git a/app_links/ohos/example/ohos/entry/src/main/ets/entryability/EntryAbility.ets b/app_links/ohos/example/ohos/entry/src/main/ets/entryability/EntryAbility.ets
new file mode 100644
index 0000000000000000000000000000000000000000..8bc48be8773196f34cccb15cf517f87f5c6b94d2
--- /dev/null
+++ b/app_links/ohos/example/ohos/entry/src/main/ets/entryability/EntryAbility.ets
@@ -0,0 +1,24 @@
+/*
+* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd.
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+import { FlutterAbility, FlutterEngine } from '@ohos/flutter_ohos';
+import { GeneratedPluginRegistrant } from '../plugins/GeneratedPluginRegistrant';
+
+export default class EntryAbility extends FlutterAbility {
+ configureFlutterEngine(flutterEngine: FlutterEngine) {
+ super.configureFlutterEngine(flutterEngine)
+ GeneratedPluginRegistrant.registerWith(flutterEngine)
+ }
+}
diff --git a/app_links/ohos/example/ohos/entry/src/main/ets/pages/Index.ets b/app_links/ohos/example/ohos/entry/src/main/ets/pages/Index.ets
new file mode 100644
index 0000000000000000000000000000000000000000..1125f9fdd95f4310a182c1c9e3680f37f73686c9
--- /dev/null
+++ b/app_links/ohos/example/ohos/entry/src/main/ets/pages/Index.ets
@@ -0,0 +1,38 @@
+/*
+* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd.
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+import common from '@ohos.app.ability.common';
+import { FlutterPage } from '@ohos/flutter_ohos'
+
+let storage = LocalStorage.getShared()
+const EVENT_BACK_PRESS = 'EVENT_BACK_PRESS'
+
+@Entry(storage)
+@Component
+struct Index {
+ private context = getContext(this) as common.UIAbilityContext
+ @LocalStorageLink('viewId') viewId: string = "";
+
+ build() {
+ Column() {
+ FlutterPage({ viewId: this.viewId })
+ }
+ }
+
+ onBackPress(): boolean {
+ this.context.eventHub.emit(EVENT_BACK_PRESS)
+ return true
+ }
+}
\ No newline at end of file
diff --git a/app_links/ohos/example/ohos/entry/src/main/ets/plugins/GeneratedPluginRegistrant.ets b/app_links/ohos/example/ohos/entry/src/main/ets/plugins/GeneratedPluginRegistrant.ets
new file mode 100644
index 0000000000000000000000000000000000000000..8361eef5ca93a83688886465f5dd025b8cffe103
--- /dev/null
+++ b/app_links/ohos/example/ohos/entry/src/main/ets/plugins/GeneratedPluginRegistrant.ets
@@ -0,0 +1,43 @@
+/*
+* Copyright (c) 2024 Hunan OpenValley Digital Industry Development Co., Ltd.
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+import { FlutterEngine, Log } from '@ohos/flutter_ohos';
+import AppLinksOhosPlugin from 'app_links_ohos';
+import IntegrationTestPlugin from 'integration_test';
+
+/**
+ * Generated file. Do not edit.
+ * This file is generated by the Flutter tool based on the
+ * plugins that support the Ohos platform.
+ */
+
+const TAG = "GeneratedPluginRegistrant";
+
+export class GeneratedPluginRegistrant {
+
+ static registerWith(flutterEngine: FlutterEngine) {
+ try {
+ flutterEngine.getPlugins()?.add(new AppLinksOhosPlugin());
+ flutterEngine.getPlugins()?.add(new IntegrationTestPlugin());
+ } catch (e) {
+ Log.e(
+ TAG,
+ "Tried to register plugins with FlutterEngine ("
+ + flutterEngine
+ + ") failed.");
+ Log.e(TAG, "Received exception while registering", e);
+ }
+ }
+}
diff --git a/app_links/ohos/example/ohos/entry/src/main/module.json5 b/app_links/ohos/example/ohos/entry/src/main/module.json5
new file mode 100644
index 0000000000000000000000000000000000000000..867f1c443694218b48c1e61be7c1aa3001e4d958
--- /dev/null
+++ b/app_links/ohos/example/ohos/entry/src/main/module.json5
@@ -0,0 +1,59 @@
+/*
+* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd.
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+{
+ "module": {
+ "name": "entry",
+ "type": "entry",
+ "description": "$string:module_desc",
+ "mainElement": "EntryAbility",
+ "deviceTypes": [
+ "phone"
+ ],
+ "deliveryWithInstall": true,
+ "installationFree": false,
+ "pages": "$profile:main_pages",
+ "abilities": [
+ {
+ "name": "EntryAbility",
+ "srcEntry": "./ets/entryability/EntryAbility.ets",
+ "description": "$string:EntryAbility_desc",
+ "icon": "$media:icon",
+ "label": "$string:EntryAbility_label",
+ "startWindowIcon": "$media:icon",
+ "startWindowBackground": "$color:start_window_background",
+ "exported": true,
+ "skills": [
+ {
+ "entities": [
+ "entity.system.home"
+ ],
+ "actions": [
+ "action.system.home"
+ ],
+ "uris": [
+ {
+ "scheme": 'sample',
+ "host": "open.my.app",
+ }
+ ]
+ }
+ ]
+ }
+ ],
+ "requestPermissions": [
+ {"name" : "ohos.permission.INTERNET"},
+ ]
+ }
+}
\ No newline at end of file
diff --git a/app_links/ohos/example/ohos/entry/src/main/resources/base/element/color.json b/app_links/ohos/example/ohos/entry/src/main/resources/base/element/color.json
new file mode 100644
index 0000000000000000000000000000000000000000..3c712962da3c2751c2b9ddb53559afcbd2b54a02
--- /dev/null
+++ b/app_links/ohos/example/ohos/entry/src/main/resources/base/element/color.json
@@ -0,0 +1,8 @@
+{
+ "color": [
+ {
+ "name": "start_window_background",
+ "value": "#FFFFFF"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/app_links/ohos/example/ohos/entry/src/main/resources/base/element/string.json b/app_links/ohos/example/ohos/entry/src/main/resources/base/element/string.json
new file mode 100644
index 0000000000000000000000000000000000000000..d9e50ac2b73f1a0445d51d530b8963be95042df1
--- /dev/null
+++ b/app_links/ohos/example/ohos/entry/src/main/resources/base/element/string.json
@@ -0,0 +1,16 @@
+{
+ "string": [
+ {
+ "name": "module_desc",
+ "value": "module description"
+ },
+ {
+ "name": "EntryAbility_desc",
+ "value": "description"
+ },
+ {
+ "name": "EntryAbility_label",
+ "value": "app_links_ohos_example"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/app_links/ohos/example/ohos/entry/src/main/resources/base/media/icon.png b/app_links/ohos/example/ohos/entry/src/main/resources/base/media/icon.png
new file mode 100644
index 0000000000000000000000000000000000000000..ce307a8827bd75456441ceb57d530e4c8d45d36c
Binary files /dev/null and b/app_links/ohos/example/ohos/entry/src/main/resources/base/media/icon.png differ
diff --git a/app_links/ohos/example/ohos/entry/src/main/resources/base/profile/main_pages.json b/app_links/ohos/example/ohos/entry/src/main/resources/base/profile/main_pages.json
new file mode 100644
index 0000000000000000000000000000000000000000..1898d94f58d6128ab712be2c68acc7c98e9ab9ce
--- /dev/null
+++ b/app_links/ohos/example/ohos/entry/src/main/resources/base/profile/main_pages.json
@@ -0,0 +1,5 @@
+{
+ "src": [
+ "pages/Index"
+ ]
+}
diff --git a/app_links/ohos/example/ohos/entry/src/main/resources/en_US/element/string.json b/app_links/ohos/example/ohos/entry/src/main/resources/en_US/element/string.json
new file mode 100644
index 0000000000000000000000000000000000000000..d9e50ac2b73f1a0445d51d530b8963be95042df1
--- /dev/null
+++ b/app_links/ohos/example/ohos/entry/src/main/resources/en_US/element/string.json
@@ -0,0 +1,16 @@
+{
+ "string": [
+ {
+ "name": "module_desc",
+ "value": "module description"
+ },
+ {
+ "name": "EntryAbility_desc",
+ "value": "description"
+ },
+ {
+ "name": "EntryAbility_label",
+ "value": "app_links_ohos_example"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/app_links/ohos/example/ohos/entry/src/main/resources/zh_CN/element/string.json b/app_links/ohos/example/ohos/entry/src/main/resources/zh_CN/element/string.json
new file mode 100644
index 0000000000000000000000000000000000000000..2679adea6dd819ae687a8992e2f74528027f6e6c
--- /dev/null
+++ b/app_links/ohos/example/ohos/entry/src/main/resources/zh_CN/element/string.json
@@ -0,0 +1,16 @@
+{
+ "string": [
+ {
+ "name": "module_desc",
+ "value": "模块描述"
+ },
+ {
+ "name": "EntryAbility_desc",
+ "value": "description"
+ },
+ {
+ "name": "EntryAbility_label",
+ "value": "app_links_ohos_example"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/app_links/ohos/example/ohos/entry/src/ohosTest/ets/test/Ability.test.ets b/app_links/ohos/example/ohos/entry/src/ohosTest/ets/test/Ability.test.ets
new file mode 100644
index 0000000000000000000000000000000000000000..25d4c71ff3cd584f5d64f6f8c0ac864928c234c4
--- /dev/null
+++ b/app_links/ohos/example/ohos/entry/src/ohosTest/ets/test/Ability.test.ets
@@ -0,0 +1,50 @@
+/*
+* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd.
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+import hilog from '@ohos.hilog';
+import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium'
+
+export default function abilityTest() {
+ describe('ActsAbilityTest', function () {
+ // Defines a test suite. Two parameters are supported: test suite name and test suite function.
+ beforeAll(function () {
+ // Presets an action, which is performed only once before all test cases of the test suite start.
+ // This API supports only one parameter: preset action function.
+ })
+ beforeEach(function () {
+ // Presets an action, which is performed before each unit test case starts.
+ // The number of execution times is the same as the number of test cases defined by **it**.
+ // This API supports only one parameter: preset action function.
+ })
+ afterEach(function () {
+ // Presets a clear action, which is performed after each unit test case ends.
+ // The number of execution times is the same as the number of test cases defined by **it**.
+ // This API supports only one parameter: clear action function.
+ })
+ afterAll(function () {
+ // Presets a clear action, which is performed after all test cases of the test suite end.
+ // This API supports only one parameter: clear action function.
+ })
+ it('assertContain',0, function () {
+ // Defines a test case. This API supports three parameters: test case name, filter parameter, and test case function.
+ hilog.info(0x0000, 'testTag', '%{public}s', 'it begin');
+ let a = 'abc'
+ let b = 'b'
+ // Defines a variety of assertion methods, which are used to declare expected boolean conditions.
+ expect(a).assertContain(b)
+ expect(a).assertEqual(a)
+ })
+ })
+}
\ No newline at end of file
diff --git a/app_links/ohos/example/ohos/entry/src/ohosTest/ets/test/List.test.ets b/app_links/ohos/example/ohos/entry/src/ohosTest/ets/test/List.test.ets
new file mode 100644
index 0000000000000000000000000000000000000000..f4140030e65d20df6af30a6bf51e464dea8f8aa6
--- /dev/null
+++ b/app_links/ohos/example/ohos/entry/src/ohosTest/ets/test/List.test.ets
@@ -0,0 +1,20 @@
+/*
+* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd.
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+import abilityTest from './Ability.test'
+
+export default function testsuite() {
+ abilityTest()
+}
\ No newline at end of file
diff --git a/app_links/ohos/example/ohos/entry/src/ohosTest/ets/testability/TestAbility.ets b/app_links/ohos/example/ohos/entry/src/ohosTest/ets/testability/TestAbility.ets
new file mode 100644
index 0000000000000000000000000000000000000000..4ca645e6013cfce8e7dbb728313cb8840c4da660
--- /dev/null
+++ b/app_links/ohos/example/ohos/entry/src/ohosTest/ets/testability/TestAbility.ets
@@ -0,0 +1,63 @@
+/*
+* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd.
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+import UIAbility from '@ohos.app.ability.UIAbility';
+import AbilityDelegatorRegistry from '@ohos.app.ability.abilityDelegatorRegistry';
+import hilog from '@ohos.hilog';
+import { Hypium } from '@ohos/hypium';
+import testsuite from '../test/List.test';
+import window from '@ohos.window';
+
+export default class TestAbility extends UIAbility {
+ onCreate(want, launchParam) {
+ hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onCreate');
+ hilog.info(0x0000, 'testTag', '%{public}s', 'want param:' + JSON.stringify(want) ?? '');
+ hilog.info(0x0000, 'testTag', '%{public}s', 'launchParam:'+ JSON.stringify(launchParam) ?? '');
+ var abilityDelegator: any
+ abilityDelegator = AbilityDelegatorRegistry.getAbilityDelegator()
+ var abilityDelegatorArguments: any
+ abilityDelegatorArguments = AbilityDelegatorRegistry.getArguments()
+ hilog.info(0x0000, 'testTag', '%{public}s', 'start run testcase!!!');
+ Hypium.hypiumTest(abilityDelegator, abilityDelegatorArguments, testsuite)
+ }
+
+ onDestroy() {
+ hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onDestroy');
+ }
+
+ onWindowStageCreate(windowStage: window.WindowStage) {
+ hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onWindowStageCreate');
+ windowStage.loadContent('testability/pages/Index', (err, data) => {
+ if (err.code) {
+ hilog.error(0x0000, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? '');
+ return;
+ }
+ hilog.info(0x0000, 'testTag', 'Succeeded in loading the content. Data: %{public}s',
+ JSON.stringify(data) ?? '');
+ });
+ }
+
+ onWindowStageDestroy() {
+ hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onWindowStageDestroy');
+ }
+
+ onForeground() {
+ hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onForeground');
+ }
+
+ onBackground() {
+ hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onBackground');
+ }
+}
\ No newline at end of file
diff --git a/app_links/ohos/example/ohos/entry/src/ohosTest/ets/testability/pages/Index.ets b/app_links/ohos/example/ohos/entry/src/ohosTest/ets/testability/pages/Index.ets
new file mode 100644
index 0000000000000000000000000000000000000000..cef0447cd2f137ef82d223ead2e156808878ab90
--- /dev/null
+++ b/app_links/ohos/example/ohos/entry/src/ohosTest/ets/testability/pages/Index.ets
@@ -0,0 +1,49 @@
+/*
+* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd.
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+import hilog from '@ohos.hilog';
+
+@Entry
+@Component
+struct Index {
+ aboutToAppear() {
+ hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility index aboutToAppear');
+ }
+ @State message: string = 'Hello World'
+ build() {
+ Row() {
+ Column() {
+ Text(this.message)
+ .fontSize(50)
+ .fontWeight(FontWeight.Bold)
+ Button() {
+ Text('next page')
+ .fontSize(20)
+ .fontWeight(FontWeight.Bold)
+ }.type(ButtonType.Capsule)
+ .margin({
+ top: 20
+ })
+ .backgroundColor('#0D9FFB')
+ .width('35%')
+ .height('5%')
+ .onClick(()=>{
+ })
+ }
+ .width('100%')
+ }
+ .height('100%')
+ }
+ }
\ No newline at end of file
diff --git a/app_links/ohos/example/ohos/entry/src/ohosTest/ets/testrunner/OpenHarmonyTestRunner.ts b/app_links/ohos/example/ohos/entry/src/ohosTest/ets/testrunner/OpenHarmonyTestRunner.ts
new file mode 100644
index 0000000000000000000000000000000000000000..1def08f2e9dcbfa3454a07b7a3b82b173bb90d02
--- /dev/null
+++ b/app_links/ohos/example/ohos/entry/src/ohosTest/ets/testrunner/OpenHarmonyTestRunner.ts
@@ -0,0 +1,64 @@
+/*
+* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd.
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+import hilog from '@ohos.hilog';
+import TestRunner from '@ohos.application.testRunner';
+import AbilityDelegatorRegistry from '@ohos.app.ability.abilityDelegatorRegistry';
+
+var abilityDelegator = undefined
+var abilityDelegatorArguments = undefined
+
+async function onAbilityCreateCallback() {
+ hilog.info(0x0000, 'testTag', '%{public}s', 'onAbilityCreateCallback');
+}
+
+async function addAbilityMonitorCallback(err: any) {
+ hilog.info(0x0000, 'testTag', 'addAbilityMonitorCallback : %{public}s', JSON.stringify(err) ?? '');
+}
+
+export default class OpenHarmonyTestRunner implements TestRunner {
+ constructor() {
+ }
+
+ onPrepare() {
+ hilog.info(0x0000, 'testTag', '%{public}s', 'OpenHarmonyTestRunner OnPrepare ');
+ }
+
+ async onRun() {
+ hilog.info(0x0000, 'testTag', '%{public}s', 'OpenHarmonyTestRunner onRun run');
+ abilityDelegatorArguments = AbilityDelegatorRegistry.getArguments()
+ abilityDelegator = AbilityDelegatorRegistry.getAbilityDelegator()
+ var testAbilityName = abilityDelegatorArguments.bundleName + '.TestAbility'
+ let lMonitor = {
+ abilityName: testAbilityName,
+ onAbilityCreate: onAbilityCreateCallback,
+ };
+ abilityDelegator.addAbilityMonitor(lMonitor, addAbilityMonitorCallback)
+ var cmd = 'aa start -d 0 -a TestAbility' + ' -b ' + abilityDelegatorArguments.bundleName
+ var debug = abilityDelegatorArguments.parameters['-D']
+ if (debug == 'true')
+ {
+ cmd += ' -D'
+ }
+ hilog.info(0x0000, 'testTag', 'cmd : %{public}s', cmd);
+ abilityDelegator.executeShellCommand(cmd,
+ (err: any, d: any) => {
+ hilog.info(0x0000, 'testTag', 'executeShellCommand : err : %{public}s', JSON.stringify(err) ?? '');
+ hilog.info(0x0000, 'testTag', 'executeShellCommand : data : %{public}s', d.stdResult ?? '');
+ hilog.info(0x0000, 'testTag', 'executeShellCommand : data : %{public}s', d.exitCode ?? '');
+ })
+ hilog.info(0x0000, 'testTag', '%{public}s', 'OpenHarmonyTestRunner onRun end');
+ }
+}
\ No newline at end of file
diff --git a/app_links/ohos/example/ohos/entry/src/ohosTest/module.json5 b/app_links/ohos/example/ohos/entry/src/ohosTest/module.json5
new file mode 100644
index 0000000000000000000000000000000000000000..fab77ce2e0c61e3ad010bab5b27ccbd15f9a8c96
--- /dev/null
+++ b/app_links/ohos/example/ohos/entry/src/ohosTest/module.json5
@@ -0,0 +1,51 @@
+/*
+* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd.
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+{
+ "module": {
+ "name": "entry_test",
+ "type": "feature",
+ "description": "$string:module_test_desc",
+ "mainElement": "TestAbility",
+ "deviceTypes": [
+ "phone"
+ ],
+ "deliveryWithInstall": true,
+ "installationFree": false,
+ "pages": "$profile:test_pages",
+ "abilities": [
+ {
+ "name": "TestAbility",
+ "srcEntry": "./ets/testability/TestAbility.ets",
+ "description": "$string:TestAbility_desc",
+ "icon": "$media:icon",
+ "label": "$string:TestAbility_label",
+ "exported": true,
+ "startWindowIcon": "$media:icon",
+ "startWindowBackground": "$color:start_window_background",
+ "skills": [
+ {
+ "actions": [
+ "action.system.home"
+ ],
+ "entities": [
+ "entity.system.home"
+ ]
+ }
+ ]
+ }
+ ]
+ }
+}
diff --git a/app_links/ohos/example/ohos/entry/src/ohosTest/resources/base/element/color.json b/app_links/ohos/example/ohos/entry/src/ohosTest/resources/base/element/color.json
new file mode 100644
index 0000000000000000000000000000000000000000..3c712962da3c2751c2b9ddb53559afcbd2b54a02
--- /dev/null
+++ b/app_links/ohos/example/ohos/entry/src/ohosTest/resources/base/element/color.json
@@ -0,0 +1,8 @@
+{
+ "color": [
+ {
+ "name": "start_window_background",
+ "value": "#FFFFFF"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/app_links/ohos/example/ohos/entry/src/ohosTest/resources/base/element/string.json b/app_links/ohos/example/ohos/entry/src/ohosTest/resources/base/element/string.json
new file mode 100644
index 0000000000000000000000000000000000000000..65d8fa5a7cf54aa3943dcd0214f58d1771bc1f6c
--- /dev/null
+++ b/app_links/ohos/example/ohos/entry/src/ohosTest/resources/base/element/string.json
@@ -0,0 +1,16 @@
+{
+ "string": [
+ {
+ "name": "module_test_desc",
+ "value": "test ability description"
+ },
+ {
+ "name": "TestAbility_desc",
+ "value": "the test ability"
+ },
+ {
+ "name": "TestAbility_label",
+ "value": "test label"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/app_links/ohos/example/ohos/entry/src/ohosTest/resources/base/media/icon.png b/app_links/ohos/example/ohos/entry/src/ohosTest/resources/base/media/icon.png
new file mode 100644
index 0000000000000000000000000000000000000000..ce307a8827bd75456441ceb57d530e4c8d45d36c
Binary files /dev/null and b/app_links/ohos/example/ohos/entry/src/ohosTest/resources/base/media/icon.png differ
diff --git a/app_links/ohos/example/ohos/entry/src/ohosTest/resources/base/profile/test_pages.json b/app_links/ohos/example/ohos/entry/src/ohosTest/resources/base/profile/test_pages.json
new file mode 100644
index 0000000000000000000000000000000000000000..b7e7343cacb32ce982a45e76daad86e435e054fe
--- /dev/null
+++ b/app_links/ohos/example/ohos/entry/src/ohosTest/resources/base/profile/test_pages.json
@@ -0,0 +1,5 @@
+{
+ "src": [
+ "testability/pages/Index"
+ ]
+}
diff --git a/app_links/ohos/example/ohos/hvigor/hvigor-config.json5 b/app_links/ohos/example/ohos/hvigor/hvigor-config.json5
new file mode 100644
index 0000000000000000000000000000000000000000..a9eb4b3a4f416a6adae837be5e6c79e7d734b5d4
--- /dev/null
+++ b/app_links/ohos/example/ohos/hvigor/hvigor-config.json5
@@ -0,0 +1,23 @@
+/*
+* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd.
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+{
+ "modelVersion": "5.0.0",
+ "dependencies": {
+ },
+ 'properties': {
+ "ohos.nativeResolver": false
+ }
+}
\ No newline at end of file
diff --git a/app_links/ohos/example/ohos/hvigorfile.ts b/app_links/ohos/example/ohos/hvigorfile.ts
new file mode 100644
index 0000000000000000000000000000000000000000..8f2d2aafe6d6a3a71a9944ebd0c91fbc308ac9d1
--- /dev/null
+++ b/app_links/ohos/example/ohos/hvigorfile.ts
@@ -0,0 +1,21 @@
+/*
+* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd.
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+import { appTasks } from '@ohos/hvigor-ohos-plugin';
+
+export default {
+ system: appTasks, /* Built-in plugin of Hvigor. It cannot be modified. */
+ plugins:[] /* Custom plugin to extend the functionality of Hvigor. */
+}
\ No newline at end of file
diff --git a/app_links/ohos/example/ohos/oh-package.json5 b/app_links/ohos/example/ohos/oh-package.json5
new file mode 100644
index 0000000000000000000000000000000000000000..76c20a296eb37e56cbbee810baaf34e560ea300c
--- /dev/null
+++ b/app_links/ohos/example/ohos/oh-package.json5
@@ -0,0 +1,21 @@
+{
+ "modelVersion": "5.0.0",
+ "name": "app_links_ohos_example",
+ "version": "1.0.0",
+ "description": "Please describe the basic information.",
+ "main": "",
+ "author": "",
+ "license": "",
+ "dependencies": {
+ "@ohos/flutter_ohos": "file:./har/flutter.har"
+ },
+ "devDependencies": {
+ "@ohos/hypium": "1.0.6"
+ },
+ "overrides": {
+ "@ohos/flutter_ohos": "file:./har/flutter.har",
+ "integration_test": "file:./har/integration_test.har",
+ "app_links_ohos": "file:./har/app_links_ohos.har",
+ "@ohos/flutter_module": "file:./entry"
+ }
+}
\ No newline at end of file
diff --git a/app_links/ohos/example/pubspec.yaml b/app_links/ohos/example/pubspec.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..dcddbeeb88c63484b72b484e0191f98f8f387cf1
--- /dev/null
+++ b/app_links/ohos/example/pubspec.yaml
@@ -0,0 +1,104 @@
+name: app_links_ohos_example
+description: "Demonstrates how to use the app_links_ohos plugin."
+# The following line prevents the package from being accidentally published to
+# pub.dev using `flutter pub publish`. This is preferred for private packages.
+publish_to: 'none' # Remove this line if you wish to publish to pub.dev
+
+environment:
+# sdk: '>=3.4.0 <4.0.0'
+
+ sdk: ^3.3.0
+ flutter: ">=3.19.0"
+
+# Dependencies specify other packages that your package needs in order to work.
+# To automatically upgrade your package dependencies to the latest versions
+# consider running `flutter pub upgrade --major-versions`. Alternatively,
+# dependencies can be manually updated by changing the version numbers below to
+# the latest version available on pub.dev. To see which dependencies have newer
+# versions available, run `flutter pub outdated`.
+dependencies:
+ flutter:
+ sdk: flutter
+
+ app_links_ohos:
+ # When depending on this package from a real application you should use:
+ # app_links_ohos: ^x.y.z
+ # See https://dart.dev/tools/pub/dependencies#version-constraints
+ # The example app is bundled with the plugin so we use a path dependency on
+ # the parent directory to use the current plugin's version.
+ path: ../
+
+ # The following adds the Cupertino Icons font to your application.
+ # Use with the CupertinoIcons class for iOS style icons.
+ cupertino_icons: ^1.0.6
+
+ app_links: ^6.1.3
+
+ ffi: ^2.1.0
+ win32: ^5.1.0
+
+dev_dependencies:
+ integration_test:
+ sdk: flutter
+ flutter_test:
+ sdk: flutter
+
+ # The "flutter_lints" package below contains a set of recommended lints to
+ # encourage good coding practices. The lint set provided by the package is
+ # activated in the `analysis_options.yaml` file located at the root of your
+ # package. See that file for information about deactivating specific lint
+ # rules and activating additional ones.
+
+ msix: ^3.16.8
+
+# flutter_lints: ^3.0.0
+ flutter_lints: ^4.0.0
+
+# For information on the generic Dart part of this file, see the
+# following page: https://dart.dev/tools/pub/pubspec
+
+# The following section is specific to Flutter packages.
+flutter:
+
+ # The following line ensures that the Material Icons font is
+ # included with your application, so that you can use the icons in
+ # the material Icons class.
+ uses-material-design: true
+
+ # To add assets to your application, add an assets section, like this:
+ # assets:
+ # - images/a_dot_burr.jpeg
+ # - images/a_dot_ham.jpeg
+
+ # An image asset can refer to one or more resolution-specific "variants", see
+ # https://flutter.dev/assets-and-images/#resolution-aware
+
+ # For details regarding adding assets from package dependencies, see
+ # https://flutter.dev/assets-and-images/#from-packages
+
+ # To add custom fonts to your application, add a fonts section here,
+ # in this "flutter" section. Each entry in this list should have a
+ # "family" key with the font family name, and a "fonts" key with a
+ # list giving the asset and other descriptors for the font. For
+ # example:
+ # fonts:
+ # - family: Schyler
+ # fonts:
+ # - asset: fonts/Schyler-Regular.ttf
+ # - asset: fonts/Schyler-Italic.ttf
+ # style: italic
+ # - family: Trajan Pro
+ # fonts:
+ # - asset: fonts/TrajanPro.ttf
+ # - asset: fonts/TrajanPro_Bold.ttf
+ # weight: 700
+ #
+ # For details regarding fonts from package dependencies,
+ # see https://flutter.dev/custom-fonts/#from-packages
+
+# Windows only (packaged app)
+msix_config:
+ display_name: app_links_example
+ msix_version: 1.0.0.0
+ protocol_activation: https, sample # Add the protocol activation for the app
+ app_uri_handler_hosts: www.example.com, example.com # Add the app uri handler hosts
diff --git a/app_links/ohos/example/test/widget_test.dart b/app_links/ohos/example/test/widget_test.dart
new file mode 100644
index 0000000000000000000000000000000000000000..6ecdd6917403e250c931b3523355168e7bb924f0
--- /dev/null
+++ b/app_links/ohos/example/test/widget_test.dart
@@ -0,0 +1,27 @@
+// This is a basic Flutter widget test.
+//
+// To perform an interaction with a widget in your test, use the WidgetTester
+// utility in the flutter_test package. For example, you can send tap and scroll
+// gestures. You can also use WidgetTester to find child widgets in the widget
+// tree, read text, and verify that the values of widget properties are correct.
+
+import 'package:flutter/material.dart';
+import 'package:flutter_test/flutter_test.dart';
+
+import 'package:app_links_ohos_example/main.dart';
+
+void main() {
+ testWidgets('Verify Platform version', (WidgetTester tester) async {
+ // Build our app and trigger a frame.
+ await tester.pumpWidget(const MyApp());
+
+ // Verify that platform version is retrieved.
+ expect(
+ find.byWidgetPredicate(
+ (Widget widget) => widget is Text &&
+ widget.data!.startsWith('Running on:'),
+ ),
+ findsOneWidget,
+ );
+ });
+}
diff --git a/app_links/ohos/lib/app_links.dart b/app_links/ohos/lib/app_links.dart
new file mode 100644
index 0000000000000000000000000000000000000000..07c6f343db9a9edcd3ef9b01620ef23036cc0c4f
--- /dev/null
+++ b/app_links/ohos/lib/app_links.dart
@@ -0,0 +1 @@
+export 'src/app_links.dart';
diff --git a/app_links/ohos/lib/app_links_ohos.dart b/app_links/ohos/lib/app_links_ohos.dart
new file mode 100644
index 0000000000000000000000000000000000000000..15330d03cf1a1134c689b986cd7009fcc4bbefaa
--- /dev/null
+++ b/app_links/ohos/lib/app_links_ohos.dart
@@ -0,0 +1,8 @@
+
+import 'app_links_ohos_platform_interface.dart';
+
+class AppLinksOhos {
+ Future getPlatformVersion() {
+ return AppLinksOhosPlatform.instance.getPlatformVersion();
+ }
+}
diff --git a/app_links/ohos/lib/app_links_ohos_method_channel.dart b/app_links/ohos/lib/app_links_ohos_method_channel.dart
new file mode 100644
index 0000000000000000000000000000000000000000..9c189967e94a3fa27b8fd79170f978ba2c3203c3
--- /dev/null
+++ b/app_links/ohos/lib/app_links_ohos_method_channel.dart
@@ -0,0 +1,17 @@
+import 'package:flutter/foundation.dart';
+import 'package:flutter/services.dart';
+
+import 'app_links_ohos_platform_interface.dart';
+
+/// An implementation of [AppLinksOhosPlatform] that uses method channels.
+class MethodChannelAppLinksOhos extends AppLinksOhosPlatform {
+ /// The method channel used to interact with the native platform.
+ @visibleForTesting
+ final methodChannel = const MethodChannel('app_links_ohos');
+
+ @override
+ Future getPlatformVersion() async {
+ final version = await methodChannel.invokeMethod('getPlatformVersion');
+ return version;
+ }
+}
diff --git a/app_links/ohos/lib/app_links_ohos_platform_interface.dart b/app_links/ohos/lib/app_links_ohos_platform_interface.dart
new file mode 100644
index 0000000000000000000000000000000000000000..2732ca52b976bbc96181d67ca9b04035a178de1f
--- /dev/null
+++ b/app_links/ohos/lib/app_links_ohos_platform_interface.dart
@@ -0,0 +1,29 @@
+import 'package:plugin_platform_interface/plugin_platform_interface.dart';
+
+import 'app_links_ohos_method_channel.dart';
+
+abstract class AppLinksOhosPlatform extends PlatformInterface {
+ /// Constructs a AppLinksOhosPlatform.
+ AppLinksOhosPlatform() : super(token: _token);
+
+ static final Object _token = Object();
+
+ static AppLinksOhosPlatform _instance = MethodChannelAppLinksOhos();
+
+ /// The default instance of [AppLinksOhosPlatform] to use.
+ ///
+ /// Defaults to [MethodChannelAppLinksOhos].
+ static AppLinksOhosPlatform get instance => _instance;
+
+ /// Platform-specific implementations should set this with their own
+ /// platform-specific class that extends [AppLinksOhosPlatform] when
+ /// they register themselves.
+ static set instance(AppLinksOhosPlatform instance) {
+ PlatformInterface.verifyToken(instance, _token);
+ _instance = instance;
+ }
+
+ Future getPlatformVersion() {
+ throw UnimplementedError('platformVersion() has not been implemented.');
+ }
+}
diff --git a/app_links/ohos/lib/src/app_links.dart b/app_links/ohos/lib/src/app_links.dart
new file mode 100644
index 0000000000000000000000000000000000000000..a6152ea1c67a125a7c7a6a1bdc66555359af413e
--- /dev/null
+++ b/app_links/ohos/lib/src/app_links.dart
@@ -0,0 +1,87 @@
+import 'dart:async';
+import "package:app_links_platform_interface/app_links_platform_interface.dart";
+
+/// App links handler.
+///
+/// This class is a singleton and should be accessed using `AppLinks()`.
+class AppLinks extends AppLinksPlatform {
+ static final AppLinks _instance = AppLinks._();
+
+ factory AppLinks() => _instance;
+
+ AppLinks._();
+
+ StreamController? _stringStreamController;
+ StreamController? _uriStreamController;
+
+ @override
+ Future getInitialLink() {
+ return AppLinksPlatform.instance.getInitialLink();
+ }
+
+ @override
+ Future getInitialLinkString() {
+ return AppLinksPlatform.instance.getInitialLinkString();
+ }
+
+ @override
+ Future getLatestLink() {
+ return AppLinksPlatform.instance.getLatestLink();
+ }
+
+ @override
+ Future getLatestLinkString() {
+ return AppLinksPlatform.instance.getLatestLinkString();
+ }
+
+ @override
+ Stream get stringLinkStream {
+ if (_stringStreamController == null) {
+ _stringStreamController = StreamController.broadcast();
+
+ _initController(
+ _stringStreamController!,
+ AppLinksPlatform.instance.stringLinkStream,
+ onCancel: () => _stringStreamController = null,
+ );
+ }
+
+ return _stringStreamController!.stream;
+ }
+
+ @override
+ Stream get uriLinkStream {
+ if (_uriStreamController == null) {
+ _uriStreamController = StreamController.broadcast();
+
+ _initController(
+ _uriStreamController!,
+ AppLinksPlatform.instance.uriLinkStream,
+ onCancel: () => _uriStreamController = null,
+ );
+ }
+
+ return _uriStreamController!.stream;
+ }
+
+ void _initController(
+ StreamController controller,
+ Stream stream, {
+ required void Function() onCancel,
+ }) {
+ final subscription = stream.listen(
+ controller.add,
+ onError: controller.addError,
+ );
+
+ // Broadcast controller doesn't support pause/resume
+ //
+ // Forward cancel event when there's no more listeners
+ // and dispose controller
+ controller.onCancel = () async {
+ await subscription.cancel();
+ await controller.close();
+ onCancel();
+ };
+ }
+}
diff --git a/app_links/ohos/ohos/.gitignore b/app_links/ohos/ohos/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..c0f9ca4c47ca2d6aea523c5e0cf3331566bbf88a
--- /dev/null
+++ b/app_links/ohos/ohos/.gitignore
@@ -0,0 +1,9 @@
+/node_modules
+/oh_modules
+/.preview
+/.idea
+/build
+/.cxx
+/.test
+/BuildProfile.ets
+/oh-package-lock.json5
diff --git a/app_links/ohos/ohos/build-profile.json5 b/app_links/ohos/ohos/build-profile.json5
new file mode 100644
index 0000000000000000000000000000000000000000..79961f96a6fe0507354b7952a378c3be2ae4bfab
--- /dev/null
+++ b/app_links/ohos/ohos/build-profile.json5
@@ -0,0 +1,10 @@
+{
+ "apiType": "stageMode",
+ "buildOption": {
+ },
+ "targets": [
+ {
+ "name": "default"
+ }
+ ]
+}
diff --git a/app_links/ohos/ohos/hvigorfile.ts b/app_links/ohos/ohos/hvigorfile.ts
new file mode 100644
index 0000000000000000000000000000000000000000..47e6e1f81d365872f101585f5dbf816bcad65864
--- /dev/null
+++ b/app_links/ohos/ohos/hvigorfile.ts
@@ -0,0 +1,2 @@
+// Script for compiling build behavior. It is built in the build plug-in and cannot be modified currently.
+export { harTasks } from '@ohos/hvigor-ohos-plugin';
\ No newline at end of file
diff --git a/app_links/ohos/ohos/index.ets b/app_links/ohos/ohos/index.ets
new file mode 100644
index 0000000000000000000000000000000000000000..39d5185512e1ed3451e0c7d0031b43ec73e1c46e
--- /dev/null
+++ b/app_links/ohos/ohos/index.ets
@@ -0,0 +1,17 @@
+/*
+* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd.
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+import AppLinksOhosPlugin from './src/main/ets/components/plugin/AppLinksOhosPlugin';
+export default AppLinksOhosPlugin;
diff --git a/app_links/ohos/ohos/local.properties b/app_links/ohos/ohos/local.properties
new file mode 100644
index 0000000000000000000000000000000000000000..f68f693dcae4ef8db5d5bc427813131d1e540262
--- /dev/null
+++ b/app_links/ohos/ohos/local.properties
@@ -0,0 +1 @@
+hwsdk.dir=E:\\Huawei4.0\\Sdk
\ No newline at end of file
diff --git a/app_links/ohos/ohos/oh-package.json5 b/app_links/ohos/ohos/oh-package.json5
new file mode 100644
index 0000000000000000000000000000000000000000..6c1b23388526ad59eda9b5586283e50cb97c79b6
--- /dev/null
+++ b/app_links/ohos/ohos/oh-package.json5
@@ -0,0 +1,11 @@
+{
+ "name": "app_links_ohos",
+ "version": "1.0.0",
+ "description": "Please describe the basic information.",
+ "main": "index.ets",
+ "author": "",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@ohos/flutter_ohos": "file:./har/flutter.har"
+ }
+}
diff --git a/app_links/ohos/ohos/src/main/ets/components/plugin/AppLinksOhosPlugin.ets b/app_links/ohos/ohos/src/main/ets/components/plugin/AppLinksOhosPlugin.ets
new file mode 100644
index 0000000000000000000000000000000000000000..3939f204a4d55774f5ae277cafd78eef9e47e010
--- /dev/null
+++ b/app_links/ohos/ohos/src/main/ets/components/plugin/AppLinksOhosPlugin.ets
@@ -0,0 +1,110 @@
+/*
+* Copyright (c) 2024 Hunan OpenValley Digital Industry Development Co., Ltd.
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+import {
+ AbilityAware,
+ AbilityPluginBinding,
+ Any,
+ FlutterPlugin,
+ FlutterPluginBinding,
+ MethodCall,
+ MethodCallHandler,
+ MethodChannel,
+ MethodResult,
+ NewWantListener,
+} from '@ohos/flutter_ohos';
+import AbilityConstant from '@ohos.app.ability.AbilityConstant';
+import Want from '@ohos.app.ability.Want';
+import EventChannel, { EventSink, StreamHandler } from '@ohos/flutter_ohos/src/main/ets/plugin/common/EventChannel';
+
+/** AppLinksOhosPlugin **/
+export default class AppLinksOhosPlugin implements FlutterPlugin, MethodCallHandler, NewWantListener, StreamHandler, AbilityAware {
+ private channel: MethodChannel | null = null;
+ private eventChannel: EventChannel | null = null;
+ private initialLink: String | null = null;
+ private latestLink: String | null = null;
+ private eventSink: EventSink | null = null;
+
+ constructor() {
+ }
+
+ onAttachedToAbility(binding: AbilityPluginBinding): void {
+ if (binding.getAbility().launchWant) {
+ this.initialLink = binding.getAbility().launchWant.uri || null;
+ this.latestLink = binding.getAbility().launchWant.uri || null;
+ }
+ binding.addOnNewWantListener(this);
+ }
+
+ onDetachedFromAbility(): void {
+ throw new Error('Method not implemented.');
+ }
+
+ onListen(args: Any, events: EventSink): void {
+ throw new Error('Method not implemented.');
+ }
+
+ onCancel(args: Any): void {
+ throw new Error('Method not implemented.');
+ }
+
+ onNewWant(want: Want, launchParams: AbilityConstant.LaunchParam): void {
+ if (want.uri) {
+ this.latestLink = want.uri;
+ this.eventSink?.success(want.uri);
+ } else {
+ this.eventSink?.success(null);
+ }
+ }
+
+ getUniqueClassName(): string {
+ return "AppLinksOhosPlugin"
+ }
+
+ onAttachedToEngine(binding: FlutterPluginBinding): void {
+ this.channel = new MethodChannel(binding.getBinaryMessenger(), "com.llfbandit.app_links/messages");
+ this.channel.setMethodCallHandler(this);
+ this.eventChannel = new EventChannel(binding.getBinaryMessenger(), "com.llfbandit.app_links/events");
+ this.eventChannel.setStreamHandler({
+ onListen: (args: Object, eventSink: EventSink) => {
+ this.eventSink = eventSink;
+ if (this.initialLink) {
+ eventSink.success(this.initialLink);
+ }
+ },
+ onCancel: () => {
+ }
+ });
+ }
+
+ onDetachedFromEngine(binding: FlutterPluginBinding): void {
+ if (this.channel != null) {
+ this.channel.setMethodCallHandler(null);
+ }
+ if (this.eventChannel != null) {
+ this.eventChannel.setStreamHandler(null);
+ }
+ }
+
+ onMethodCall(call: MethodCall, result: MethodResult): void {
+ if (call.method == "getLatestLink") {
+ result.success(this.latestLink);
+ } else if (call.method == "getInitialLink") {
+ result.success(this.initialLink);
+ } else {
+ result.notImplemented();
+ }
+ }
+}
\ No newline at end of file
diff --git a/app_links/ohos/ohos/src/main/module.json5 b/app_links/ohos/ohos/src/main/module.json5
new file mode 100644
index 0000000000000000000000000000000000000000..d7d8888fd90fb04a81f7f7af12624615b5607f5a
--- /dev/null
+++ b/app_links/ohos/ohos/src/main/module.json5
@@ -0,0 +1,10 @@
+{
+ "module": {
+ "name": "app_links_ohos",
+ "type": "har",
+ "deviceTypes": [
+ "default",
+ "tablet"
+ ]
+ }
+}
diff --git a/app_links/ohos/pubspec.yaml b/app_links/ohos/pubspec.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..c1868dac1ed662c87958df3d732df367ecaba88c
--- /dev/null
+++ b/app_links/ohos/pubspec.yaml
@@ -0,0 +1,84 @@
+name: app_links_ohos
+description: "hap Links, Deep Links."
+version: 1.0.0
+homepage: https://gitee.com/openharmony-sig/fluttertpc_app_links
+
+environment:
+# sdk: '>=3.4.0 <4.0.0'
+# flutter: '>=3.3.0'
+
+ sdk: ^3.3.0
+ flutter: ">=3.19.0"
+
+dependencies:
+ flutter:
+ sdk: flutter
+ plugin_platform_interface: ^2.0.2
+
+ app_links_linux: ^1.0.3
+ app_links_platform_interface: ^2.0.2
+ app_links_web: ^1.0.4
+
+dev_dependencies:
+ flutter_test:
+ sdk: flutter
+ flutter_lints: ^3.0.0
+
+# For information on the generic Dart part of this file, see the
+# following page: https://dart.dev/tools/pub/pubspec
+
+# The following section is specific to Flutter packages.
+flutter:
+ # This section identifies this Flutter project as a plugin project.
+ # The 'pluginClass' specifies the class (in Java, Kotlin, Swift, Objective-C, etc.)
+ # which should be registered in the plugin registry. This is required for
+ # using method channels.
+ # The Android 'package' specifies package in which the registered class is.
+ # This is required for using method channels on Android.
+ # The 'ffiPlugin' specifies that native code should be built and bundled.
+ # This is required for using `dart:ffi`.
+ # All these are used by the tooling to maintain consistency when
+ # adding or updating assets for this project.
+ plugin:
+ platforms:
+ ohos:
+ package: com.llfbandit.app_links.app_links_ohos
+ pluginClass: AppLinksOhosPlugin
+
+ # To add assets to your plugin package, add an assets section, like this:
+ # assets:
+ # - images/a_dot_burr.jpeg
+ # - images/a_dot_ham.jpeg
+ #
+ # For details regarding assets in packages, see
+ # https://flutter.dev/assets-and-images/#from-packages
+ #
+ # An image asset can refer to one or more resolution-specific "variants", see
+ # https://flutter.dev/assets-and-images/#resolution-aware
+
+ # To add custom fonts to your plugin package, add a fonts section here,
+ # in this "flutter" section. Each entry in this list should have a
+ # "family" key with the font family name, and a "fonts" key with a
+ # list giving the asset and other descriptors for the font. For
+ # example:
+ # fonts:
+ # - family: Schyler
+ # fonts:
+ # - asset: fonts/Schyler-Regular.ttf
+ # - asset: fonts/Schyler-Italic.ttf
+ # style: italic
+ # - family: Trajan Pro
+ # fonts:
+ # - asset: fonts/TrajanPro.ttf
+ # - asset: fonts/TrajanPro_Bold.ttf
+ # weight: 700
+ #
+ # For details regarding fonts in packages, see
+ # https://flutter.dev/custom-fonts/#from-packages
+
+topics:
+ - deeplink
+ - app-links
+ - universal-links
+ - custom-url-schemes
+ - web-to-app
\ No newline at end of file
diff --git a/app_links/ohos/test/app_links_ohos_test.dart b/app_links/ohos/test/app_links_ohos_test.dart
new file mode 100644
index 0000000000000000000000000000000000000000..e9bad750644b765850e5c5220ed349af2d6d7e88
--- /dev/null
+++ b/app_links/ohos/test/app_links_ohos_test.dart
@@ -0,0 +1,29 @@
+import 'package:flutter_test/flutter_test.dart';
+import 'package:app_links_ohos/app_links_ohos.dart';
+import 'package:app_links_ohos/app_links_ohos_platform_interface.dart';
+import 'package:app_links_ohos/app_links_ohos_method_channel.dart';
+import 'package:plugin_platform_interface/plugin_platform_interface.dart';
+
+class MockAppLinksOhosPlatform
+ with MockPlatformInterfaceMixin
+ implements AppLinksOhosPlatform {
+
+ @override
+ Future getPlatformVersion() => Future.value('42');
+}
+
+void main() {
+ final AppLinksOhosPlatform initialPlatform = AppLinksOhosPlatform.instance;
+
+ test('$MethodChannelAppLinksOhos is the default instance', () {
+ expect(initialPlatform, isInstanceOf());
+ });
+
+ test('getPlatformVersion', () async {
+ AppLinksOhos appLinksOhosPlugin = AppLinksOhos();
+ MockAppLinksOhosPlatform fakePlatform = MockAppLinksOhosPlatform();
+ AppLinksOhosPlatform.instance = fakePlatform;
+
+ expect(await appLinksOhosPlugin.getPlatformVersion(), '42');
+ });
+}