鸿蒙元服务-开发一个简单的天气应用

举报
Damon小智 发表于 2024/12/31 21:03:31 2024/12/31
【摘要】 随着鸿蒙生态的不断完善,HarmonyOS 为开发者提供了全场景、多设备联动的能力。其中“元服务” (Service Widget 或 Ability Card) 是 HarmonyOS 特有的轻量级服务形态,可通过卡片的形式将应用的核心功能无缝呈现在多种设备上。此次,我们将以“简单天气应用”为例,展示如何利用鸿蒙元服务特性开发一款可在手机、平板、智慧屏等多种终端以卡片形式展示天气信息的应用。

随着鸿蒙生态的不断完善,HarmonyOS 为开发者提供了全场景、多设备联动的能力。其中“元服务” (Service Widget 或 Ability Card) 是 HarmonyOS 特有的轻量级服务形态,可通过卡片的形式将应用的核心功能无缝呈现在多种设备上。此次,我们将以“简单天气应用”为例,展示如何利用鸿蒙元服务特性开发一款可在手机、平板、智慧屏等多种终端以卡片形式展示天气信息的应用。


一、实现目标

我们的最终目标是实现一个天气查询卡片,用户无需进入完整应用界面,就能在主屏卡片中实时查看当前城市的天气状况、温度以及天气图标。

核心功能点:

  1. 提供当前地理位置天气查询(示例以固定城市或内置坐标为例)。
  2. 展示天气卡片:包括城市名称、当前温度、天气图标和简短描述。
  3. 支持轻量级交互,如点击卡片刷新天气。

二、开发环境准备

1. 开发工具安装

  • DevEco Studio: 华为官方提供的集成开发环境,下载地址可参考华为开发者官网。
  • HarmonyOS SDK: 可通过 DevEco Studio 内置 SDK Manager 下载对应版本的鸿蒙 SDK。
  • 开发者账号与设备(可选): 若需在真机或鸿蒙模拟器中运行,需要有华为开发者账号并启用相应权限。

2. 项目初始化

打开 DevEco Studio:

  1. 创建新工程:选择 “File” -> “New” -> “HarmonyOS Project”。
  2. 选择模板:选择 Empty Feature Ability 模板(FA 模板),这样可以方便后续创建元服务卡片。
  3. 输入项目信息,如名称:SimpleWeather,包名:com.example.simpleweather,并选择合适的 API Level。

创建完毕后,DevEco Studio 将自动生成基础的目录结构。

3. 元服务(Service Widget)配置

在鸿蒙中,元服务通常以 Ability 的形式存在,并通过 config.jsonmodule.json5 等配置文件来声明。我们需要在项目的 module.json5 中添加元服务相关的配置。

示例配置(请根据实际版本和目录结构微调):


{
  "module": {
    "type": "entry",
    "name": "entry",
    "abilities": [
      {
        "name": "WeatherServiceAbility",
        "type": "service",
        "skills": [],
        "forms": [
          {
            "name": "WeatherWidget",
            "description": "Display simple weather info",
            "dimensions": [
              {
                "id": 1,
                "width": 2,
                "height": 2
              }
            ],
            "defaultDimension": 1,
            "jsComponent": true
          }
        ]
      }
    ]
  }
}


这里声明了一个 Service Ability(WeatherServiceAbility)和对应的一项元服务卡片(WeatherWidget)。


三、代码实现

1. 数据来源与网络请求

天气数据可以通过公开的天气 API 获取,如 OpenWeatherMap(需注册获取 API Key)。为简化演示,这里假定我们有一个简单的 API 调用函数。

entry/src/main/js/default/common/utils/weatherRequest.js 文件中编写:


import fetch from '@ohos.net.fetch';

const API_URL = "https://api.openweathermap.org/data/2.5/weather?q=Beijing&units=metric&appid=YOUR_API_KEY";

