当前位置: 首页 > news >正文

HarmonyOS 超级终端与服务卡片开发:打造无缝多设备交互体验

HarmonyOS 超级终端与服务卡片开发:打造无缝多设备交互体验 #星光不负码向未来#

参与#星光不负码上未来#征文活动

欢迎继续探索 HarmonyOS 进阶系列!在上篇《HarmonyOS 分布式与 AI 集成》中,我们实现了跨设备同步的智能备忘录应用。本篇将深入探讨 HarmonyOS 的超级终端(Super Device)服务卡片(Service Widget),通过一个 跨设备协作的音乐播放器应用,展示如何利用超级终端实现设备间无缝连接,并通过服务卡片提供快捷交互入口,带来流畅的鸿蒙生态体验。

本文基于 HarmonyOS NEXT API 12+,使用 ArkTSDevEco Studio 2025,结合 超级终端 API服务卡片框架,实现音乐播放器的多设备协同和卡片化交互。让我们开始吧!


前置准备

工具版本要求下载链接
DevEco Studio2025.1+华为开发者官网
JDK17内置于 DevEco Studio
HarmonyOS 设备手机/平板/手表/车机华为 Mate 60 / MatePad / Watch 4 / AITO M9
模拟器API 12+DevEco Studio 内置
HMS Core SDK6.13+自动集成

项目结构

music-player-app
├── entry/src/main/ets
│   ├── MainAbility
│   │   ├── pages
│   │   │   ├── Player.ets
│   │   │   └── Settings.ets
│   │   ├── services
│   │   │   └── MusicSyncService.ets
│   │   └── widgets
│   │       └── MusicWidget.ets
│   └── resources
│       └── base
│           └── media
│               └── icon.png
├── module.json5
└── build-profile.json5

安装环境

  • 安装 DevEco Studio:从 华为开发者官网 下载。
  • 配置模拟器:Tools > Device Manager > Create Simulator(支持手机/平板/手表)。
  • 验证:运行默认 “Hello World” 项目,确保模拟器或设备正常连接。

步骤 1:配置超级终端权限

module.json5 中添加超级终端和媒体相关权限:

{"module": {"name": "entry","type": "entry","mainElement": "MainAbility","deviceTypes": ["phone","tablet","wearable","car"],"requestPermissions": [{"name": "ohos.permission.DISTRIBUTED_DEVICE_STATE_CHANGE","reason": "$string:permission_device_state_reason","usedScene": {"abilities": ["MainAbility"],"when": "always"}},{"name": "ohos.permission.MEDIA_LOCATION","reason": "$string:permission_media_reason"}],"metaData": {"customizeData": [{"name": "Widget","value": "com.example.musicplayerapp.widgets.MusicWidget"}]}}
}

说明

  • DISTRIBUTED_DEVICE_STATE_CHANGE:监听设备连接状态。
  • MEDIA_LOCATION:访问音乐文件。
  • metaData:注册服务卡片。

步骤 2:实现超级终端协同(分布式设备管理)

MusicSyncService.ets 中实现设备发现与音乐播放同步:

