ohos平台适配flutter三方库指导url_launcher
1. 准备工作
下载待适配的三方插件:官方插件库
本指导书, 以适配 url_launcher 6.3.1 为例
2. 插件目录
lib:是对接dart端代码的入口,由此文件接收到参数后,通过channel将数据发送到原生端;
android:安卓端代码实现目录;
ios:ios原生端实现目录;
example:一个依赖于该插件的Flutter应用程序,来说明如何使用它;
README.md:介绍包的文件;
CHANGELOG.md:记录每个版本中的更改;
LICENSE:包含软件包许可条款的文件。
3. 创建插件的ohos模块
命令:flutter create --platforms ohos,android,ios --org <org> <appName>
步骤:
-
用Android Studio打开刚刚下载好的插件。
-
打开Terminal,cd到插件目录下。
-
执行命令
flutter create --platforms ohos url_launcher_ohos
创建一个ohos平台的flutter模块。flutter create --platforms ohos url_launcher_ohos Creating project url_launcher_ohos... Resolving dependencies in `url_launcher_ohos`... Downloading packages... Got dependencies in `url_launcher_ohos`. Wrote 46 files. All done! You can find general documentation for Flutter at: https://docs.flutter.dev/ Detailed API documentation is available at: https://api.flutter.dev/ If you prefer video documentation, consider: https://www.youtube.com/c/flutterdev In order to run your application, type: $ cd url_launcher_ohos $ flutter run Your application code is in url_launcher_ohos/lib/main.dart. jianguo@nutpi url_launcher %
执行创建命令前:
执行创建命令后,可以将url_launcher_ohos目录下的.dart_tool和.ldea文件删除。
4. 编写ohos插件的dart接口和pubspec.yaml文件
可直接复制url_launcher_android目录下lib的dart代码和pubspec.yaml文件进行修改。
dart代码基本不需要修改,只需要将android字样改为ohos。
lib目录dart代码:
pubspec.yaml文件:
name: url_launcher_ohos
description: Android implementation of the url_launcher plugin.
repository: https://gitcode.com/openharmony-tpc/flutter_packages/tree/master/packages/url_launcher/url_launcher_ohos
issue_tracker: https://gitcode.com/openharmony-tpc/flutter_packages/issues
version: 6.3.16
environment:
sdk: ^3.6.0
flutter: ">=3.27.0"
flutter:
plugin:
implements: url_launcher
platforms:
ohos:
package: io.flutter.plugins.urllauncher
pluginClass: UrlLauncherPlugin
dartPluginClass: UrlLauncherOhos
dependencies:
flutter:
sdk: flutter
url_launcher_platform_interface: ^2.3.1
dev_dependencies:
flutter_test:
sdk: flutter
mockito: ^5.4.4
pigeon: ^22.4.1
plugin_platform_interface: ^2.1.7
test: ^1.16.3
topics:
- links
- os-integration
- url-launcher
- urls
5. 编写ohos插件的原生ets模块
5.1 创建ohos的插件模块
由于是写ohos平台的flutter插件,而不是写一个应用,需要将原来的entry模块删除,新建一个url_launcher插件的静态模块,用来写ets原生代码逻辑。
步骤:
-
用DevEco Studio打开url_launcher_ohos下的ohos项目:
-
新建一个名称为url_launcher的静态模块:
在DevEco Studio左上角点击
Flie > New > Module > Static Library > Next
,module name填写为url_launcher
,其他选项为默认,点击Finish,完成创建。 -
删除entry以及其他多余目录:
entry目录(entry是用来写应用的,现在是要写插件,此处已不需要,应该删除),将
url_launcher > src > main > ets
目录下的文件全部删除(此处是一些模板代码可删除)。
5.2 修改相关配置文件
-
在url_launcher目录内的oh-package.json5添加libs/flutter.har 依赖:
{ "name": "url_launcher", "version": "1.0.0", "description": "Please describe the basic information.", "main": "Index.ets", "author": "", "license": "Apache-2.0", "dependencies": { "@ohos/flutter_ohos": "file:libs/flutter.har" //此处为添加的依赖 } }
-
将url_launcher目录外侧的oh-package.json5的dependencies中的flutter.har依赖删除:
{ "name": "url_launcher_ohos", "version": "1.0.0", "description": "Please describe the basic information.", "main": "", "author": "", "license": "", "dependencies": { }, "devDependencies": { "@ohos/hypium": "1.0.6" }, }
-
在url_launcher目录下添加flutter.har:
5.3 编写ets代码
文件结构,和代码逻辑可参考安卓或ios:gitcode.com/openharmony…
ohos的api可以参考:gitcode.com/openharmony…
5.4 修改index文件
import UrlLauncherPlugin from './src/main/ets/plugin/UrlLauncherPlugin';
export default UrlLauncherPlugin;
5.5 打har
写完代码,改完配置文件后,即可打har包。
打包工具:DevEco Studio。
打包步骤:
- 鼠标定位到url_launcher目录。
- 点击DevEco Studio中的Build。
- 点击Make Module 'url_launcher'选项。
- 等待打包完成。
预期结果:
在url_launcher > build > default > outputs
中有url_launcher.har生成,即为打har包成功。
6. 编写example
6.1 创建一个ohos平台的flutter example应用,用来验证刚刚适配的插件功能
cd 到url_launcher_ohos目录下 ;
命令:flutter create --platforms ohos example
工具:Android Studio
6.2 修改dart代码
复制url_launcher_android\example\lib
下的main.dart代码,替换url_launcher_ohos\example\lib
下的main.dart代码。
6.3 修改example pubspec.yaml文件
name: url_launcher_example
description: Demonstrates how to use the url_launcher plugin.
publish_to: none
environment:
sdk: ^3.6.0
flutter: ">=3.27.0"
dependencies:
flutter:
sdk: flutter
url_launcher_ohos:
# When depending on this package from a real application you should use:
# url_launcher_android: ^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: ../
url_launcher_platform_interface: ^2.3.1
dev_dependencies:
flutter_test:
sdk: flutter
integration_test:
sdk: flutter
mockito: ^5.4.4
plugin_platform_interface: ^2.1.7
flutter:
uses-material-design: true
7. 修改url_launcher的pubspec.yaml文件
flutter: plugin:platforms添加ohos。
dependencies:添加url_launcher_ohos依赖。
name: url_launcher
description: Flutter plugin for getting commonly used locations on host platform file systems, such as the temp and app data directories.
repository: https://github.com/flutter/packages/tree/main/packages/url_launcher/url_launcher
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+url_launcher%22
version: 2.1.0
environment:
sdk: ">=2.18.0 <4.0.0"
flutter: ">=3.3.0"
flutter:
plugin:
platforms:
android:
default_package: url_launcher_android
ios:
default_package: url_launcher_foundation
linux:
default_package: url_launcher_linux
macos:
default_package: url_launcher_foundation
windows:
default_package: url_launcher_windows
ohos:
default_package: url_launcher_ohos #此处为添加
dependencies:
flutter:
sdk: flutter
url_launcher_android: ^2.1.0
url_launcher_foundation: ^2.3.0
url_launcher_linux: ^2.2.0
url_launcher_platform_interface: ^2.1.0
url_launcher_windows: ^2.2.0
url_launcher_ohos:
path: ../url_launcher_ohos #此处为添加
dev_dependencies:
flutter_test:
sdk: flutter
integration_test:
sdk: flutter
plugin_platform_interface: ^2.0.0
test: ^1.16.0
8. 运行example
8.1 签名
用 Deveco Studio
打开三方库的 example > ohos
目录。
单击 File > Project Structure > Project > Signing Configs
界面勾选 Automatically generate signature
,等待自动签名完成即可,单击 OK
。
8.2 运行
cd到url_launcher_ohos\example > ohos
目录,使用下列指令运行:
flutter pub get
flutter run -d <device-id>
运行成功效果如下:
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'package:flutter/foundation.dart' show visibleForTesting;
import 'package:flutter/services.dart';
import 'package:url_launcher_platform_interface/link.dart';
import 'package:url_launcher_platform_interface/url_launcher_platform_interface.dart';
import 'src/messages.g.dart';
/// An implementation of [UrlLauncherPlatform] for Android.
class UrlLauncherAndroid extends UrlLauncherPlatform {
/// Creates a new plugin implementation instance.
UrlLauncherAndroid({
@visibleForTesting UrlLauncherApi? api,
}) : _hostApi = api ?? UrlLauncherApi();
final UrlLauncherApi _hostApi;
/// Registers this class as the default instance of [UrlLauncherPlatform].
static void registerWith() {
UrlLauncherPlatform.instance = UrlLauncherAndroid();
}
@override
final LinkDelegate? linkDelegate = null;
@override
Future<bool> canLaunch(String url) async {
final bool canLaunchSpecificUrl = await _hostApi.canLaunchUrl(url);
if (!canLaunchSpecificUrl) {
final String scheme = _getUrlScheme(url);
// canLaunch can return false when a custom application is registered to
// handle a web URL, but the caller doesn't have permission to see what
// that handler is. If that happens, try a web URL (with the same scheme
// variant, to be safe) that should not have a custom handler. If that
// returns true, then there is a browser, which means that there is
// at least one handler for the original URL.
if (scheme == 'http' || scheme == 'https') {
return _hostApi.canLaunchUrl('$scheme://flutter.dev');
}
}
return canLaunchSpecificUrl;
}
@override
Future<void> closeWebView() {
return _hostApi.closeWebView();
}
// TODO(stuartmorgan): Implement launchUrl, and make this a passthrough
// to launchUrl. See also https://github.com/flutter/flutter/issues/66721
@override
Future<bool> launch(
String url, {
required bool useSafariVC,
required bool useWebView,
required bool enableJavaScript,
required bool enableDomStorage,
required bool universalLinksOnly,
required Map<String, String> headers,
String? webOnlyWindowName,
}) async {
final bool succeeded;
if (useWebView) {
succeeded = await _hostApi.openUrlInWebView(
url,
WebViewOptions(
enableJavaScript: enableJavaScript,
enableDomStorage: enableDomStorage,
headers: headers));
} else {
succeeded = await _hostApi.launchUrl(url, headers);
}
// TODO(stuartmorgan): Remove this special handling as part of a
// breaking change to rework failure handling across all platform. The
// current behavior is backwards compatible with the previous Java error.
if (!succeeded) {
throw PlatformException(
code: 'ACTIVITY_NOT_FOUND',
message: 'No Activity found to handle intent { $url }');
}
return succeeded;
}
// Returns the part of [url] up to the first ':', or an empty string if there
// is no ':'. This deliberately does not use [Uri] to extract the scheme
// so that it works on strings that aren't actually valid URLs, since Android
// is very lenient about what it accepts for launching.
String _getUrlScheme(String url) {
final int schemeEnd = url.indexOf(':');
if (schemeEnd == -1) {
return '';
}
return url.substring(0, schemeEnd);
}
}