从零到一:flutter_timezone库的鸿蒙适配深度探索

2025-04-24 23:46:38
122次阅读
0个评论

从零到一:flutter_timezone库的鸿蒙适配深度探索

适配仓库地址

在数字化浪潮的推动下,跨平台开发框架如 Flutter 凭借其高效、便捷的特性,成为了开发者们的宠儿。而鸿蒙系统的崛起,更是为跨平台开发注入了新的活力。为了助力开发者在鸿蒙生态中快速实现 flutter_timezone 获取时间程序功能,本文将深入浅出地为大家解析如何适配 flutter_timezone 三方库至鸿蒙平台。

一、适配鸿蒙版 flutter_timezone 三方库

(一)版本选择与仓库简介

我们先去 pub 上查看最新版本,发现目前 pub 上最新是 1.1.4,我们选择以 1.1.4 版本为基础进行适配。flutter_timezone 是一个用于在 Flutter 应用中退出应用程序功能的插件,其 GitHub 仓库为 https://github.com/tjarvstrand/flutter_timezone ,我们的目标是将这个插件适配到鸿蒙平台。

(二)引入背景与使用场景

在 OpenHarmony 北向生态的发展过程中,许多已经适配了 Flutter 的厂商在接入 OpenHarmony 时,都希望能够继续使用 FlutterToast 来实现通知功能。因此,我们提供了这个适配方案,采用插件化的适配器模式,帮助生态伙伴快速实现产品化。

本方案适用于已经支持 Flutter 框架的设备在移植到 OpenHarmony 系统过程中,作为一个备选方案。

(三)使用文档与插件库使用

适配 OpenHarmony 平台的详细使用指导可以参考:Flutter使用指导文档

在项目中使用该插件库时,只需在 pubspec.yaml 文件的 dependencies 中新增如下配置:

dependencies:
  flutter_timezone:
    git:
      url: "https://gitcode.com/nutpi/flutter_timezone.git"
      path: ""

然后在项目根目录运行 flutter pub get,即可完成依赖添加

接下来是具体的适配过程。

二、适配过程详解

(一)准备工作

确保已经配置好了 Flutter 开发环境,具体可参考 Flutter 配置指南。同时,从 官方插件库 下载待适配的三方插件。本指导书, 以适配 fflutter_timezone 为例

image-20250417200546042

(二)插件目录结构

下载并解压插件后,我们会看到以下目录结构:

  • lib :对接 Dart 端代码的入口,由此文件接收到参数后,通过 channel 将数据发送到原生端。
  • android :安卓端代码实现目录。
  • ios :iOS 原生端实现目录。
  • example :一个依赖于该插件的 Flutter 应用程序,用于说明如何使用它。
  • README.md :介绍包的文件。
  • CHANGELOG.md :记录每个版本中的更改。
  • LICENSE :包含软件包许可条款的文件。

(三)创建插件的鸿蒙模块

在插件目录下,打开 Terminal,执行以下命令来创建一个鸿蒙平台的 Flutter 模块:

flutter create . --org net.wolverinebeach.flutter_timezone --template=plugin --platforms=ohos

步骤:

  1. 用vscode/trae打开刚刚下载好的插件。

  2. 打开Terminal,cd到插件目录下。

  3. 执行命令flutter create . --template=plugin --platforms=ohos 创建一个ohos平台的flutter模块。

(四)在根目录下添加鸿蒙平台配置

在项目根目录的 pubspec.yaml 文件中,添加鸿蒙平台的相关配置:

name: flutter_timezone
description: A flutter plugin for getting the local timezone of the device.
version: 4.1.0
homepage: https://github.com/tjarvstrand/flutter_timezone

environment:
  sdk: '>=3.4.0 <4.0.0'
  flutter: ">=3.22.0"

dependencies:
  flutter:
    sdk: flutter
  flutter_web_plugins:
    sdk: flutter

dev_dependencies:
  flutter_test:
    sdk: flutter