// entry/src/main/ets/MainAbility/services/MusicSyncService.ets
import deviceManager from '@ohos.distributedHardware.deviceManager'
import distributedData from '@ohos.data.distributedData'
import { BusinessError } from '@kit.BasicServicesKit'class MusicSyncService {private deviceManager: deviceManager.DeviceManager | null = nullprivate kvStore: distributedData.KVStore | null = nullprivate readonly STORE_ID = 'music_player_store'async init(context: any): Promise<void> {try {// 初始化设备管理this.deviceManager = await deviceManager.createDeviceManager(context.bundleName)this.deviceManager.on('deviceStateChange', (data) => {console.info(`Device ${data.deviceId} ${data.deviceState === 1 ? 'online' : 'offline'}`)})// 初始化分布式存储const kvManager = distributedData.createKVManager({ context, bundleName: context.bundleName })this.kvStore = await kvManager.getKVStore(this.STORE_ID, {createIfMissing: true,autoSync: true})} catch (error) {console.error(`Init failed: ${(error as BusinessError).message}`)}}async syncPlaybackState(state: PlaybackState): Promise<void> {if (!this.kvStore) returnawait this.kvStore.put('playback_state', JSON.stringify(state))}async getPlaybackState(): Promise<PlaybackState | null> {if (!this.kvStore) return nullconst state = await this.kvStore.get('playback_state')return state ? JSON.parse(state) : null}async getAvailableDevices(): Promise<deviceManager.DeviceInfo[]> {if (!this.deviceManager) return []return await this.deviceManager.getTrustedDeviceList()}
}interface PlaybackState {trackId: stringposition: numberisPlaying: boolean
}export const musicSyncService = new MusicSyncService()

亮点

  • 动态监听设备状态,实时更新可用设备列表。
  • 使用 KVStore 同步播放状态(如曲目、进度、播放/暂停)。

步骤 3:实现音乐播放器 UI

Player.ets 中实现响应式播放器界面:

// entry/src/main/ets/MainAbility/pages/Player.ets
import media from '@ohos.multimedia.media'
import router from '@ohos.router'@Entry
@Component
struct Player {@State playbackState: PlaybackState = { trackId: 'track1', position: 0, isPlaying: false }@State devices: deviceManager.DeviceInfo[] = []private audioPlayer: media.AVPlayer | null = nullaboutToAppear() {musicSyncService.init(this.context)this.loadDevices()this.initPlayer()this.loadPlaybackState()}async loadDevices() {this.devices = await musicSyncService.getAvailableDevices()}async loadPlaybackState() {const state = await musicSyncService.getPlaybackState()if (state) {this.playbackState = state}}async initPlayer() {this.audioPlayer = await media.createAVPlayer()this.audioPlayer.on('play', () => {this.playbackState.isPlaying = truemusicSyncService.syncPlaybackState(this.playbackState)})this.audioPlayer.on('seekDone', (position) => {this.playbackState.position = positionmusicSyncService.syncPlaybackState(this.playbackState)})}build() {Column() {Text(`Now Playing: ${this.playbackState.trackId}`).fontSize(20).fontWeight(FontWeight.Bold).margin(10)Progress(this.playbackState.position, 100).width('80%').margin(10)Row() {Button(this.playbackState.isPlaying ? 'Pause' : 'Play').fontSize(18).backgroundColor(this.playbackState.isPlaying ? '#F44336' : '#4CAF50').onClick(() => {this.playbackState.isPlaying ? this.audioPlayer?.pause() : this.audioPlayer?.play()})Button('Settings').fontSize(18).backgroundColor('#2196F3').onClick(() => {router.pushUrl({ url: 'pages/Settings' })})}.justifyContent(FlexAlign.SpaceBetween).width('100%')List() {ForEach(this.devices, (device: deviceManager.DeviceInfo) => {ListItem() {Text(device.deviceName).fontSize(16)}})}.margin(10)}.width('100%').padding(20).backgroundColor('#F5F5F5')}
}

说明

  • 使用 @ohos.multimedia.media 播放音频。
  • 响应式 UI,支持手机、平板、车机等设备。

音乐播放器界面
图源:华为开发者社区 - 音乐播放器 UI 示例


步骤 4:实现服务卡片

MusicWidget.ets 中实现桌面服务卡片:

// entry/src/main/ets/MainAbility/widgets/MusicWidget.ets
import formBindingData from '@ohos.app.form.formBindingData'@Component
struct MusicWidget {@State playbackState: PlaybackState = { trackId: 'track1', position: 0, isPlaying: false }build() {Column() {Text(this.playbackState.trackId).fontSize(14).fontWeight(FontWeight.Medium)Button(this.playbackState.isPlaying ? 'Pause' : 'Play').fontSize(12).width(80).height(30).onClick(() => {this.playbackState.isPlaying = !this.playbackState.isPlayingmusicSyncService.syncPlaybackState(this.playbackState)})}.width(160).height(100).backgroundColor('#FFFFFF')}
}export default {onCreate() {const formData = {trackId: 'track1',isPlaying: false}return formBindingData.createFormBindingData({ data: formData })},onUpdate(formId: string) {// 更新卡片状态},onDestroy(formId: string) {// 清理资源}
}

说明

  • 服务卡片支持桌面快捷交互。
  • 通过 formBindingData 动态更新卡片内容。

步骤 5:构建与多设备调试

  1. 构建 HAP 包

    • Build > Build Hap > Generate Signed Hap。
    • 输出 entry.hapform.hap(服务卡片)。
  2. 多设备部署

    • 手机/平板:通过 DevEco Studio 直接安装。
    • 手表/车机:使用远程调试(Tools > Remote Device)。
    • 验证超级终端:确保设备通过华为账户绑定在同一局域网。
  3. 测试协同

    • 在手机上播放/暂停音乐,观察手表卡片和车机界面同步。
    • 检查日志:Tools > Logcat,过滤 “MusicSyncService”。

进阶与最佳实践

  • 性能优化

    • 缓存播放状态:
      @StorageLink('playbackCache') playbackState: PlaybackState
      
  • 错误处理

    • 添加重试机制:
      async syncPlaybackState(state: PlaybackState, retries: number = 3): Promise<void> {for (let i = 0; i < retries; i++) {try {await this.kvStore.put('playback_state', JSON.stringify(state))return} catch (error) {console.error(`Retry ${i + 1}: ${(error as BusinessError).message}`)}}
      }
      
  • 卡片动态更新

    • 使用 FormProvider 推送更新:
      import FormProvider from '@ohos.app.form.FormProvider'
      FormProvider.updateForm(formId, formBindingData.createFormBindingData({ data }))
      
  • 资源推荐

    • 华为开发者官网 - 超级终端
    • Gitee - HarmonyOS 开源项目
    • B站教程:“HarmonyOS 超级终端开发实战”

总结

通过本篇,你掌握了:

  • 超级终端:实现手机、手表、车机间的音乐播放同步。
  • 服务卡片:提供桌面快捷交互入口。
  • 多设备适配:响应式 UI 适配不同设备。

下一期预告:《HarmonyOS 云服务与推送通知》——让你的应用随时与用户保持连接!

有问题?欢迎在评论区交流!喜欢请点赞分享~

(最后更新:2025 年 10 月 24 日)

http://www.dtcms.com/a/523607.html

相关文章:

  • TeamViewer 手机版:一键远程控制,深度管理,提升多设备管理效率
  • Day70 基于 Mailbox 机制的多线程传感器数据处理系统设计与实现
  • ORM 使用说明
  • 为什么要做手机网站百媚导航app入口app入口
  • 第八章-Tomcat调试与监控
  • 算法基础篇(8)贪心算法
  • 第二章-Tomcat核心架构拆解
  • 带你深度了解作用域和闭包
  • 【Mac下通过Brew安装Ollama 】部署 DeepSeek 轻量模型(实测版)
  • 微信网站用什么语言开发wordpress4.9.4 安装
  • 如何在百度提交自己的网站简要列举网站常见类型
  • 机器视觉HALCON:5.图像标定
  • 【跟小嘉学习JavaWeb开发】第三章 从数据类型说起
  • CTF WEB入门 爆破篇
  • NAT网络地址转换
  • 【自然语言处理】预训练01:词嵌入(word2vec)
  • 利用inscode帮我用前端页面展示分析博客数据
  • 「赤兔」Chitu 框架深度解读(十):任务调度与并发控制策略
  • Java CompletableFuture 详解与实战:让异步编程更优雅
  • 建设外贸网站要多少钱建设局办的焊工证全国通用吗
  • Linux_基础IO(2)
  • Docker 中使用Nginx 一个端口启动多个前端项目
  • S9 顺序队列
  • 函数绑定器 std::bind
  • STM32基本定时器
  • 第9部分-性能优化、调试与并发设计模式
  • 编程素养提升之EffectivePython(Builder篇)
  • Vue 3 + TypeScript 项目性能优化全链路实战:从 2.1MB 到 130KB 的蜕变
  • 网站首页图腾讯 云上做网站教程
  • Ubuntu(Linux)安装更好用的中文输入法