起因:一次想不起来的厦门之行

去年十一月,我站在厦门环岛路的一个拐角,忽然想不起来自己三年前来这座城市时走过哪条路、在哪个巷子里吃了那碗沙茶面。手机相册里翻了半天,只找到几张没有地理信息的食物照片。人明明去过那么多地方,但记忆像沙子一样从指缝漏掉了。

我日常出差多,一年大概飞二三十次。试过用运动类 App 记轨迹,但每次出门前要「开始记录」,到了地方还得「结束记录」,忘了就白跑一趟。那些 App 本质上是为跑步骑行设计的,拿来记通勤记旅行,像拿螺丝刀开啤酒瓶——能用,但别扭。也试过旅行平台标记去过的城市,一打开全是别人的攻略,我只想安安静静看自己的足迹。

所以那个念头反复冒出来:能不能有个东西,就只做「留痕」这一件事?不需要打卡,不需要社交,不需要写游记。我走过,它就记住了。

从想法到上架,断断续续写了两年

白天上班,晚上和周末才能写代码。最早的版本特别粗糙,就是把 GPS 坐标画在地图上,连线都没有,一堆散落的点,像地图上长了麻子。

真正花时间的是两个技术问题。

第一个:后台持续定位的功耗控制。 这个搞过移动端定位的同学都知道有多头疼。如果不做处理,后台 GPS 常驻一天手机就没电了。我前后试了七八种方案,在精度和功耗之间反复拉扯。比如在 iOS 端,最终采用的策略是根据运动状态动态切换定位精度:

// 根据活动类型动态调整定位精度
func adjustAccuracy(for activity: CMMotionActivity) {
    if activity.stationary {
            locationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters
                    locationManager.distanceFilter = 200
                        } else if activity.automotive {
                                locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters
                                        locationManager.distanceFilter = 50
                                            } else {
                                                    locationManager.desiredAccuracy = kCLLocationAccuracyBest
                                                            locationManager.distanceFilter = 10
                                                                }
                                                                }
                                                                ```
静止时大幅降低采样频率,移动时再提上来。最后做到的效果是:一整天后台运行,耗电大约在 3%5% 之间,对大部分人来说基本无感。

**第二个:轨迹的可视化渲染。** 轨迹数据本身是冷冰冰的经纬度数组,直接画出来就是一团乱麻。我花了很长时间调颜色、调线宽、调透明度,让密集的地方自然加深,偶尔路过的地方淡淡一笔。现在打开地图看自己走过的城市,有点像水墨晕开的感觉——去得多的地方颜色浓,去得少的地方颜色浅。

在鸿蒙端(HarmonyOS NEXT),地图渲染这块我用了 ArkUICanvas 组件配合 MapKit 做叠加绘制。ArkTS 的声明式 UI 在处理这种「数据驱动视图更新」的场景时确实比较顺手,轨迹数据变了,地图上的热力图自动重绘,不用手动管生命周期:

```arkts
// 轨迹热力渲染 - 根据经过次数计算透明度
@Builder
renderTrackSegment(segment: TrackSegment) {
  Polyline()
      .bindPoints(segment.points)
          .bindStrokeWidth(segment.zoomAdaptiveWidth())
              .bindStrokeColor(this.heatColor(segment.visitCount))
                  .bindOpacity(Math.min(0.3 + segment.visitCount * 0.15, 0.95))
                  }
                  ```
## 它最终长成了什么样

打开「雁过留痕」,给它定位权限之后,就没有"之后"了。没有按钮要按,没有模式要选。你该干嘛干嘛,它在后台安静地记着。

哪天你想看,点开 App,地图上你走过的街道、坐过的高铁线路、飞过的航线,都在那里。可以按时间筛选——比如只看今年去过的地方,或者只看某次旅行那几天的轨迹。

它比运动 App 更适合"非运动场景"。通勤、出差、旅行、周末瞎逛,这些日常移动不需要"开始/暂停/结束"的仪式感,它就该像呼吸一样自然地被记住。

另外一点我比较在意的:数据完全在本地。没有账号系统,没有云端同步到别人的服务器。你的行踪是你自己的事,不该被任何平台知道。

## 一个意外的玩法:城市填色

自己用了大半年之后发现了一个没预料到的东西:「密度感」带来的满足。当你看到自己住的城市,街道被你一条一条走满、地图上那片区域慢慢变"实"的时候,会有一种很安静的成就感。不是游戏里打卡集章的刺激,是一种"我确实在这里活过"的踏实。

有朋友拿去 citywalk,每次刻意选没走过的路,回来看地图上又多了一小片颜色,像慢慢填满一幅画。这个玩法我完全没设计过,但听到的时候觉得挺开心的。

## 写在最后

「雁过留痕」目前已上架 App Store,搜名字就能找到。我没有运营团队,没有推广预算,就是一个人在做这件事。

鸿蒙版本也在适配 HarmonyOS NEXT 中,ArkUI 的声明式开发体验对独立开发者还是挺友好的,后续会单独写一篇鸿蒙适配过程中踩过的坑。

如果你也在做鸿蒙开发,或者对移动端后台定位、轨迹可视化这些方向感兴趣,欢迎评论区交流。雁过留痕,痕迹在你自己手里。

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