鸿蒙 5 开发宝藏案例分享 --- 快捷触达的骑行体验
鸿蒙宝藏案例详解:共享单车“丝滑”骑行体验的代码实现 🚲💻
大家好!上次分享了鸿蒙那个超棒的共享单车体验案例,很多朋友留言说想看代码细节。没问题!这就带大家深入代码层,看看那些“丝滑”的体验(扫码直达、实时状态窗、路径规划)到底是怎么敲出来的。官方文档有时像藏宝图,代码才是真金白银!
核心目标再强调: 用 HarmonyOS 的
Scan Kit(扫码直达)、Map Kit(找车导航)、Live View Kit(实况窗)三大能力,把扫码->解锁->骑行->还车->支付的流程做到极简、实时、无感。
🎯 模块一:扫码直达解锁页 (Scan Kit)
目标: 用户在任何地方扫码,直接跳转到该单车的解锁确认页,跳过打开 App、找入口的步骤。
关键代码详解 (TypeScript/ArkTS)
代码解析 & 关键点:
权限申请 (
module.json5): 扫码必须的相机权限!必须在配置文件声明:
ScanOptions配置灵活:scanTypes: 指定识别的码类型,非常灵活。enableMultiMode: 是否一次扫多个码(共享单车通常不需要,关掉更快)。enableAlbum: 是否允许从相册选择二维码图片(重要!用户可能截图扫码)。
startScanForResult: 这是启动扫码的核心 API,返回一个Promise。.then()里处理成功结果,.catch()处理失败。结果处理 (
result):result.scanType: 识别出的码类型(二维码?条形码?)。result.value: 扫码得到的数据字符串(通常包含单车唯一 ID、解锁指令等)。这个例子简化了,实际业务中这里会解析result.value获取单车信息!状态管理 (
AppStorage): 鸿蒙提供的应用级状态管理。这里设置CYCLING_STATUS = WAITING_UNLOCK,告诉应用“用户扫到码了,等待确认解锁”。这个状态会被解锁页面使用。
router.pushUrl: 实现“直达”的关键! 直接路由导航到解锁确认页pages/ConfirmUnlock。用户瞬间从扫码界面跳到了解锁按钮面前,省去所有中间步骤。通常会把单车 ID 等信息通过params传递过去:router.pushUrl({ url: 'pages/ConfirmUnlock', params: { bikeId: parsedBikeId } })。
调用时机: 在你的首页(Index)、共享单车功能页(BikePage),甚至一个桌面万能卡片(Card)的按钮点击事件里,调用ScanUtil.scan(this)即可触发扫码。
🗺️ 模块二:智能找车与步行导航 (Map Kit)
目标: 在“找车”页面,显示用户位置、车辆位置,并绘制步行路线。
关键代码详解 (地图初始化、定位、路径规划与绘制)
代码解析 & 关键点:
权限 (
module.json5): 定位权限同样必须声明:
MapComponent: 地图的 UI 组件。mapCallback在地图加载完成后触发,此时才能安全地获取mapController进行操作。定位流程 (
enableMyLocation):setMyLocationEnabled(true): 让地图显示用户位置蓝点。getCurrentLocation: 获取一次精确位置。对于持续追踪,需用on('locationChange')监听。坐标转换 (
convertCoordinate): 非常重要! 设备 GPS 返回的是 WGS84 坐标,国内地图服务(如 GCJ02)需要转换才能准确显示。路径规划 (
getWalkingRoutes):调用
navi.getWalkingRoutes(params)是核心。传入起点(origins)、终点(destination)、类型(WALKING)。返回的
RouteResult包含路线信息,其中overviewPolyline是一串压缩过的经纬度点,用于绘制路线。绘制路线 (
addPolyline):使用
mapController.addPolyline(options)绘制折线。options.points传入路线规划得到的坐标点数组 (overviewPolyline需要先解码,示例代码假设MapUtil.walkingRoutes内部或返回结果已处理)。通过
width,color等属性定制路线外观。交互流程: 用户点击地图 -> 获取点击点坐标 -> 清除旧数据 -> 添加新 Marker -> 规划并绘制到该 Marker 的步行路线。
✨ 模块三:实况窗展示骑行状态 (Live View Kit)
目标: 解锁后,在状态栏(胶囊)、通知中心、锁屏实时显示骑行状态/时长/费用;还车后变待支付;支付后结束。
关键代码详解 (创建、更新、销毁实况窗)
代码解析 & 关键点:
LiveViewDataBuilder: 构建实况窗数据的核心工具。它定义了:主信息 (
primary): 标题、内容文本/颜色、点击动作(WantAgent)、卡片布局(LayoutData)、锁屏扩展能力名/参数/图片。胶囊态 (
capsule): 状态栏显示的图标、背景色、文字。其他: 显示时长(
keepTime)、是否持久化等。状态管理: 实况窗内容不是静态的!
updateLiveView方法根据业务状态 (RIDING,WAITING_PAYMENT,PAYMENT_COMPLETED) 动态更新liveViewData的各个部分,然后调用update()或stop()刷新界面。
WantAgent: 实现点击交互的关键! 定义了用户点击实况窗(胶囊或卡片)后要执行的动作。最常见的就是跳转回 App 的特定页面(如骑行页、支付页)。wantAgent模块用于构建这个意图。
LiveNotification: 负责实况窗的生命周期管理 (create,update,stop)。.from(context, env)将实况窗与特定的业务环境(env)关联起来。沉浸态锁屏实况窗 (高级):
在
LiveViewDataBuilder中配置setLiveViewLockScreenAbilityName和setLiveViewLockScreenPicture。实现一个继承自
LiveViewLockScreenExtensionAbility的 Ability。在
onSessionCreate方法中,使用session.loadContent('你的自定义UI页面路径')加载你用 ArkUI 编写的自定义锁屏卡片界面。这让你可以展示比默认模板更丰富的信息(比如地图缩略图、更详细的费用明细)。声明扩展 Ability (
module.json5):
服务开通: 使用实况窗能力前,需要在
AppGallery Connect后台为你的应用开通Live View Kit服务权益。
📌 总结与思考
把这三块核心代码串起来,就构成了那个“丝滑”骑行体验的骨架:
ScanUtil.scan() 被调用 -> 扫码成功 ->router.pushUrl直达解锁页。用户点击解锁 -> 调用
LiveViewController.startLiveView() 创建实况窗 (显示骑行中)。骑行中









评论