HarmonyOS 扫码直达接入实战:系统扫、应用落,三步送用户进履约页 📅 发布时间:2026/9/12 21:03:47 👁 浏览次数: 本文基于 HarmonyOS 6.1 的「扫码直达」官方文档与 App Linking 接入指导整理。文中代码是为说明问题自写的完整示例不是官方示例的搬运API 名称、枚举取值与版本号等事实性信息均标注官方出处涉及真机表现的部分已明确标注未做任何实测数据编造。引子扫码之后用户落在了首页有个做本地生活的朋友跟V哥抱怨他在应用里生成了一张扫一扫点单的码发出去给用户。用户用系统的扫一扫一拍——应用是打开了但停在了启动页。点单页在哪用户得自己再点两下。他说“这码白做了。”这事V哥第一反应是是不是V哥没配对。翻完官方文档才看明白从 6.1 起系统把’扫码直达’这件事接好了大半但’扫完落在哪一页’这件事系统不知道得你告诉它。换句话说入口是系统给的落地是应用自己的活。把这两件分清楚整套能力就顺了。一、扫码直达到底是什么系统扫应用落官方的描述很直白开发者把域名注册到扫码直达服务后用户通过控制中心等系统级常驻入口扫描应用的二维码、条形码就能跳转到应用对应服务页实现一步直达接入扫码直达服务。V哥把整条链路拆成四步画成一张业务流步骤谁来做你写不写代码① 域名注册到扫码直达服务你在 AGC 开发者网站不写配② 用户从系统扫码入口发起扫码系统控制中心等不写③ 系统解析码值、查到对应应用系统不写④ 拉起应用、跳到对应服务页系统拉起 你做路由写一眼看清了吧前③步都是系统的事只有第④步的落到哪个页需要你接住码值再路由。这里有个硬边界先说在前扫码直达仅支持中国境内香港特别行政区、澳门特别行政区、中国台湾除外接入使用扫码直达 · 说明。如果你的应用做海外发行这条链路在你那不生效别硬等。二、第一步先把域名交给 App Linking扫码直达到底靠什么把码和你的应用绑在一起答案是App Linking。官方的开发准备写得很明确针对扫码直达App Linking 是必选项。你需要做四件事开发准备 · 仅针对扫码直达必选在 AGC 控制台开通 App Linking 服务在开发者网站上关联应用在 App Linking 中配置二维码、条形码关联的网址域名在应用的module.json5里关联这个域名。三个V哥自己踩过的坑提前说只能用 HTTPS 网址。App Linking 当前仅支持 HTTPSHTTP 域名直接不被接受。不能用自动签名。官方明确接入 App Linking 不能使用 DevEco 的自动签名功能必须手动签名。第一次V哥卡在这半天编译能过、扫码不跳最后发现是签名方式不对。应用未安装时码值对应的网页也得准备好。用户手机没装你的应用系统会拉起浏览器打开那个 HTTPS 页面——这是你沉默获客的兜底。V哥的判断就一句域名是门票App Linking 是那条门缝。门缝没开后面再怎么写路由都是空转。顺带说一句为什么这件事值得做扫码直达的入口是系统级的常驻入口控制中心等比你在应用里自己塞一个扫码按钮浅得多。用户不用先打开你的 App、再找扫码入口而是系统一拍、直接落到服务页。对拉新和复访来说这条路径省掉的就是那两下点击——而这恰恰是最容易流失的地方。所以域名这一步别嫌配起来麻烦。三、第二步在 EntryAbility 接住码值这一步才是真正要写代码的地方。系统拉起应用时码值那个 HTTPS 链接会落在Want的uri字段里。你要做的是在EntryAbility的两个入口都接住它冷启动走onCreate热启动走onNewWant。下面是自写的完整示例把接住码值、再跳页的逻辑收在routeByUri一处// entryability/EntryAbility.etsimport{UIAbility,Want}fromkit.AbilityKit;import{BusinessError}fromkit.BasicServicesKit;import{hilog}fromkit.PerformanceAnalysisKit;import{router,window}fromkit.ArkUI;exportdefaultclassEntryAbilityextendsUIAbility{privateuiContext?:UIContext;// 冷启动系统扫码入口拉起时码值经 App Linking 落在 want.urionCreate(want:Want):void{this.routeByUri(want);}// 热启动应用已在前台再次被扫码入口拉起onNewWant(want:Want):void{this.routeByUri(want);}onWindowStageCreate(windowStage:window.WindowStage):void{windowStage.loadContent(pages/Index);windowStage.getMainWindow().then((win:window.Window){this.uiContextwin.getUIContext();});}// 把码值 → 页面的映射收口在一处别散落到各 abilityprivaterouteByUri(want:Want):void{consturi:string|undefinedwant?.uri;if(!uri){return;}consttarget:stringScanRouter.match(uri);if(this.uiContext){conststate:router.RouterStatethis.uiContext.getRouter().getState();// 已经在目标页就不重复压栈避免用户回退时一路是同一页if(statestate.name!Access){this.uiContext.getRouter().pushUrl({url:target}).catch((err:BusinessError){hilog.error(0x0001,[ScanDirect],路由失败 code:${err.code});});}}}}这里有三个V哥自己加的细节值得单说冷、热启动都接只写onCreate应用本来就在后台时再扫一次码你收不到第二次——因为走的是onNewWant。这个坑很隐蔽不报错只是第二次扫码没反应。uiContext异步拿到getMainWindow()是 Promise页面没加载完时uiContext还是空的直接路由会空指针。教训是路由动作要等uiContext就绪。已经在目标页就别压栈不加这个判断用户连扫两次回退键要按好几下才能出去。四、第三步把码值收口成一张路由表接住uri之后最忌讳的就是在 ability 里写一堆 if-else 判断路径。码一多逻辑就糊了。V哥的做法是把路径前缀 → 目标页抽成一张规则表集中维护// common/ScanRouter.etsimport{hilog}fromkit.PerformanceAnalysisKit;import{url}fromkit.ArkTS;interfaceRouteRule{pattern:string;// 路径前缀page:string;// 目标页面desc:string;// 业务含义便于排查}exportclassScanRouter{// 码值注册到扫码直达后系统只负责把用户送到这// 具体落到哪个服务页由这张表决定 —— 别让用户停在首页privatestaticrules:RouteRule[][{pattern:/scan/pay,page:pages/Pay,desc:扫支付码 → 支付页},{pattern:/scan/order,page:pages/OrderDetail,desc:扫订单码 → 订单详情},{pattern:/scan/coupon,page:pages/Coupon,desc:扫券码 → 领券页},];staticmatch(uri:string):string{try{constpath:stringnewurl.URL(uri).pathname;for(construleofScanRouter.rules){if(path.startsWith(rule.pattern)){returnrule.page;}}}catch(err){// 解析失败别静默至少回首页也方便你定位问题hilog.error(0x0001,[ScanDirect],URI 解析异常:${err});}returnpages/Index;}}把路由收口成表好处是新增一种码只改这张表不动 ability。这是工程上最划算的一笔。五、两个验证标准装了跳履约页没装跳网页写完代码别急着上线。官方给了两条验收标准V哥建议你逐条对着查开发后验证标准类型你在验证什么应用已安装跳转体验规则必须满足扫支付码跳到支付页不是首页应用未安装跳转体验建议系统拉起浏览器打开码值对应的网页第一条是硬指标。V哥那个朋友的问题恰恰就是扫完停在首页——他压根没做路由URI 到了Want里就被忽略了。V哥的铁律履约页不是首页。扫支付码用户要的是支付不是你的启动页。断在首页就是断在体验上。第二条是兜底。没装应用的用户扫了你的码应该被引到网页完成动作或下载——这条做不好等于白白浪费一次触达。六、6.1 的增强与边界扫码直达本身依赖系统路由应用侧改动不大。但 6.1 在 Scan Kit 上确实加了料和你做扫码相关功能时能用上Scan Kit 开发详解默认界面扫码标题动态适配ScanOptions里把scanTypes限定成单一制式如只QR_CODE系统扫码页标题会自动变成扫描二维码或扫描条形码。Wearable 全支持6.1 起带后置相机的穿戴设备也能用默认/自定义界面扫码。复杂场景算法加固曲面码、小角度码、污损码、远距离小码识别率提升。但要把话说清楚这些是 Scan Kit 的增强不是扫码直达的增强。扫码直达的核心是系统扫、应用落的路由分发应用侧那三步注册域名、接住码值、路由履约页在 6.1 的主线上没变。别把两件事混成一团去讲。还有一个边界提醒扫码直达要求中国境内且必须真机验证——模拟器不支持相机相关扫码能力图像识码部分可模拟器调试完整链路必须以真机实测为准Scan Kit · 支持设备。七、上线自检清单把上面几点整理成一份可以贴进 PR 描述的清单域名已在 AGC 开通 App Linking并配置到扫码直达服务了吗module.json5里关联了正确的域名吗用的是HTTPS域名吗HTTP 不被接受用的是手动签名吗自动签名会导致扫码不跳EntryAbility的onCreate和onNewWant都接住了want.uri吗路由动作等uiContext就绪后才执行吗码值 → 页面的映射收口在一张路由表里了吗还是散落的 if-else扫支付码 / 订单码跳的是履约页而不是首页吗应用未安装时码值对应的网页能正常打开吗连续扫码会不会重复压栈已在目标页不再 push中国境内以外发行的版本有降级方案吗此能力不生效在真机上用控制中心扫码入口完整走通一遍了吗参考与出处本文涉及的事实性信息API 名称、枚举取值、版本号、官方约束来自以下官方文档文中的结构、代码示例、决策流程与自检清单为本人整理编写接入扫码直达服务Scan Kit统一扫码服务· 开发准备Scan Kit统一扫码服务开发详解App Linking 接入指导统一扫码服务ArkTSCodelab最后一句扫码直达真正难的不是代码——满打满算就三步。难的是把系统扫、应用落这件事分清楚门票域名交给 App Linking接住码值写进 EntryAbility路由履约页收成一张表。前三件做对用户一扫就到少一件用户就停在首页。