# The following section is specific to Flutter.
flutter:
  plugin:
    platforms:
      android:
        package: net.wolverinebeach.flutter_timezone
        pluginClass: FlutterTimezonePlugin
      ios:
        pluginClass: FlutterTimezonePlugin
      linux:
        pluginClass: FlutterTimezonePlugin
      macos:
        pluginClass: FlutterTimezonePlugin
      windows:
        pluginClass: FlutterTimezonePluginCApi
      web:
        pluginClass: FlutterTimezonePlugin
        fileName: flutter_timezone_web.dart
      ohos:
        package: net.wolverinebeach.flutter_timezone
        pluginClass: FlutterTimezonePlugin

(五)编写鸿蒙插件的原生 ArkTS模块

1. 创建鸿蒙插件模块

使用 DevEco Studio 打开鸿蒙项目。

2. 修改相关配置文件

ohos 目录内的 oh-package.json5 文件中添加 libs/flutter.har 依赖,并创建 .gitignore 文件,添加以下内容以忽略 libs 目录:

/node_modules
/oh_modules
/local.properties
/.preview
/.idea
/build
/libs
*.har
/.cxx
/.test
/BuildProfile.ets
/oh-package-lock.json5

oh-package.json5 文件内容如下:

{
  "name": "flutter_timezone",
  "version": "1.0.0",
  "description": "A flutter plugin for getting the local timezone of the device.",
  "main": "index.ets",
  "author": "nutpi",
  "license": "Apache-2.0",
  "dependencies": {
    "@ohos/flutter_ohos": "file:./har/flutter.har"
  }
}

ohos 目录下创建 index.ets 文件,导出配置:

import FlutterExitAppPlugin from './src/main/ets/components/plugin/FlutterExitAppPlugin';
export default FlutterExitAppPlugin;

3. 编写 ETS 代码

ohos的api可以参考:https://gitcode.com/openharmony/docs

以下是 FlutterTimezonePlugin.ets 文件的代码示例:

import {
  FlutterPlugin,
  FlutterPluginBinding,
  MethodCall,
  MethodCallHandler,
  MethodChannel,
  MethodResult,
} from '@ohos/flutter_ohos';
import { i18n } from '@kit.LocalizationKit';

/** FlutterTimezonePlugin **/
export default class FlutterTimezonePlugin implements FlutterPlugin, MethodCallHandler {
  private channel: MethodChannel | null = null;

  constructor() {
  }

  getUniqueClassName(): string {
    return "FlutterTimezonePlugin"
  }

  onAttachedToEngine(binding: FlutterPluginBinding): void {
    this.channel = new MethodChannel(binding.getBinaryMessenger(), "flutter_timezone");
    this.channel.setMethodCallHandler(this)
  }

  onDetachedFromEngine(binding: FlutterPluginBinding): void {
    if (this.channel != null) {
      this.channel.setMethodCallHandler(null)
    }
  }

  onMethodCall(call: MethodCall, result: MethodResult): void {
    switch (call.method) {
      case 'getLocalTimezone':
        result.success(this.getLocalTimezone());
        break;
      case 'getAvailableTimezones':
        result.success(this.getAvailableTimezones());
        break;
      case 'getPlatformVersion':
        result.success("OpenHarmony ^ ^ ")
        break;
      default:
        result.notImplemented();
    }

  }

  // 获取本地时区
  private getLocalTimezone(): string {
    const timezone = i18n.getTimeZone();
    return timezone.getID();
  }

  // 获取可用时区列表
  private getAvailableTimezones(): string[] {
    return i18n.TimeZone.getAvailableIDs();
  }
}

现在就可以正常使用啦。

三、关于鸿蒙版Flutter的 时区

这里我使用的是时区相关功能

导入模块

import { i18n } from '@kit.LocalizationKit';

开发实例

包括获取特定时区、计算固定和实际时区偏移量、获取和遍历时区列表等。

// 获取巴西时区
let timezone: i18n.TimeZone = i18n.getTimeZone('America/Sao_Paulo'); // 传入特定时区,创建时区类
let timezoneId: string = timezone.getID(); // timezoneId = 'America/Sao_Paulo'

// 获取城市Id对应的时区对象
let aucklandTimezone: i18n.TimeZone = i18n.TimeZone.getTimezoneFromCity('Auckland');
timezoneId = aucklandTimezone.getID(); // timezoneId = 'Pacific/Auckland'