export async function getWeatherInfo() {
  try {
    const response = await fetch.fetch(API_URL);
    const json = await response.json();
    return {
      city: json.name,
      temp: Math.round(json.main.temp),
      description: json.weather[0].description,
      icon: json.weather[0].icon
    };
  } catch (e) {
    console.error("Failed to fetch weather:", e);
    return null;
  }
}

2. 卡片布局编写

在鸿蒙中,元服务卡片使用 Declarative UI 或 XML 布局。以 Declarative UI 为例,在 entry/src/main/js/default/pages/CardForm.js 中:


import { getWeatherInfo } from '../common/utils/weatherRequest.js'

export default {
  data: {
    city: "Loading...",
    temp: "--",
    description: "N/A",
    iconUrl: ""
  },
  onInit() {
    this.loadWeather();
  },
  async loadWeather() {
    const info = await getWeatherInfo();
    if(info) {
      this.city = info.city;
      this.temp = info.temp + "°C";
      this.description = info.description;
      // 使用OpenWeatherMap的图标链接
      this.iconUrl = `http://openweathermap.org/img/wn/${info.icon}@2x.png`;
    }
  },
  refresh() {
    this.loadWeather();
  }
}


对应的 UI 布局文件(entry/src/main/js/default/pages/CardForm.hml)示例:


<template>
  <div class="container">
    <div class="city">{{city}}</div>
    <image src="{{iconUrl}}" class="icon"/>
    <div class="temp">{{temp}}</div>
    <div class="desc">{{description}}</div>
    <button class="refresh-btn" @click="refresh">刷新</button>
  </div>
</template>


样式文件(CardForm.css)简单示例:


.container {
  flex-direction: column;
  justify-content: center;
  align-items: center;
}
.city {
  font-size: 24px;
  margin-bottom: 10px;
}
.temp {
  font-size: 40px;
  font-weight: bold;
  margin-top: 10px;
}
.desc {
  font-size: 18px;
  margin-top: 5px;
}
.icon {
  width: 50px;
  height: 50px;
  margin: 10px;
}
.refresh-btn {
  margin-top: 15px;
  padding: 10px;
  background-color: #5B8FF9;
  color: #ffffff;
  border-radius: 5px;
}


3. Ability 与 Card 关联

entry/src/main/js/default/app.js 中注册卡片路由:


export default {
  onCreate() {
    console.info('Application onCreate');
  },
  onDestroy() {
    console.info('Application onDestroy');
  }
}


entry/src/main/js/default/ability/WeatherServiceAbility.js 中,创建 service ability 并注册卡片数据源:


import Ability from '@ohos.application.Ability'

export default class WeatherServiceAbility extends Ability {
    onCreate(want, launchParam) {
        console.info('WeatherServiceAbility onCreate');
    }

    onRequestForm(formId, formParams) {
        console.info('WeatherServiceAbility onRequestForm');
        // 返回卡片页面
        return {
            template: 'CardForm'
        };
    }
}


确保在 module.json5 配置中已指定 WeatherServiceAbility 所提供的卡片模板为 CardForm


四、调试与部署

1. 模拟器调试

DevEco Studio 提供 HarmonyOS 模拟器或者可以连接鸿蒙设备。点击运行按钮选择合适的设备即可部署运行。
成功后,在主屏添加卡片,在可用卡片列表中应能看到 “SimpleWeather” 的卡片,添加后显示实时天气信息。

2. 真机调试

将鸿蒙手机或平板通过 USB 连接到开发电脑,开启开发者模式。在 DevEco Studio 中选择目标设备为真实硬件,部署运行。


五、常见问题与解决方案


天气数据无法获取?

    • 检查网络权限与 API Key 是否正确,以及设备是否能够访问外网。
    • 在 module.json5 中添加网络权限声明。

卡片无法正常显示布局?

    • 确保 CardForm.hml、CardForm.css、CardForm.js 文件路径和命名与配置中一致。
    • 检查 WeatherServiceAbility 的 onRequestForm 方法返回的模板名称是否正确。

刷新不生效?

    • 查看 loadWeather 方法是否正确刷新 data 数据。
    • 确保 button 的点击事件被正确绑定。
【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。