相关阅读:
前言
随着 HDC 2024
的结束,鸿蒙 Next
正式对个人开发者开放,个人开发者终于能够更简单地加入到鸿蒙 Next
的体验中。(之前只有少数个人开发者能加入到预览中 华为纯血鸿蒙 HarmonyOS NEXT 开发者预览版首批 Beta 招募开启,支持 Mate 60 / Pro、X5 机型)。
最新工具 - 下载中心 - 华为开发者联盟 (huawei.com)
DevEco Studio NEXT Developer Beta1
面向HarmonyOS应用及元服务开发者提供的集成开发环境(IDE),助力高效开发。
Build Version 5.0.3.403 发布日期 2024/06/21
真机和模拟器的区别
这一次除了开放下载 DevEco Studio Next 版本
,还开放了模拟器下载,(当然,需要去申请一下,很快就会通过),那么真机和模拟器有什么区别呢?
模拟器与真机的差异-概述-使用模拟器运行应用/服务-应用/服务运行-DevEco Studio | 华为开发者联盟 (huawei.com)
在 ui
层面,主要是一些效果,比如阴影或者3d效果的缺失。这里提前说这个,是因为后面要考。
鸿蒙玩家
如果你是一个鸿蒙开发者,就比较简单了,直接到 最新工具 - 下载中心 - 华为开发者联盟 (huawei.com) 下载符合你的设备的 DevEco Studio
。
如果你第一次玩,需要创建一个华为开发者账号,后续需要用到。比如如果你使用真机,需要登录账号签名。比如你下载模拟器,需要登录账号,去申请模拟器下载权限。
点击链接,申请模拟器下载权限。
怎么编写鸿蒙应用,我这里不展开写了。大家可以查看下面的文章了解更多的信息。
- Flutter到鸿蒙,不是有手就行吗? (下拉刷新) - 掘金 (juejin.cn)
- Flutter到鸿蒙,不是有手就行吗? (列表加载更多) - 掘金 (juejin.cn)
- Flutter到鸿蒙,不是有手就行吗? (仿掘金点赞按钮) - 掘金 (juejin.cn)
欢迎大家使用 HarmonyCandies 提供的鸿蒙组件,欢迎加入 HarmonyCandies (github.com)。
Flutter 鸿蒙化玩家
作为 Flutter
鸿蒙化的玩家,你没有阅读过下面的文章,也没有关系。 OpenHarmony-SIG/flutter_flutter (gitee.com) 鸿蒙化社区更新很快,之前文章里面的一些信息已经失效。
- Flutter Love 鸿蒙 - 掘金 (juejin.cn)
- 不是鸿蒙 ArkUI 不会写,而是 Flutter 更有性价比 - 掘金 (juejin.cn)
- Flutter 鸿蒙化 在一起 就可以 - 掘金 (juejin.cn)
后续内容全部基于 OpenHarmony-SIG/flutter_flutter (gitee.com) 和 OpenHarmony-SIG/flutter_engine (gitee.com) 的 dev 分支。参考文档也以 dev 分支 的文档为准。另外最新支持的是
ohos api12
。
下面基于最新的社区进度,主要讲一下环境和一些注意事项。
Mac
Mac
分 X86
和 ARM
芯片的。注意,由于目前 Flutter for Harmony
暂时不支持 x86_x64
架构,在 X86
芯片的 Mac
上面,你只能用真机开发。ARM 芯片(即 M1,M2,M3,M4) 可以使用模拟器。
Windows
注意,由于目前 Flutter for Harmony
暂时不支持 x86_x64
架构,所以 Windows
上面你只能使用真机进行开发。
模拟器真机差异
前面说了模拟器与真机之间是有差异的,这导致 Flutter
在鸿蒙模拟器中,可能某些组件 API
不能使用。
模拟器与真机的差异-概述-使用模拟器运行应用/服务-应用/服务运行-DevEco Studio | 华为开发者联盟 (huawei.com)
比如说 FloatingActionButton
包含阴影效果,就没法在模拟器中使用,会导致闪退。上图相关的 API
我们都要注意一下。
可以的话,做 Flutter 鸿蒙化最好是使用真机。
环境配置
准备工作
- 下载适配鸿蒙的
flutter sdk
git clone -b dev git@gitee.com:openharmony-sig/flutter_flutter.git
- 下载
DevEco-Studio
最新工具 - 下载中心 - 华为开发者联盟 (huawei.com)
Mac 和 Linux
- 设置环境变量
我的鸿蒙相关的内容是放在 /Users/zmtzawqlp/Documents/ohos/flutter/flutter_flutter
中的。
export PATH=/Users/zmtzawqlp/Documents/ohos/flutter/flutter_flutter/bin:$PATH
export PATH=/Users/zmtzawqlp/Documents/ohos/flutter/flutter_flutter/bin/cache/dart-sdk/bin:$PATH
# ohos
export TOOL_HOME=/Applications/DevEco-Studio.app/Contents # mac环境
export DEVECO_SDK_HOME=$TOOL_HOME/sdk # command-line-tools/sdk
export PATH=$TOOL_HOME/tools/ohpm/bin:$PATH # command-line-tools/ohpm/bin
export PATH=$TOOL_HOME/tools/hvigor/bin:$PATH # command-line-tools/hvigor/bin
export PATH=$TOOL_HOME/tools/node/bin:$PATH # command-line-tools/tool/node/bin
Windows
- 去环境变量中添加,下面的键值对。
- 去环境变量
PATH
中添加,下面的路径
以及 flutter
和 dart
的路径,这里就不截图了。
引擎编译
目前,社区已经支持自动下载最新的线上引擎,所以对于不追求引擎代码随时最新的玩家,这部分内容可以跳过。
环境准备
编译问题
python 版本
如果你编译报错
ModuleNotFoundError: No module named 'imp'
,请切换 python
版本到 3.11
以其以下。 python3.12
中 imp
已经不支持。
python - ModuleNotFoundError: No module named 'imp' - Stack Overflow
Xcode15
如果你的电脑升级了 Xcode15
,在做编译引擎的时候,也许会遇到下面的错误。
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX14.4.sdk/System/Library/Frameworks/Foundation.framework/Headers/NSObjCRuntime.h:657:37: error: use of undeclared identifier 'NSIntegerMax'
static const NSInteger NSNotFound = NSIntegerMax;
或者
../../third_party/dart/runtime/bin/security_context_macos.cc:188:17: error: use of undeclared identifier 'noErr'
if (status != noErr) {
^
../../third_party/dart/runtime/bin/security_context_macos.cc:196:19: error: use of undeclared identifier 'noErr'
if (status != noErr) {
^
../../third_party/dart/runtime/bin/security_context_macos.cc:205:17: error: use of undeclared identifier 'noErr'
if (status != noErr) {
^
../../third_party/dart/runtime/bin/security_context_macos.cc:303:21: error: use of undeclared identifier 'noErr'
OSStatus status = noErr;
^
../../third_party/dart/runtime/bin/security_context_macos.cc:319:23: error: use of undeclared identifier 'noErr'
status == noErr && (trust_result == kSecTrustResultProceed ||
^
解决办法是从下面地址选择 13.3 sdk
中的 TargetConditionals.h
替换掉你本地的,注意做备份。
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/TargetConditionals.h
运行调试引擎
设置本地引擎
我们可以通过下面三种方法在运行调试项目的时候,设置我们编译出来的引擎。
launch.json
通过 vscode
我们可以创建 launch.json
.
其中
--local-engine-src-path
是你编译出来引擎目录下面 src
的路径。
--local-engine
是 src
下面 out
文件夹中
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "ohos_demo",
"request": "launch",
"type": "dart",
"args": [
"--local-engine-src-path",
"/Users/xxx/Documents/ohos/flutter/engine/src",
"--local-engine",
"ohos_debug_unopt_arm64",
]
},
{
"name": "ohos_demo (profile mode)",
"request": "launch",
"type": "dart",
"flutterMode": "profile",
"args": [
"--local-engine-src-path",
"/Users/xxx/Documents/ohos/flutter/engine/src",
"--local-engine",
"ohos_profile_arm64",
]
},
{
"name": "ohos_demo (release mode)",
"request": "launch",
"type": "dart",
"flutterMode": "release",
"args": [
"--local-engine-src-path",
"/Users/xxx/Documents/ohos/flutter/engine/src",
"--local-engine",
"ohos_release_arm64",
]
}
]
}
缺点每个项目都需要创建一个,并且只能点击这里的按钮启动。
命令
直接使用命令运行,当然也需要配置参数。
flutter run --local-engine-src-path /Users/xxx/Documents/ohos/flutter/engine/src --local-engine ohos_debug_unopt_arm64
修改 flutter_tools 的流程
- 创建一个
ohos_local_engine.patch
文件,将下面的内容复制到里面去。
diff --git a/packages/flutter_tools/lib/src/runner/flutter_command_runner.dart b/packages/flutter_tools/lib/src/runner/flutter_command_runner.dart
index 28dc9f587a..bf94f57750 100644
--- a/packages/flutter_tools/lib/src/runner/flutter_command_runner.dart
+++ b/packages/flutter_tools/lib/src/runner/flutter_command_runner.dart
@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+import 'dart:io';
+
import 'package:args/args.dart';
import 'package:args/command_runner.dart';
import 'package:completion/completion.dart';
@@ -172,7 +174,54 @@ class FlutterCommandRunner extends CommandRunner<void> {
}
}
- return super.run(args);
+ ArgResults argResults = super.parse(args);
+
+ var ohosArgs = <String>[];
+ // 没有设置过本地引擎
+ if (!args.contains('--local-engine-src-path') &&
+ !args.contains('--local-engine')) {
+ final String? flutterOhosEngine =
+ Platform.environment['FLUTTER_OHOS_ENGINE'];
+
+ print('FLUTTER_OHOS_ENGINE -----$flutterOhosEngine');
+ if (flutterOhosEngine != null) {
+ Directory outDirectory = globals.fs
+ .directory(globals.fs.path.join(flutterOhosEngine, 'out'));
+ var buildMode = 'debug';
+ var command = argResults.command;
+ if (command != null) {
+ if (command.options.contains('release') &&
+ command['release'] == true) {
+ buildMode = 'release';
+ } else if (command.options.contains('profile') &&
+ command['profile'] == true) {
+ buildMode = 'profile';
+ }
+ }
+ var localEngine = '';
+ if (outDirectory.existsSync()) {
+ for (final FileSystemEntity file in outDirectory.listSync()) {
+ if (file is Directory && file.basename.contains(buildMode)) {
+ localEngine = file.basename;
+ }
+ }
+ }
+ if (localEngine.isNotEmpty) {
+ ohosArgs = [
+ '--local-engine-src-path',
+ flutterOhosEngine,
+ '--local-engine',
+ localEngine,
+ ];
+ print('自动设置本地引擎位\n${ohosArgs.join('\n')}');
+ }
+ }
+ }
+
+ return super.run(<String>[
+ ...ohosArgs,
+ ...args,
+ ]);
}
@override
- 到你本地
Flutter SDK
的目录中去,执行git apply ohos_local_engine.patch
。 - 删除
Flutter SDK
目录下面bin\cache
中的flutter_tools.stamp
和flutter_tools.snapshot
, 执行flutter doctor
命令,重新编译flutter_tools
。 - 增加环境变量
FLUTTER_OHOS_ENGINE
指向本地引擎的src
目录。
- linux,macos
export FLUTTER_OHOS_ENGINE=/Users/xxx/Documents/ohos/flutter/engine/src
- windows
这样子就会根据你运行的模式自己设置本地引擎的参数了。
签名
如果在真机上面运行,需要签名。之前是使用工具进行签名的,但是对于需要频繁切换项目的情况下,不方便,我们可以使用 Deveco Studio
签名,对你想运行的项目进行签名。流程跟 Flutter Ios
端使用 Xcode
签名相似。
- 用
Deveco Studio
打开项目的ohos
目录 - 单击
File > Project Structure > Project > Signing Configs
界面勾选Automatically generate signature
,等待自动签名完成即可,单击OK
。 - 查看
build-profile.json5
配置信息,配置信息中增加自动签名生成的证书信息。
鸿蒙 Flutter 插件
现阶段 Flutter
适配工作主要集中在鸿蒙原生插件的适配。下面介绍一下已知完成适配的插件。
flutter_packages
OpenHarmony-SIG/flutter_packages (gitee.com) 是适配官方 flutter/packages: A collection of useful packages maintained by the Flutter team (github.com) 仓库。
引用方式例子如下:
dependencies:
path_provider:
git:
url: "https://gitee.com/openharmony-sig/flutter_packages.git"
path: "packages/path_provider/path_provider"
path_provider | 2.1.1 | 官方库 | 11月30日 | gitee.com/openharmony… | |
---|---|---|---|---|---|
shared_preferences | 2.2.1 | 官方库 | 11月30日 | gitee.com/openharmony… | |
url_launcher | 6.1.11 | 官方库 | 11月30日 | gitee.com/openharmony… | |
image_picker | 1.0.4 | 官方库 | 12月30日 | gitee.com/openharmony… | |
local_auth | 2.1.6 | 官方库 | 12月30日 | gitee.com/openharmony… | |
pigeon | 11.0.1 | 官方库 | 12月30日 | gitee.com/openharmony… | |
webview_flutter | 4.2.4、4.4.4 | 官方库 | 12月30日 | gitee.com/openharmony… | |
video_player | 2.7.2 | 官方库 | 3月30日 | gitee.com/openharmony… | |
file_selector | 1.0.1 | 官方库 | 12月30日 | gitee.com/openharmony… | |
camera | 0.10.5 | 官方库 | 3月30日 | gitee.com/openharmony… |
plus 插件
[Request]: support HarmonyOS · Issue #2480 · fluttercommunity/plus_plugins (github.com) 作者对于适配鸿蒙平台兴趣不大,所以这里决定 HarmonyCandies (github.com) 来维护。
wakelock_plus_ohos
引用:
dependencies:
wakelock_plus: 1.1.4
wakelock_plus_ohos: any
device_info_plus_ohos
引用:
dependencies:
device_info_plus: any
device_info_plus_ohos: any
注意,有 2
个 uid
是系统级别的,需要应用单独申请。
/// Requires permission: ohos.permission.sec.ACCESS_UDID (System permission, only open to system apps).
/// Device serial number.
/// 设备序列号。
final String serial;
/// Requires permission: ohos.permission.sec.ACCESS_UDID (System permission, only open to system apps).
/// Device Udid.
/// 设备Udid。
final String udid;
使用
import 'package:device_info_plus_ohos/device_info_plus_ohos.dart';
final DeviceInfoOhosPlugin deviceInfoOhosPlugin = DeviceInfoOhosPlugin();
OhosDeviceInfo deviceInfo = await deviceInfoOhosPlugin.ohosDeviceInfo;
// Requires permission: ohos.permission.sec.ACCESS_UDID (System permission, only open to system apps).
OhosAccessUDIDInfo accessUDIDInfo = await deviceInfoOhosPlugin.ohosAccessUDIDInfo;
network_info_plus_ohos
引用:
dependencies:
network_info_plus: any
network_info_plus_ohos: any
在你的项目的 module.json5
文件中增加以下权限设置。
requestPermissions: [
{"name" : "ohos.permission.INTERNET"},
{"name" : "ohos.permission.GET_WIFI_INFO"},
],
sensors_plus_ohos
引用:
dependencies:
sensors_plus: 4.0.2
sensors_plus_ohos: any
在你的项目的 module.json5
文件中增加以下权限设置。
requestPermissions: [
{"name" : "ohos.permission.ACCELEROMETER"},
{"name" : "ohos.permission.GYROSCOPE"},
],
connectivity_plus_ohos
引用:
dependencies:
connectivity_plus: 5.0.2
connectivity_plus_ohos: any
在你的项目的 module.json5
文件中增加以下权限设置。
requestPermissions: [
{"name" : "ohos.permission.INTERNET"},
{"name" : "ohos.permission.GET_NETWORK_INFO"},
],
battery_plus_ohos
引用:
dependencies:
battery_plus: 5.0.3
battery_plus_ohos: any
package_info_plus_ohos
引用:
dependencies:
package_info_plus: 4.2.0
package_info_plus_ohos: any
糖果插件
flutter_image_compress
引用:
dependencies:
flutter_image_compress: ^2.2.0
Feature | Android | iOS | Web | macOS | OpenHarmony |
---|---|---|---|---|---|
method: compressWithList | ✅ | ✅ | ✅ | ✅ | ✅ |
method: compressAssetImage | ✅ | ✅ | ✅ | ✅ | ✅ |
method: compressWithFile | ✅ | ✅ | ❌ | ✅ | ✅ |
method: compressAndGetFile | ✅ | ✅ | ❌ | ✅ | ✅ |
format: jpeg | ✅ | ✅ | ✅ | ✅ | ✅ |
format: png | ✅ | ✅ | ✅ | ✅ | ✅ |
format: webp | ✅ | ✅ | [🌐][webp-compatibility] | ❌ | ✅ |
format: heic | ✅ | ✅ | ❌ | ✅ | ✅ |
param: quality | ✅ | ✅ | [🌐][webp-compatibility] | ✅ | ✅ |
param: rotate | ✅ | ✅ | ❌ | ✅ | ✅ |
param: keepExif | ✅ | ✅ | ❌ | ✅ | ❌ |
flutter_image_editor
引用:
dependencies:
image_editor: ^2.2.0
Feature | Android | iOS | OpenHarmony |
---|---|---|---|
flip | ✅ | ✅ | ✅ |
crop | ✅ | ✅ | ✅ |
rotate | ✅ | ✅ | ✅ |
scale | ✅ | ✅ | ✅ |
matrix | ✅ | ✅ | ❌ |
mix image | ✅ | ✅ | ✅ |
merge multi image | ✅ | ✅ | ✅ |
draw point | ✅ | ✅ | ✅ |
draw line | ✅ | ✅ | ✅ |
draw rect | ✅ | ✅ | ✅ |
draw circle | ✅ | ✅ | ✅ |
draw path | ✅ | ✅ | ✅ |
draw Bezier | ✅ | ✅ | ✅ |
Gaussian blur | ❌ | ❌ | ❌ |
flutter_photo_manager
注意,由于隐私设计的变更,该插件没法在后续的版本中使用了,鸿蒙将不再支持直接获取相册的图片文件。
引用:
注意 photo_manager_image_provider
需要限制一下版本。
dependencies:
photo_manager: ^3.1.0
dependency_overrides:
photo_manager_image_provider: ^1.1.1
暂时支持下面的功能,目前鸿蒙只支持图片和视频 2 种资源类型。
Feature | OpenHarmony |
---|---|
getAssetPathList | ✅ |
getAssetCountFromPath | ✅ |
fetchPathProperties | ✅ |
getAssetCount | ✅ |
getAssetListPaged | ✅ |
getOriginBytes | ✅ |
getThumb | ✅ |
getAssetListRange | ✅ |
getAssetsByRange | ✅ |
deleteWithIds | ✅ |
getColumnNames | ✅ |
saveImage | ✅ |
saveImageWithPath | ✅ |
saveVideo | ✅ |
requestPermissionExtend | ✅ |
ignorePermissionCheck | ✅ |
log | ✅ |
notify | ✅ |
其他插件
permission_handler_ohos
引用:
dependencies:
permission_handler_ohos: any
权限列表来自: gitee.com/openharmony…
注意
由于 OpenHarmony
和 HarmonyOS
的权限差异以及鸿蒙版本的高速迭代,检查请求权限的 api
是传递的权限的字符串全称,如果你发现 PermissionOhos
枚举中没有某个权限,你可以直接传递权限的字符串全称。等鸿蒙版本稳定下来了,会再同步权限列表到枚举中。
权限枚举列表是由文档自动生成的。
// GENERATED CODE - DO NOT MODIFY MANUALLY
// **************************************************************************
// Auto generated by https://github.com/HarmonyCandies/permission_handler_ohos/bin/main.dart
// **************************************************************************
// https://gitee.com/openharmony/docs/blob/OpenHarmony-4.1-Release/zh-cn/application-dev/security/AccessToken/permissions-for-all.md
// ignore_for_file: constant_identifier_names,slash_for_doc_comments
/// The Permissions of OpenHarmony
/// total: 44
enum PermissionOhos {
/// ohos.permission.USE_BLUETOOTH
///
/// 允许应用查看蓝牙的配置。
///
/// 权限级别:normal
///
/// 授权方式:system_grant
///
/// ACL使能:true
///
/// 起始版本:8
use_bluetooth(
name: 'ohos.permission.USE_BLUETOOTH',
permissionLevel: 'normal',
grantType: 'system_grant',
aclEnabled: true,
startVersion: 8,
),
使用
请认真阅读官方关于权限的文档 gitee.com/openharmony…
在你的项目的 module.json5
文件中增加对应需要权限设置,比如:
requestPermissions: [
{ name: "ohos.permission.READ_CALENDAR" },
{ name: "ohos.permission.WRITE_CALENDAR" },
],
例子
检查权限状态
import 'package:device_info_plus_ohos/device_info_plus_ohos.dart';
final PermissionStatusOhos status =
await PermissionHandlerOhos.checkPermissionStatus(
PermissionOhos.read_calendar.name);
请求单个权限
final PermissionStatusOhos status =
await PermissionHandlerOhos.requestPermission(
PermissionOhos.read_calendar.name,
);
请求多个权限
final Map<String, PermissionStatusOhos> statusMap =
await PermissionHandlerOhos.requestPermissions([
PermissionOhos.read_calendar.name,
PermissionOhos.write_calendar.name,
]);
打开设置页面
PermissionHandlerOhos.openAppSettings();
audio_streamer_ohos
引用:
dependencies:
audio_streamer: 4.1.1
audio_streamer_ohos: any
audio_streamer 在 OpenHarmony 平台上的实现
在 OpenHarmony 项目的 module.json
文件中添加 ohos.permission.MICROPHONE
权限
{
"module": {
"requestPermissions": [
{
"name": "ohos.permission.MICROPHONE",
"reason": "Microphone permission is required to record audio."
}
]
}
}
geolocator
地址: HarmonyCandies/geolocator_ohos: The OpenHarmony implementation of geolocator. (github.com)
引用:
dependencies:
geolocator: any
geolocator_ohos: ^0.0.1
在你的项目的 module.json5
文件中增加以下权限设置。
"requestPermissions": [
{"name" : "ohos.permission.KEEP_BACKGROUND_RUNNING"},
{
"name": "ohos.permission.LOCATION",
"reason": "$string:EntryAbility_label",
"usedScene": {
"abilities": [
"EntryAbility"
],
"when": "inuse"
}
},
{
"name": "ohos.permission.APPROXIMATELY_LOCATION",
"reason": "$string:EntryAbility_label",
"usedScene": {
"abilities": [
"EntryAbility"
],
"when": "inuse"
}
},
{
"name": "ohos.permission.LOCATION_IN_BACKGROUND",
"reason": "$string:EntryAbility_label",
"usedScene": {
"abilities": [
"EntryAbility"
],
"when": "inuse"
}
},
]
鸿蒙特有的方法
CountryCode? countryCode= await geolocatorOhos.getCountryCode();
(逆)地理编码转化
final position = await geolocatorOhos.getCurrentPosition(
locationSettings: const CurrentLocationSettingsOhos(
priority: LocationRequestPriority.firstFix,
scenario: LocationRequestScenario.unset,
),
);
// ohos only
if (await geolocatorOhos.isGeocoderAvailable()) {
//
var addresses = await geolocatorOhos.getAddressesFromLocation(
ReverseGeoCodeRequest(
latitude: position.latitude,
longitude: position.longitude,
locale: 'zh',
maxItems: 1,
),
);
for (var address in addresses) {
if (kDebugMode) {
print('ReverseGeoCode address:$address');
}
var position = await geolocatorOhos.getAddressesFromLocationName(
GeoCodeRequest(description: address.placeName ?? ''),
);
if (kDebugMode) {
print('geoCode position:$position');
}
}
}
vibration
地址:flutter_vibration/vibration_ohos at master · benjamindean/flutter_vibration (github.com)
引用:
dependencies:
vibration: any
vibration_ohos: any
在你的项目的 module.json5
文件中增加以下权限设置。
"requestPermissions": [
{"name" : "ohos.permission.VIBRATE"},
]
vibrateEffect
and vibrateAttribute
are only exist in VibrationOhos
.
(VibrationPlatform.instance as VibrationOhos).vibrate(
vibrateEffect: const VibratePreset(count: 100),
vibrateAttribute: const VibrateAttribute(
usage: 'alarm',
),
);
sqflite
引用:
dependencies:
sqflite:
git:
url: "https://gitee.com/openharmony-sig/flutter_sqflite.git"
path: "sqflite"
fluttertoast
引用:
dependencies:
fluttertoast:
git:
url: "https://gitee.com/openharmony-sig/flutter_fluttertoast.git"
audio_session
引用:
dependencies:
audio_session:
git:
url: "https://gitee.com/openharmony-sig/flutter_audio_session.git"
flutter_sound
引用:
dependencies:
flutter_sound:
git:
url: "https://gitee.com/openharmony-sig/flutter_sound.git"
path: "flutter_sound"
image_gallery_saver
引用:
dependencies:
image_gallery_saver:
git:
url: "https://gitee.com/openharmony-sig/flutter_image_gallery_saver.git"
location
引用:
dependencies:
location:
git:
url: "https://gitee.com/openharmony-sig/flutter_location.git"
path: "location"
power_image
引用:
dependencies:
power_image:
git:
url: "https://gitee.com/openharmony-sig/flutter_power_image.git"
flutter_native_image
引用:
dependencies:
flutter_native_image:
git:
url: "https://gitee.com/openharmony-sig/flutter_native_image.git"
audioplayers
引用:
dependencies:
audioplayers:
git:
url: "https://gitee.com/openharmony-sig/flutter_audioplayers.git"
image_crop
引用:
dependencies:
image_crop:
git:
url: "https://gitee.com/openharmony-sig/flutter_image_crop.git"
bitmap
引用:
dependencies:
bitmap:
git:
url: "https://gitee.com/openharmony-sig/flutter_bitmap.git"
leak_detector
引用:
dependencies:
leak_detector:
git:
url: "https://gitee.com/openharmony-sig/flutter_leak_detector.git"
flutter_contacts
引用:
dependencies:
flutter_contacts:
git:
url: "https://gitee.com/openharmony-sig/flutter_contacts.git"
编写插件注意事项
关于鸿蒙的 context
在制作插件中,你可能需要用到 2
种 context
。
ApplicationContex
你可以直接从 onAttachedToEngine
方法中获取。
private context: Context | null = null;
onAttachedToEngine(binding: FlutterPluginBinding): void {
this.context = binding.getApplicationContext();
}
onDetachedFromEngine(binding: FlutterPluginBinding): void {
this.context = null;
}
该 context
可以用于获取 applicationInfo
等属性。
let applicationInfo = this.context.applicationInfo;
UIAbilityContext
插件继承 AbilityAware
并且在 onAttachedToAbility
方法中获取。
export default class XXXPlugin implements FlutterPlugin, MethodCallHandler, AbilityAware {
private _uiContext: common.UIAbilityContext | null = null;
onAttachedToAbility(binding: AbilityPluginBinding): void {
this._uiContext = binding.getAbility().context;
}
onDetachedFromAbility(): void {
this._uiContext = null;
}
}
该 uiContext
可以用于获取 applicationInfo
等属性。
photoAccessHelper.getPhotoAccessHelper(PhotoManagerPlugin.uiContext);
关于插件参数传递
按照以前的习惯,dart
端传递 map
参数,原生端根据 map
解析参数。
但由于 ts
支持将字符串直接转换成对应的 interface
,那么我们可以将 dart
的端的参数。
参数定义
比如 geolocator_ohos
中的 CurrentLocationSettingsOhos
在 dart
端的实现为如下:
Map<String, dynamic> toMap() {
return {
if (priority != null) 'priority': priority?.toInt(),
if (scenario != null) 'scenario': scenario?.toInt(),
if (maxAccuracy != null) 'maxAccuracy': maxAccuracy,
if (timeoutMs != null) 'timeoutMs': timeoutMs,
};
}
@override
String toString() {
return jsonEncode(toMap());
}
而在鸿蒙原生端,对于的 interface
是 CurrentLocationRequest
export interface CurrentLocationRequest {
priority?: LocationRequestPriority;
scenario?: LocationRequestScenario;
maxAccuracy?: number;
timeoutMs?: number;
}
值得注意的是,如果参数为 null
,不要传递过去,比如 'priority': null
, 如果传递过去,鸿蒙原生端会解析错误。不传递过去的话,会解析为 undefined
,这也对应了 priority?: LocationRequestPriority
可选的意思。
可以使用
chatgpt
直接将鸿蒙的interface
转换成dart
的类,并且增加toMap
,fromMap
,和注释。
插件传递
dart
端,将参数类以字符串的方式传递过去,并且用字符串的方式接受返回值。
@override
Future<Position> getCurrentPosition({
LocationSettings? locationSettings,
String? requestId,
}) async {
assert(
locationSettings == null ||
locationSettings is CurrentLocationSettingsOhos,
'locationSettings should be CurrentLocationSettingsOhos',
);
try {
final Duration? timeLimit = locationSettings?.timeLimit;
Future<dynamic> positionFuture =
GeolocatorOhos._methodChannel.invokeMethod(
'getCurrentPosition',
locationSettings?.toString(),
);
if (timeLimit != null) {
positionFuture = positionFuture.timeout(timeLimit);
}
return PositionOhos.fromString(await positionFuture);
}
}
在鸿蒙端, 将字符串直接转换成鸿蒙对应的 interface
。
let request: geoLocationManager.CurrentLocationRequest = JSON.parse(args);
并且将要返回的 interface
转换成字符串。
result.success(JSON.stringify(location));
当然了,这样有个问题,就是如果鸿蒙端修改了 interface
的属性名字,插件很难感知到(当然会报错)。
纯 Flutter 库
extended_text
dependencies:
extended_text: 10.0.1-ohos // 适配 3.7.12
extended_text: 13.0.2 // 适配 3.22.0
extended_text_field
dependencies:
extended_text_field: 11.0.1-ohos // 适配 3.7.12
extended_text_field: 15.0.0-ohos // 适配 3.22.0
flutter_platform_utils
HarmonyCandies/flutter_platform_utils: A utility to check the platform for ohos (github.com)
如果您的库支持 OpenHarmony
平台,并且有 Platform.isOhos
的判断,那么建议换成 PlatformUtils.isOhos
避免对其他非鸿蒙用户在非鸿蒙分支编译的影响。
结语
独行快,众行远,加入鸿蒙正当时。
随着鸿蒙商店里面的应用越来越多,还在观望的你,与其犹豫不决,还不如笃定前行。
作为开发者,我们曾经骂过微软,骂过谷歌,骂过苹果,但这些抱怨其实源于我们对它们的期望,希望它们变得更好。同样的,鸿蒙也是如此。
最后,鸿蒙原生,启动!
爱 鸿蒙
,爱糖果
,欢迎加入Harmony Candies,一起生产可爱的鸿蒙小糖果QQ群:981630644