// 时区的本地化名称
let timeZoneName: string = timezone.getDisplayName('zh-Hans', true); // timeZoneName = '巴西利亚标准时间'

// 本地化城市名称
let cityDisplayName: string = i18n.TimeZone.getCityDisplayName('Auckland', 'zh-Hans'); // cityDisplayName = '奥克兰 (新西兰)'

// 时区的固定偏移量
let rawOffset: number = timezone.getRawOffset(); // rawOffset = -10800000

// 时区的实际偏移量(固定偏移量+夏令时)
let offset: number = timezone.getOffset(1234567890); // offset = -10800000

// 系统支持的时区Id列表
let availableIDs: Array<string> = i18n.TimeZone.getAvailableIDs(); // availableIDs = ['America/Adak', 'Asia/Hovd', ...]

// 系统支持的时区城市Id列表
let cityIDs: Array<string> = i18n.TimeZone.getAvailableZoneCityIDs(); // cityIDs = ['Auckland', 'Magadan', ...]

// 遍历时区城市Id列表
let timezoneList: Array<object> = []; // 呈现给用户的时区列表

class Item {
  cityDisplayName: string = "";
  timezoneId: string = "";
  offset: string = "";
  cityId: string = ""
}

for (let i = 0; i < cityIDs.length; i++) {
  let cityId: string = cityIDs[i];
  let timezone: i18n.TimeZone = i18n.TimeZone.getTimezoneFromCity(cityId); // 城市Id对应的时区对象
  let cityDisplayName: string = i18n.TimeZone.getCityDisplayName(cityId, 'zh-CN'); // 本地化城市名称
  let timestamp: number = (new Date()).getTime();
  let item: Item = {
     cityDisplayName: cityDisplayName,
     timezoneId: timezone.getID(),
     offset: 'GMT' + (timezone.getOffset(timestamp) / 3600 * 1000),
     cityId: cityId
  };
  timezoneList.push(item);
}

// 指定地理坐标所在的时区对象数组
let timezoneArray: Array<i18n.TimeZone> = i18n.TimeZone.getTimezonesByLocation(-43.1, -22.5);

四、编写 Example

1. 创建 Example 应用

在插件根目录下创建一个名为 example 的文件夹,用于存放示例应用。在 example 文件夹中,创建一个鸿蒙平台的 Flutter 应用,用于验证插件功能。

2. 签名与运行

使用 Deveco Studio 打开 example > ohos 目录,单击 File > Project Structure > Project > Signing Configs,勾选 Automatically generate signature,等待自动签名完成。然后运行以下命令:

flutter pub get

 flutter build hap --debug

如果应用正常启动,说明插件适配成功。如果没有,欢迎大家联系坚果派一起支持。

五、总结

通过以上步骤,我们成功地将 flutter_timezone 三方库适配到了鸿蒙平台。这个过程涉及到了解插件的基本信息、配置开发环境、创建鸿蒙模块、编写原生代码以及测试验证等多个环节。希望这篇博客能够帮助到需要进行 flutter_timezone 鸿蒙适配的开发者们,让大家在鸿蒙生态的开发中更加得心应手。

六、参考

七、坚果派

坚果派由坚果等人创建,团队拥有若干华为HDE,以及若干其他领域的三十余位万粉博主运营。专注于分享的技术包括HarmonyOS/OpenHarmony,ArkUI-X,元服务,服务卡片,华为自研语言,BlueOS操作系统、团队成员聚集在北京、上海、广州、深圳、南京、杭州、苏州、宁夏等地。 聚焦“鸿蒙原生应用”、“智能物联”和“AI赋能”、“人工智能”四大业务领域,依托华为开发者专家等强大的技术团队,以及涵盖需求、开发、测试、运维于一体的综合服务体系,赋能文旅、媒体、社交、家居、消费电子等行业客户,满足社区客户数字化升级转型的需求,帮助客户实现价值提升。 目前上架鸿蒙原生应用18款,三方库72个。期待与大家沟通。

地址:https://atomgit.com/nutpi

https://gitcode.com/nutpi

收藏00

登录 后评论。没有帐号? 注册 一个。