做鸿蒙应用调试的人,几乎绕不开一个环节:把手上这台真机登记到 AGC 后台的设备列表里。标题里这个"鸿蒙篇-获取不同型号的UDID,在 AppGallery Connect 中添加设备",说的就是这件事——先从每一台真机上把 64 位十六进制的设备唯一标识(UDID)取出来,再回到应用市场分发平台的开发者后台(下文统一简称 AGC)把它录进调试设备白名单,然后重新生成一张绑定这批设备的调试 profile,工程才可能把包装到真机上。听起来只有三步,但实际动手时会发现坑比想象中多:手机、平板、折叠屏取值的命令不一样,老固件和新固件bm get的参数不一样,Windows 和 macOS 的驱动情况不一样,Studio 自动签名和手动签名各自还有一套缓存逻辑。这篇文章面向刚上手的开发者,也面向被设备列表反复折腾过的老手,把取 UDID、录设备、换 profile、排故障这整条链路拆开讲清楚,参数怎么给、命令怎么敲、报错从哪儿查,都尽量写到可以直接照做的程度。
1. 先把机制想明白:为什么调试必须绑定设备
1.1 调试签名机制到底在卡什么
很多人第一次遇到"这台设备不在证书允许的列表里"这类提示时,第一反应是代码或权限配置写错了,其实跟业务代码一点关系都没有。鸿蒙的应用在真机上安装,走的是签名校验链路:开发者证书(.cer)证明"这个包是谁签的",Profile(HarmonyAppProvision,工程里常见的 .p7b 文件)证明"这个包被允许装到哪些设备上、能开哪些受限能力"。调试类型的 Profile 里有一份设备白名单,安装时的校验逻辑会把当前设备的 UDID 拿出来,跟白名单做比对,不在名单里就直接拒绝安装。这个设计的目的很简单:防止有人拿着你的调试证书给任意设备刷包。所以"取 UDID → 录进后台 → 重新下发 Profile"不是形式主义,它是签名链上真正生效的一环。
我见过太多人卡在这一步:后台明明已经把设备加进去了,工程里还是装不上,最后发现是本地那份 .p7b 还是旧的。设备列表是上游数据,Profile 是下游产物,后台改了列表不会自动覆盖你硬盘上那份文件,必须重新生成、重新下载、替换工程里的旧文件。这条因果关系记牢,后面大半的坑都能自己定位。
1.2 UDID、OAID、AAID、SN 到底该用哪个
这是新手最容易混的一组概念,必须掰开说。UDID是设备级唯一标识,由系统在设备生产或首次初始化时生成,用于签名校验、设备管理这类开发环节,一串十六进制字符,结构上比较稳定。OAID是广告标识,用户可以在设置里重置,面向广告归因场景。AAID是应用匿名标识,跟着应用和账号走。SN是硬件序列号,属于生产制造环节的编号,用户可见但格式因机型而异。
它们几个的用法边界很清楚:进 AGC 设备列表填的必须是 UDID,填 OAID 或 SN 一律校验不过。而如果在业务代码里想做"统计新增设备"这类需求,规范做法是用 OAID 或 AAID,而不是把 UDID 写进埋点——UDID 属于设备标识信息,涉及个人信息保护要求,能不能采集、采集后存哪儿、留多久,都得按隐私声明来,别图省事直接当业务主键用。
注意:签名用的 UDID 是给后台和构建工具用的,不是给业务代码用的。这两件事的边界一旦模糊,后面合规审查会很麻烦。
1.3 模拟器和真机的区别,先别浪费时间
本地模拟器(Emulator)跑的是虚拟设备,它不参与设备白名单校验,你不需要为模拟器申请任何 UDID,也不需要在 AGC 里加它。模拟器能装的包和真机能装的包在签名要求上不完全一样,很多人第一次在模拟器上跑得很顺,一插真机就报错,就是没意识到这是两套环境。我的习惯是:界面和交互逻辑先在模拟器上跑,一旦要验证推送、地图、蓝牙、相机、支付、账号登录这类依赖真实硬件或真实签名的能力,立刻切真机,别在模拟器上跟一个永远不存在的硬件较劲。
2. 动手前的准备:工具、账号、手机三件事
2.1 命令行工具从哪儿来,别单独去下
取 UDID 用的工具是hdc(HarmonyOS Device Connector),它跟 Android 生态里的 adb 是同一类东西,作用是与设备建立调试通道。最省事的获取方式是直接从 DevEco Studio 的安装目录里拿,它自带的版本一定和你的 SDK 匹配,路径通常在 Studio 安装目录下的sdk/default/openharmony/toolchains/里,Windows 上是hdc.exe,macOS 和 Linux 上是hdc。
我为什么强调"别单独去下"?因为 hdc 的客户端和服务端有版本匹配要求,你在网上随手抓一个版本,很可能跟设备固件里的 hdcd 对不上,表现出来就是hdc list targets永远是空列表,或者连上了但shell开头的命令全部超时。这种问题最难查,因为没有任何一条报错会直接告诉你"版本不匹配"。
配置环境变量的思路很简单,把 toolchains 目录加到 PATH 里,打开终端敲:
hdc -v能打出带版本号的输出就说明通了。我一般还会顺手确认一下:
hdc list targets没连设备时它返回[Empty]或者一行空提示,这是正常的,不是报错。
2.2 账号和项目权限的最小准备
AGC 后台的设备管理和证书管理是挂在具体项目、具体应用下面的,所以在加设备之前,你得先有一个可用的开发者账号,并且在对应项目里有管理权限。团队协作场景下常见的问题是:设备列表在 A 同学账号下维护,B 同学拿着同一个工程的代码却怎么也装不上,因为 B 用的是自己的账号自动签名,签名体系压根不是一套。这种时候要么统一到同一个账号,要么把证书和 Profile 文件共享给团队并在工程里手动配置。
手动签名需要的文件清单我列一下,缺一样都配不起来:
| 文件类型 | 作用 | 从哪儿来 |
|---|---|---|
| .p12 密钥库 | 存放私钥,签名时用来算签名值 | 后台生成并下载,密码自己记住 |
| .cer 数字证书 | 与 .p12 配对,公钥部分 | 后台申请后下载 |
| .p7b / HarmonyAppProvision | 绑定设备列表和受限权限 | 后台生成调试 Profile 后下载 |
| 密钥库密码 / 别名 | 签名配置项 | 生成 p12 时自己设定 |
这四个东西是绑定的,换任何一个都得重配,别混着用不同批次下载的文件,这是很隐蔽的错误来源。
2.3 手机端必须打开的开关顺序
不同型号的鸿蒙设备,打开开发者选项的路径基本一致,但按钮文案会有细微差别,我按实际点击顺序说:
- 进"设置",滑到最下面找"关于本机"(部分机型叫"关于手机"或"关于设备")。
- 找到"版本号"这一行,连续点击 7 次,中途会弹出输入锁屏密码的提示,输对了继续点。
- 系统提示"您已处于开发者模式",回到设置主界面,在"系统"或"系统和更新"下面就能看到"开发者选项"。
- 进"开发者选项",打开"USB 调试"。
- 如果要做性能分析或安装调试,再顺手打开"仅充电模式下允许 ADB 调试"这类开关——这一项特别容易被忽略。
第 5 步是我踩过最多次的坑。鸿蒙设备默认 USB 连接方式是"仅充电",这个模式下调试通道可能起不来,hdc list targets就是空的。你需要下拉通知栏,把 USB 连接方式改成"传输文件"或"传输照片",再重新执行命令。有些人会在开发者选项里打开"仅充电模式下允许调试",这是另一种解法,两者选一个能通就行。
插上数据线之后,手机上会弹一个"是否允许 USB 调试"的授权框,一定要点"允许",并且勾上"始终允许",不然后面每次重连都要重新授权。点了"取消"的话,命令行会显示设备存在但状态异常,这种状态俗称未授权。
3. 不同型号抓 UDID 的完整实操
3.1 通用三步走:连上、认出来、取到值
不管什么型号,核心就三步,我把它们写成一套可以闭眼执行的流程。
第一步,确认物理连接。数据线很关键,我吃过太多亏了——很多随设备附带的线是纯充电线,没有数据线芯,插上去只充电不识别。换一根确定能传数据的线,走 USB 直连,中间不要接扩展坞、不要接 USB Hub,那些东西在部分机型上会掉设备。
第二步,确认被识别:
hdc list targets正常应该看到一个设备标识,通常是一串字母数字的组合,例如FMR0224C22000123这种形态。如果返回[Empty],说明没识别到;如果返回的设备标识后面带Unauthorized,说明识别到了但没授权,回手机上点允许。
第三步,取值:
hdc shell bm get --udid输出通常只有一行,形如:
udid of current device is : 4A1B2C3D4E5F60718293A4B5C6D7E8F90A1B2C3D4E5F60718293A4B5C6D7E8F9后面那串就是你要的东西。复制的时候注意两点:一是把udid of current device is :这行前缀去掉,只留十六进制串;二是别把换行和空格带进去,粘贴到后台输入框里之后手动看一眼首尾有没有多余空白。
如果你手上是较早固件的设备,--udid这个参数可能不被识别,会提示参数错误,那就换成短参数:
hdc shell bm get -u这两个命令输出内容一致,区别只是参数写法。实测下来,新固件两种都能用,老固件优先用-u。我一般先试--udid,报参数错误立刻换-u,不用纠结。
顺手可以把设备信息一起记下来,填后台的时候方便备注:
hdc shell param get const.product.model hdc shell param get const.product.devicetype hdc shell param get const.ohos.apiversion第一条给你设备型号,第二条给你设备类型(phone、tablet、wearable、tv 之类),第三条给你系统 API 版本。这几条信息在排查"为什么这台设备装不上"的时候价值很高,建议养成随手记录的习惯。
3.2 手机、平板、折叠屏、穿戴设备的差异点
普通手机是最顺的,上述流程基本一次通过。需要注意的只有 USB 连接模式和授权弹窗。
平板的差异点在于部分型号的调试开关位置略有不同,"仅充电模式下允许调试"这项可能不在开发者选项里,而是在开发者选项的下一级菜单。另外平板的 USB 口规格不一样,有些是 USB-C 有些是老接口,线材一定要对。平板还有个隐藏问题:部分平板的 USB 口在充电底座上,底座本身不传数据,必须插机身口。
折叠屏是相对特殊的一类。展开态和折叠态在系统上报的设备类型可能不同,取值本身不受影响(UDID 是设备级的,不会因为形态变化而变),但你在后台备注的时候要想清楚写哪一型。我遇到过折叠屏在折叠状态下调试通道偶发断开的情况,展开之后恢复,这种大概率是系统在形态切换时的电源策略导致的,遇到就先展开重试,别一上来就怀疑签名。
穿戴设备走的是另一套配对逻辑,通常需要通过手机端的调试桥接或者专用的调试工具连,不能直接用数据线插电脑 USB 口。这类设备的调试通道建立比较麻烦,我建议先把手机真机跑通,穿戴设备留到有必要的时候再折腾。
智慧屏 / 车机这类形态一般在开发者选项里直接提供了调试授权,连接方式可能是网络调试而不是 USB,具体看你手上设备提供的选项。如果需要网络调试,hdc支持通过hdc tconn <ip>:<port>建立连接,但前提是设备端已经开好了对应的调试监听,这一步各厂商的开放程度不一样。
3.3 Windows、macOS、Linux 三端的连接差异
Windows上报的坑最多。最常见的是驱动没装好,设备管理器里能看到一个带黄色感叹号的未识别设备。这时候不需要去找什么特殊驱动包,装好 DevEco Studio 完整环境之后,驱动通常随环境一起装上了;如果还不行,重新插拔一次让系统重新识别,或者换个 USB 口(优先机箱后面的直连口,别用前面板)。Windows 上另外一个高频问题是端口占用,某些手机助手类软件会抢调试连接,导致 hdc 抢不到设备,把这类软件退干净再试。
macOS是最省心的,基本免驱,插上就行。唯一需要注意的是新版系统对 USB 配件的授权提示,弹出来要允许,否则系统层面就拦住了。另外 macOS 上如果装了多个 hdc 版本,which hdc确认一下用的是哪一个,别用了旧版本还在那儿猜设备有问题。
Linux上需要处理的是设备访问权限。普通用户默认没有 USB 设备节点的读写权限,表现出来就是能列出设备但操作全失败。常规做法是加一条 udev 规则,把厂商 ID 加进白名单,然后重新加载规则、重新插拔设备。这一步的具体写法跟你手上设备的厂商 ID 有关,我不在这里写死,思路就是"给这个设备的 USB 节点一个普通用户可读写的权限",网上通用模板很多,照抄改字段即可。还有一个常被忽略的点:Linux 上这些规则改完之后不重新插拔是不生效的,改完必须拔了重插。
4. 在 AGC 后台把设备录进去
4.1 设备列表、证书、Profile 三者的关系
进后台之前先建立一张心智图,不然点着点着就迷路。在 AGC 的设备管理里,你维护的是一份调试设备清单,每台设备一条记录,字段主要是设备名称和一个 UDID。这份清单本身不产生任何效果,它只有在被引用的时候才有意义——申请调试证书时,后台会基于当时的设备清单生成一份 Profile,这份 Profile 里就包含了白名单快照。
所以完整链条是:设备清单 → 生成调试证书 Profile → 下载到本地 → 配置进工程 → 重新编译安装。任何一环断了都会失败。最常见的断点在最后一环:后台加了设备,但没有重新生成 Profile,本地工程用的还是老文件,装的时候照样被拒。记住"改列表必重发 Profile"这条铁律。
注意:设备清单变更后,不是"下次生成时生效"这么宽松,而是必须主动重新生成一次。有些人按了保存就走了,以为自动同步,第二天来装还是失败。
4.2 添加设备的界面操作与填写规范
进后台的路径大致是:登录开发者账号 → 选择目标项目 → 选择目标应用 → 进入证书、APP ID 与 Profile 管理区域 → 找到设备管理 → 新增设备。
新增的时候要填两项:设备名称和 UDID。
- 设备名称:这是给人看的备注,随便填,但要填得有信息量。我的命名习惯是"型号-用途-持有人",比如
平板-测试-组内A。团队协作时这个字段能省下大量沟通成本,千万别图省事全填"手机1""手机2",过两周谁都不知道哪台是哪台。 - UDID:粘贴刚才命令行取到的那串十六进制,不要带 0x 前缀,不要带空格,不要手动改大小写。系统对格式校验很严格,多一个字符就过不了。
这里有个很多人问过的细节:UDID 通常是小写十六进制,但如果你从某些地方复制到的是大写形式,粘贴进去大概率也能识别,因为校验的核心是数值而不是大小写。不过为了稳妥,我建议统一按命令行原样复制,不做任何人工加工,减少变量。
另一个常见提示是"该设备已存在"。这说明这个 UDID 已经被录入过了,不需要重复操作,直接去生成 Profile 就行。如果团队里多人维护,建议先查一下现有列表再新增,避免重复记录导致后面统计混乱。
设备数量是有上限的。单个调试证书能绑定的设备数量各时期规则不同,量级上通常在百台左右,具体以上传时控制台的提示为准。这个限制不是刁难人,它的目的是防止调试证书被滥用成分发渠道。我建议团队里做定期清理:项目结束、设备淘汰、外借归还,都顺手把没用的记录删掉。限流压顶的时候再清理,往往正好卡在发版前夜,很难受。
4.3 Profile 重新生成与工程侧同步
设备录完之后,回到证书与 Profile 管理区,找到当前使用的调试 Profile,重新生成一份(新申请或者更新都行),然后下载到本地,文件名一般是.p7b。
工程侧的配置在build-profile.json5里,signingConfigs节点下会有证书路径、Profile 路径、密钥库路径、别名和密码这几项。手动签名需要把新下载的.p7b路径替换进去,注意相对路径的基准目录,很多人填了绝对路径在自己机器上跑得好好的,一提交代码别人就构建失败。
如果你用的是 Studio 的自动签名,流程会简单一些:登录账号之后,工具会自动在后台创建或更新证书和 Profile,并且同步到本地。但自动签名也有缓存,改动设备列表之后,我一般会做这几件事:断开设备重新插上、在签名配置里重新触发一次自动签名、清理工程重新构建。最保险的做法是看工程目录里那份 .p7b 的修改时间,如果时间没变,说明根本没更新,怎么构建都是白搭。
Profile 更新之后还要确认一件事:旧的 HAP 必须先卸载。签名变了但包名没变的情况下,有些机型会保留旧的应用数据,导致装上去跑的还是旧逻辑。卸载命令:
hdc uninstall <你的包名>然后重新安装:
hdc install <你的hap文件路径>看到类似install bundle successfully的输出才算真的成功。
5. 常见问题与排查速查表
5.1 连不上、认不出、取不到值
这一类问题的排查顺序一定要固定,从物理层往上查,别一上来就怀疑代码。
| 现象 | 最可能的原因 | 处理动作 |
|---|---|---|
hdc list targets返回空 | 线是充电线 / USB 模式是仅充电 / 驱动未装 | 换数据线、下拉通知栏改传输模式、检查设备管理器 |
| 设备出现但带 Unauthorized | 手机上的调试授权弹窗被拒了 | 拔插重连,手机上点允许并勾选始终允许 |
bm get --udid提示参数错误 | 固件版本较老,不认长参数 | 改用hdc shell bm get -u |
| 命令执行后长时间无输出 | hdc 客户端与设备端版本不匹配 | 换用 Studio 自带 toolchains 里的 hdc |
| 换个 USB 口就好了 | 前面板供电或信号不稳 | 优先用机箱后置直连口,去掉扩展坞 |
| 插上就断、反复重连 | 手机助手类软件抢占调试通道 | 退出所有同类软件后重试 |
我个人的固定动作是:先跑hdc kill清掉后台残留的服务进程,再hdc start重启,然后hdc list targets。这一套下来能解决大约七成的"莫名其妙连不上"。很多人不知道 hdc 是有服务端常驻进程的,进程卡死之后客户端怎么调都是空的,重启一下就好。
还有一种情况值得单说:设备列表里能看到两台设备。这通常是你之前用网络调试连过一台,tconn建立的连接还在,跟当前 USB 设备并存了。清理办法是hdc tconn断开那个网络连接,或者直接重启 hdc 服务。
5.2 装不上、签名报警
这一类问题的关键词是"设备不在列表内""签名校验失败""profile 与设备不匹配"。按下面顺序查:
- 核对 UDID 有没有录错。最常见的低级错误,取的那台设备跟插的那台不是同一台,尤其是桌上摆着好几台测试机的时候。对照一下命令行实时取的值和后台记录的值,一位一位看过去。
- 确认 Profile 是新的。看工程里
.p7b文件的修改时间,比设备录入时间早,那肯定没更新。 - 确认工程里指向的是新文件。有时候文件下载了,
build-profile.json5里还指着旧路径,尤其是复制粘贴配置的时候。 - 确认签名体系一致。同一台设备,A 同学用自动签名能装,B 同学手动签名装不上,大概率是两人用的证书不是一套。
- 确认包类型。调试包和正式包走的校验不一样,别拿调试证书去签一个准备走内部测试分发的包,那套流程的校验点更多。
补一句很多人忽略的:内部测试分发场景下,设备也需要进入对应的测试设备清单,否则测试人员下载安装会失败。这个和开发调试是两条独立的清单,别以为录进调试列表就通了。
5.3 几条踩出来的经验
别用自己主力机做唯一测试机。调试证书的有效期、设备列表的变更、反复卸载安装,都折腾得很,主力机上更容易出问题。备一台专门的测试机,插上就调,省心。
建立一份团队设备台账。一份表格,记设备名、UDID、型号、API 版本、当前归属。有人离职、有人换机、项目结项,都更新一次。这份台账在你要清理设备上限、或者排查"到底谁签的包"的时候,价值极高。我见过太多团队在发版前一天才发现设备列表已经满了,然后开始回忆哪台是两年前的旧机器。
不要把 UDID 当业务 ID 用。前面说过一次,这里再强调一次。业务埋点用 OAID 或 AAID,这是数据合规的基本盘。UDID 只出现在签名和设备管理这些开发环节,一旦你把它写进上报字段,后面整改起来非常痛苦。
定期检查 hdc 的版本一致性。团队里每个人机器上的 hdc 版本最好统一。有人从 Studio 里拿,有人从别处拿,出现"我这能连你那不能连"时,排查成本极高。我现在的做法是在项目文档里固定写上 hdc 的绝对路径,所有人用同一份。
改动之后先清理再构建。签名相关的改动,清掉build目录重新构建,能避免很多"改了没生效"的假象。构建缓存有时候会把旧的签名产物留下来。
模拟器解决不了的问题,别在模拟器上耗。一定要用真机验证的第一时间就切,一天时间花在模拟器上找一个永远找不到的硬件问题,是最不划算的。
最后说一个我最近才养成的习惯:每拿到一台新测试机,第一件事不是装应用,而是插上电脑把型号、API 版本、UDID 三条信息一次性记进台账,然后立刻去后台录进去。这样等到真正调试的时候,插上就能跑,不用再经历一次"线不对、驱动没装、授权没点"的完整流程。重复劳动能省则省,把时间留给真正需要思考的地方。