写点什么

【拥抱鸿蒙】HarmonyOS 实现扫码安装

作者:郑知鱼
  • 2025-05-26
    湖北
  • 本文字数:16541 字

    阅读完需:约 54 分钟

【拥抱鸿蒙】HarmonyOS实现扫码安装

问题

鸿蒙包的分发无法像安卓包那样仅提供一个 apk 文件的下载地址就可以安装。


一段时间以来,鸿蒙包安装仅依赖华为官方提供的工具链hdc,这需要鸿蒙设备借助数据线连接到能运行hdc命令的电脑,再使用命令行或者 DevEco 安装,安装过程过于繁琐,不方便内部测试。

解决方案

近期,华为官方新增了“内部测试”的 Profile,用于内部测试阶段分发。



我们很容易可以发现,新增的“内部测试”类型区别于“发布”和“调试”类型,这其中必然有其原因。


这个新增的描述文件类型不禁让我联想到 iOS App 的 Ad-hoc 分发方式,仔细翻阅华为官方文档后印证了我的想法。这正是为方便内部测试设计的便捷安装方式,即用“内部测试”描述文件进行签名的 App,通过相应的配置,可以实现测试人员在鸿蒙设备的浏览器打开一个网页点击安装即可下载安装。


操作文档见:HarmonyOS应用内部测试

限制与流程

限制

  • 内部测试版本有效期当前为 90 天,目前仅支持 HarmonyOS 5.0.4(16)及以上系统版本。

  • 内部测试可将应用分发到指定设备上,原理是利用设备 UDID 对设备进行授权,只有已授权设备才允许安装和使用应用。而 AGC(AppGallery Connect)上每个账号可添加的设备数量为 100,因此内部测试最多可安装到 100 台设备上。

  • 当前 HarmonyOS 应用内部测试仅支持企业开发者,这里的企业开发者是区别于个人开发者而言的,而不是所谓的企业签账号(In-house)。

流程

“内部测试”分发的流程如下所示



包含申请发布证书、注册测试设备、申请内部测试 Profile、配置签名信息、编译打包应用、上传应用包至服务器、生成应用描述并上传服务器、构造 DeepLink 等八个步骤。


前三个步骤需要在 AGC 上进行操作,可参考官方文档进行配置即可。后五个步骤以及需要注意的点我将下面列出,供大家参考。


  1. 配置签名信息需要在签名配置中分别选择在 AGC 上申请“内部测试”的 Profile 文件(.p7b)和发布证书文件(.cer)。



  1. 在 product 设置中选择 Build Mode 为 release 并 Apply,再 build 出 hap 包。



  1. 需要将编译得到的各个 hap 包、icon、以及对应的 manifest.json5 上传至服务器或第三方云上,下载 URL 必须以“https”开头。

  2. manifest.json5 文件中packageHash的值用于验证 hap 包的完整性。MAC 上需要通过shasum工具生成:shasum -a 256 [path-to-hap];Windows 系统下可通过certutil -hashfile [path-to-hap] SHA256命令获取。

  3. manifest.json5 文件中sign的值用于校验描述文件签名。需要使用internal-testing工具获取,该工具提供了.bat 文件可以直接在 Windows 系统设备的终端中运行:


manifest-sign.bat -operation sign -mode localjks -inputFile D:\old.json5 -outputFile D:\new.json5 -keystore D:\enterprise.p12 -keystorepasswd 123456 -keyaliaspasswd 123456 -privatekey enterprise
复制代码


在 Mac 系统中,需要在终端运行如下命令:


java -jar ./manifest-sign-tool-1.0.0.jar -operation sign -mode localjks -inputFile ./old_manifest.json5 -outputFile ./manifest.json5 -keystore sign/cxy.p12 -keystorepasswd xxx -keyaliaspasswd xxx -privatekey xxx
复制代码


  1. 配置完 json5 文件后,我们还需要验证签名,以免安装时报错,这里同样需要用到internal-testing工具,其对应参数如下。


-operation verify -inputFile D:\new.json5 -keystore D:\enterprise.p12 -keystorepasswd 123456
复制代码


运行后如提示“verify success”则说明验签成功,可以使用。


  1. 如何生成"https"开头的下载 URL 呢?我们可以将对应的 app.hap、icon.png、manifest.json5 以及下载引导页面 index.html 文件上传到 CDN 服务器上,这样就满足要求啦。


效果如下图所示:



生成一个加载 html 文件 URL 的二维码,就可以实现内部测试分发啦🌈


我是郑知鱼🐳,欢迎大家讨论与指教。


如果你觉得有所收获,也请点赞👍🏻收藏⭐️关注🔍我吧~~


最后,附上示例的 manifest.json5 和 index.html 以供参考。


  • manifest.json5


{  "app": {    "bundleName": "com.xxx.app.huawei",    "bundleType": "app",    "versionCode": 1,    "versionName": "1.0.0",    "label": "XXX",    "deployDomain": "xxx.com",    "icons": {      "normal": "https://xxx.com/common/ohos/test/xxx/icon-normal.png",      "large": "https://xxx.com/common/ohos/test/xxx/icon-large.png"    },    "minAPIVersion": "5.0.5(17)",    "targetAPIVersion": "5.0.5(17)",    "modules": [      {        "name": "module1",        "type": "entry",        "deviceTypes": [          "phone"        ],        "packageUrl": "https://xxx.com/common/ohos/test/xxx/app.hap",        "packageHash": "fd3206de9ead9dd9d6dd020335114ebf2f408436acc92c0950a2516f11a26f46"      }    ]  },  "sign": "MEUCIBEcU8O31W3nNCmOM81131gu97W7q/PSN1SpfBoJuFlmAiEAhhbG8FTUfmjNnu55wHZmHE+90zEasvDNeO5l2/vbp8s="}
复制代码


  • index.html


<!doctype html><html><head><meta charset='UTF-8'><meta name='viewport' content='width=device-width initial-scale=1'><link href='https://fonts.loli.net/css?family=PT+Serif:400,400italic,700,700italic&subset=latin,cyrillic-ext,cyrillic,latin-ext' rel='stylesheet' type='text/css' /><style type='text/css'>html {overflow-x: initial !important;}:root { --bg-color: #ffffff; --text-color: #333333; --select-text-bg-color: #B5D6FC; --select-text-font-color: auto; --monospace: "Lucida Console",Consolas,"Courier",monospace; --title-bar-height: 20px; }.mac-os-11 { --title-bar-height: 28px; }html { font-size: 14px; background-color: var(--bg-color); color: var(--text-color); font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; }body { margin: 0px; padding: 0px; height: auto; inset: 0px; font-size: 1rem; line-height: 1.42857143; overflow-x: hidden; background-image: inherit; background-size: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: inherit; tab-size: 4; background-position: inherit; background-repeat: inherit; }iframe { margin: auto; }a.url { word-break: break-all; }a:active, a:hover { outline: 0px; }.in-text-selection, ::selection { text-shadow: none; background: var(--select-text-bg-color); color: var(--select-text-font-color); }#write { margin: 0px auto; height: auto; width: inherit; word-break: normal; word-wrap: break-word; position: relative; white-space: normal; overflow-x: visible; padding-top: 36px; }#write.first-line-indent p { text-indent: 2em; }#write.first-line-indent li p, #write.first-line-indent p * { text-indent: 0px; }#write.first-line-indent li { margin-left: 2em; }.for-image #write { padding-left: 8px; padding-right: 8px; }body.typora-export { padding-left: 30px; padding-right: 30px; }.typora-export .footnote-line, .typora-export li, .typora-export p { white-space: pre-wrap; }.typora-export .task-list-item input { pointer-events: none; }@media screen and (max-width: 500px) {   body.typora-export { padding-left: 0px; padding-right: 0px; }  #write { padding-left: 20px; padding-right: 20px; }  .CodeMirror-sizer { margin-left: 0px !important; }  .CodeMirror-gutters { display: none !important; }}#write li > figure:last-child { margin-bottom: 0.5rem; }#write ol, #write ul { position: relative; }img { max-width: 100%; vertical-align: middle; image-orientation: from-image; }button, input, select, textarea { color: inherit; font-family: inherit; font-size: inherit; font-style: inherit; font-variant-caps: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; }input[type="checkbox"], input[type="radio"] { line-height: normal; padding: 0px; }*, ::after, ::before { box-sizing: border-box; }#write h1, #write h2, #write h3, #write h4, #write h5, #write h6, #write p, #write pre { width: inherit; }#write h1, #write h2, #write h3, #write h4, #write h5, #write h6, #write p { position: relative; }p { line-height: inherit; }h1, h2, h3, h4, h5, h6 { break-after: avoid-page; break-inside: avoid; orphans: 4; }p { orphans: 4; }h1 { font-size: 2rem; }h2 { font-size: 1.8rem; }h3 { font-size: 1.6rem; }h4 { font-size: 1.4rem; }h5 { font-size: 1.2rem; }h6 { font-size: 1rem; }.md-math-block, .md-rawblock, h1, h2, h3, h4, h5, h6, p { margin-top: 1rem; margin-bottom: 1rem; }.hidden { display: none; }.md-blockmeta { color: rgb(204, 204, 204); font-weight: 700; font-style: italic; }a { cursor: pointer; }sup.md-footnote { padding: 2px 4px; background-color: rgba(238, 238, 238, 0.7); color: rgb(85, 85, 85); border-top-left-radius: 4px; border-top-right-radius: 4px; border-bottom-right-radius: 4px; border-bottom-left-radius: 4px; cursor: pointer; }sup.md-footnote a, sup.md-footnote a:hover { color: inherit; text-transform: inherit; text-decoration: inherit; }#write input[type="checkbox"] { cursor: pointer; width: inherit; height: inherit; }figure { overflow-x: auto; margin: 1.2em 0px; max-width: calc(100% + 16px); padding: 0px; }figure > table { margin: 0px; }tr { break-inside: avoid; break-after: auto; }thead { display: table-header-group; }table { border-collapse: collapse; border-spacing: 0px; width: 100%; overflow: auto; break-inside: auto; text-align: left; }table.md-table td { min-width: 32px; }.CodeMirror-gutters { border-right-width: 0px; background-color: inherit; }.CodeMirror-linenumber { }.CodeMirror { text-align: left; }.CodeMirror-placeholder { opacity: 0.3; }.CodeMirror pre { padding: 0px 4px; }.CodeMirror-lines { padding: 0px; }div.hr:focus { cursor: none; }#write pre { white-space: pre-wrap; }#write.fences-no-line-wrapping pre { white-space: pre; }#write pre.ty-contain-cm { white-space: normal; }.CodeMirror-gutters { margin-right: 4px; }.md-fences { font-size: 0.9rem; display: block; break-inside: avoid; text-align: left; overflow: visible; white-space: pre; background-image: inherit; background-size: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: inherit; position: relative !important; background-position: inherit; background-repeat: inherit; }.md-fences-adv-panel { width: 100%; margin-top: 10px; text-align: center; padding-top: 0px; padding-bottom: 8px; overflow-x: auto; }#write .md-fences.mock-cm { white-space: pre-wrap; }.md-fences.md-fences-with-lineno { padding-left: 0px; }#write.fences-no-line-wrapping .md-fences.mock-cm { white-space: pre; overflow-x: auto; }.md-fences.mock-cm.md-fences-with-lineno { padding-left: 8px; }.CodeMirror-line, twitterwidget { break-inside: avoid; }.footnotes { opacity: 0.8; font-size: 0.9rem; margin-top: 1em; margin-bottom: 1em; }.footnotes + .footnotes { margin-top: 0px; }.md-reset { margin: 0px; padding: 0px; border: 0px; outline: 0px; vertical-align: top; text-decoration: none; text-shadow: none; float: none; position: static; width: auto; height: auto; white-space: nowrap; cursor: inherit; line-height: normal; font-weight: 400; text-align: left; box-sizing: content-box; direction: ltr; background-position: 0px 0px; }li div { padding-top: 0px; }blockquote { margin: 1rem 0px; }li .mathjax-block, li p { margin: 0.5rem 0px; }li blockquote { margin: 1rem 0px; }li { margin: 0px; position: relative; }blockquote > :last-child { margin-bottom: 0px; }blockquote > :first-child, li > :first-child { margin-top: 0px; }.footnotes-area { color: rgb(136, 136, 136); margin-top: 0.714rem; padding-bottom: 0.143rem; white-space: normal; }#write .footnote-line { white-space: pre-wrap; }@media print {   body, html { border: 1px solid transparent; height: 99%; break-after: avoid; break-before: avoid; font-variant-ligatures: no-common-ligatures; }  #write { margin-top: 0px; padding-top: 0px; border-color: transparent !important; }  .typora-export * { -webkit-print-color-adjust: exact; }  .typora-export #write { break-after: avoid; }  .typora-export #write::after { height: 0px; }  .is-mac table { break-inside: avoid; }  .typora-export-show-outline .typora-export-sidebar { display: none; }}.footnote-line { margin-top: 0.714em; font-size: 0.7em; }a img, img a { cursor: pointer; }pre.md-meta-block { font-size: 0.8rem; min-height: 0.8rem; white-space: pre-wrap; background-color: rgb(204, 204, 204); display: block; overflow-x: hidden; }p > .md-image:only-child:not(.md-img-error) img, p > img:only-child { display: block; margin: auto; }#write.first-line-indent p > .md-image:only-child:not(.md-img-error) img { left: -2em; position: relative; }p > .md-image:only-child { display: inline-block; width: 100%; }#write .MathJax_Display { margin: 0.8em 0px 0px; }.md-math-block { width: 100%; }.md-math-block:not(:empty)::after { display: none; }.MathJax_ref { fill: currentcolor; }[contenteditable="true"]:active, [contenteditable="true"]:focus, [contenteditable="false"]:active, [contenteditable="false"]:focus { outline: 0px; box-shadow: none; }.md-task-list-item { position: relative; list-style-type: none; }.task-list-item.md-task-list-item { padding-left: 0px; }.md-task-list-item > input { position: absolute; top: 0px; left: 0px; margin-left: -1.2em; margin-top: calc(1em - 10px); border: none; }.math { font-size: 1rem; }.md-toc { min-height: 3.58rem; position: relative; font-size: 0.9rem; border-top-left-radius: 10px; border-top-right-radius: 10px; border-bottom-right-radius: 10px; border-bottom-left-radius: 10px; }.md-toc-content { position: relative; margin-left: 0px; }.md-toc-content::after, .md-toc::after { display: none; }.md-toc-item { display: block; color: rgb(65, 131, 196); }.md-toc-item a { text-decoration: none; }.md-toc-inner:hover { text-decoration: underline; }.md-toc-inner { display: inline-block; cursor: pointer; }.md-toc-h1 .md-toc-inner { margin-left: 0px; font-weight: 700; }.md-toc-h2 .md-toc-inner { margin-left: 2em; }.md-toc-h3 .md-toc-inner { margin-left: 4em; }.md-toc-h4 .md-toc-inner { margin-left: 6em; }.md-toc-h5 .md-toc-inner { margin-left: 8em; }.md-toc-h6 .md-toc-inner { margin-left: 10em; }@media screen and (max-width: 48em) {   .md-toc-h3 .md-toc-inner { margin-left: 3.5em; }  .md-toc-h4 .md-toc-inner { margin-left: 5em; }  .md-toc-h5 .md-toc-inner { margin-left: 6.5em; }  .md-toc-h6 .md-toc-inner { margin-left: 8em; }}a.md-toc-inner { font-size: inherit; font-style: inherit; font-weight: inherit; line-height: inherit; }.footnote-line a:not(.reversefootnote) { color: inherit; }.md-attr { display: none; }.md-fn-count::after { content: "."; }code, pre, samp, tt { font-family: var(--monospace); }kbd { margin: 0px 0.1em; padding: 0.1em 0.6em; font-size: 0.8em; color: rgb(36, 39, 41); background-color: rgb(255, 255, 255); border: 1px solid rgb(173, 179, 185); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; box-shadow: rgba(13, 13, 14, 0.2) 0px 1px 0px, rgb(255, 255, 255) 0px 0px 0px 2px inset; white-space: nowrap; vertical-align: middle; }.md-comment { color: rgb(162, 137, 3); opacity: 0.8; font-family: var(--monospace); }code { text-align: left; }a.md-print-anchor { white-space: pre !important; border: none !important; display: inline-block !important; position: absolute !important; width: 1px !important; right: 0px !important; outline: 0px !important; text-shadow: initial !important; background-position: 0px 0px !important; }.os-windows.monocolor-emoji .md-emoji { font-family: "Segoe UI Symbol", sans-serif; }.md-diagram-panel > svg { max-width: 100%; }[lang="flow"] svg, [lang="mermaid"] svg { max-width: 100%; height: auto; }[lang="mermaid"] .node text { font-size: 1rem; }table tr th { border-bottom-width: 0px; }video { max-width: 100%; display: block; margin: 0px auto; }iframe { max-width: 100%; width: 100%; border: none; }.highlight td, .highlight tr { border: 0px; }mark { background-color: rgb(255, 255, 0); color: rgb(0, 0, 0); }.md-html-inline .md-plain, .md-html-inline strong, mark .md-inline-math, mark strong { color: inherit; }.md-expand mark .md-meta { opacity: 0.3 !important; }mark .md-meta { color: rgb(0, 0, 0); }@media print {   .typora-export h1, .typora-export h2, .typora-export h3, .typora-export h4, .typora-export h5, .typora-export h6 { break-inside: avoid; }}.md-diagram-panel .messageText { stroke: none !important; }.md-diagram-panel .start-state { fill: var(--node-fill); }.md-diagram-panel .edgeLabel rect { opacity: 1 !important; }.md-require-zoom-fix foreignObject { font-size: var(--mermaid-font-zoom); }.md-fences.md-fences-math { font-size: 1em; }.md-fences-advanced:not(.md-focus) { padding: 0px; white-space: nowrap; border: 0px; }.md-fences-advanced:not(.md-focus) { background-image: inherit; background-size: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: inherit; background-position: inherit; background-repeat: inherit; }.typora-export-show-outline .typora-export-content { max-width: 1440px; margin: auto; display: flex; flex-direction: row; }.typora-export-sidebar { width: 300px; font-size: 0.8rem; margin-top: 80px; margin-right: 18px; }.typora-export-show-outline #write { --webkit-flex: 2; flex: 2 1 0%; }.typora-export-sidebar .outline-content { position: fixed; top: 0px; max-height: 100%; overflow: hidden auto; padding-bottom: 30px; padding-top: 60px; width: 300px; }@media screen and (max-width: 1024px) {   .typora-export-sidebar, .typora-export-sidebar .outline-content { width: 240px; }}@media screen and (max-width: 800px) {   .typora-export-sidebar { display: none; }}.outline-content li, .outline-content ul { margin-left: 0px; margin-right: 0px; padding-left: 0px; padding-right: 0px; list-style: none; }.outline-content ul { margin-top: 0px; margin-bottom: 0px; }.outline-content strong { font-weight: 400; }.outline-expander { width: 1rem; height: 1.428571429rem; position: relative; display: table-cell; vertical-align: middle; cursor: pointer; padding-left: 4px; }.outline-expander::before { content: ''; position: relative; font-family: Ionicons; display: inline-block; font-size: 8px; vertical-align: middle; }.outline-item { padding-top: 3px; padding-bottom: 3px; cursor: pointer; }.outline-expander:hover::before { content: ''; }.outline-h1 > .outline-item { padding-left: 0px; }.outline-h2 > .outline-item { padding-left: 1em; }.outline-h3 > .outline-item { padding-left: 2em; }.outline-h4 > .outline-item { padding-left: 3em; }.outline-h5 > .outline-item { padding-left: 4em; }.outline-h6 > .outline-item { padding-left: 5em; }.outline-label { cursor: pointer; display: table-cell; vertical-align: middle; text-decoration: none; color: inherit; }.outline-label:hover { text-decoration: underline; }.outline-item:hover { border-color: rgb(245, 245, 245); background-color: var(--item-hover-bg-color); }.outline-item:hover { margin-left: -28px; margin-right: -28px; border-left-width: 28px; border-left-style: solid; border-left-color: transparent; border-right-width: 28px; border-right-style: solid; border-right-color: transparent; }.outline-item-single .outline-expander::before, .outline-item-single .outline-expander:hover::before { display: none; }.outline-item-open > .outline-item > .outline-expander::before { content: ''; }.outline-children { display: none; }.info-panel-tab-wrapper { display: none; }.outline-item-open > .outline-children { display: block; }.typora-export .outline-item { padding-top: 1px; padding-bottom: 1px; }.typora-export .outline-item:hover { margin-right: -8px; border-right-width: 8px; border-right-style: solid; border-right-color: transparent; }.typora-export .outline-expander::before { content: "+"; font-family: inherit; top: -1px; }.typora-export .outline-expander:hover::before, .typora-export .outline-item-open > .outline-item > .outline-expander::before { content: '−'; }.typora-export-collapse-outline .outline-children { display: none; }.typora-export-collapse-outline .outline-item-open > .outline-children, .typora-export-no-collapse-outline .outline-children { display: block; }.typora-export-no-collapse-outline .outline-expander::before { content: "" !important; }.typora-export-show-outline .outline-item-active > .outline-item .outline-label { font-weight: 700; }.md-inline-math-container mjx-container { zoom: 0.95; }

/* meyer reset -- http://meyerweb.com/eric/tools/css/reset/ , v2.0 | 20110136 | License: none (public domain) */
@include-when-export url(https://fonts.loli.net/css?family=PT+Serif:400,400italic,700,700italic&subset=latin,cyrillic-ext,cyrillic,latin-ext);
/* =========== */
/* pt-serif-regular - latin *//* pt-serif-italic - latin *//* pt-serif-700 - latin *//* pt-serif-700italic - latin */:root { --active-file-bg-color: #dadada; --active-file-bg-color: rgba(32, 43, 51, 0.63); --active-file-text-color: white; --bg-color: #f3f2ee; --text-color: #1f0909; --control-text-color: #444; --rawblock-edit-panel-bd: #e5e5e5;
--select-text-bg-color: rgba(32, 43, 51, 0.63); --select-text-font-color: white;}
pre { --select-text-bg-color: #36284e; --select-text-font-color: #fff;}
html { font-size: 16px; -webkit-font-smoothing: antialiased;}
html, body { background-color: #f3f2ee; font-family: "PT Serif", 'Times New Roman', Times, serif; color: #1f0909; line-height: 1.5em;}
/*#write { overflow-x: auto; max-width: initial; padding-left: calc(50% - 17em); padding-right: calc(50% - 17em);}
@media (max-width: 36em) { #write { padding-left: 1em; padding-right: 1em; }}*/
#write { max-width: 40em;}
@media only screen and (min-width: 1400px) { #write { max-width: 914px; }}
ol li { list-style-type: decimal; list-style-position: outside;}ul li { list-style-type: disc; list-style-position: outside;}
ol,ul { list-style: none;}
blockquote,q { quotes: none;}blockquote:before,blockquote:after,q:before,q:after { content: ''; content: none;}table { border-collapse: collapse; border-spacing: 0;}/* styles */
/* ====== */
/* headings */
h1,h2,h3,h4,h5,h6 { font-weight: bold;}h1 { font-size: 1.875em; /*30 / 16*/ line-height: 1.6em; /* 48 / 30*/ margin-top: 2em;}h2,h3 { font-size: 1.3135em; /*21 / 16*/ line-height: 1.15; /*24 / 21*/ margin-top: 2.285714em; /*48 / 21*/ margin-bottom: 1.15em; /*24 / 21*/}h3 { font-weight: normal;}h4 { font-size: 1.135em; /*18 / 16*/ margin-top: 2.67em; /*48 / 18*/}h5,h6 { font-size: 1em; /*16*/}h1 { border-bottom: 1px solid; margin-bottom: 1.875em; padding-bottom: 0.8135em;}/* links */
a { text-decoration: none; color: #065588;}a:hover,a:active { text-decoration: underline;}/* block spacing */
p,blockquote,.md-fences { margin-bottom: 1.5em;}h1,h2,h3,h4,h5,h6 { margin-bottom: 1.5em;}/* blockquote */
blockquote { font-style: italic; border-left: 5px solid; margin-left: 2em; padding-left: 1em;}/* lists */
ul,ol { margin: 0 0 1.5em 1.5em;}/* tables */.md-meta,.md-before, .md-after { color:#999;}
table { margin-bottom: 1.5em; /*24 / 16*/ font-size: 1em; /* width: 100%; */}thead th,tfoot th { padding: .25em .25em .25em .4em; text-transform: uppercase;}th { text-align: left;}td { vertical-align: top; padding: .25em .25em .25em .4em;}
code,.md-fences { background-color: #dadada;}
code { padding-left: 2px; padding-right: 2px;}
.md-fences { margin-left: 2em; margin-bottom: 3em; padding-left: 1ch; padding-right: 1ch;}
pre,code,tt { font-size: .875em; line-height: 1.714285em;}/* some fixes */
h1 { line-height: 1.3em; font-weight: normal; margin-bottom: 0.5em;}
p + ul,p + ol{ margin-top: .5em;}
h3 + ul,h4 + ul,h5 + ul,h6 + ul,h3 + ol,h4 + ol,h5 + ol,h6 + ol { margin-top: .5em;}
li > ul,li > ol { margin-top: inherit; margin-bottom: 0;}
li ol>li { list-style-type: lower-alpha;}
li li ol>li{ list-style-type: lower-roman;}
h2,h3 { margin-bottom: .75em;}hr { border-top: none; border-right: none; border-bottom: 1px solid; border-left: none;}h1 { border-color: #c5c5c5;}blockquote { border-color: #bababa; color: #656565;}
blockquote ul,blockquote ol { margin-left:0;}
.ty-table-edit { background-color: transparent;}thead { background-color: #dadada;}tr:nth-child(even) { background: #e8e7e7;}hr { border-color: #c5c5c5;}.task-list{ padding-left: 1rem;}
.md-task-list-item { padding-left: 1.5rem; list-style-type: none;}
.md-task-list-item > input:before { content: '\221A'; display: inline-block; width: 1.25rem; height: 1.6rem; vertical-align: middle; text-align: center; color: #ddd; background-color: #F3F2EE;}
.md-task-list-item > input:checked:before,.md-task-list-item > input[checked]:before{ color: inherit;}
#write pre.md-meta-block { min-height: 1.875rem; color: #555; border: 0px; background: transparent; margin-top: -4px; margin-left: 1em; margin-top: 1em;}
.md-image>.md-meta { color: #9B5146;}
.md-image>.md-meta{ font-family: Menlo, 'Ubuntu Mono', Consolas, 'Courier New', 'Microsoft Yahei', 'Hiragino Sans GB', 'WenQuanYi Micro Hei', serif;}

#write>h3.md-focus:before{ left: -1.5rem; color:#999; border-color:#999;}#write>h4.md-focus:before{ left: -1.5rem; top: .25rem; color:#999; border-color:#999;}#write>h5.md-focus:before{ left: -1.5rem; top: .0.3135rem; color:#999; border-color:#999;}#write>h6.md-focus:before{ left: -1.5rem; top: 0.3135rem; color:#999; border-color:#999;}
.md-toc:focus .md-toc-content{ margin-top: 19px;}
.md-toc-content:empty:before{ color: #065588;}.md-toc-item { color: #065588;}#write div.md-toc-tooltip { background-color: #f3f2ee;}
#typora-sidebar { background-color: #f3f2ee; -webkit-box-shadow: 0 6px 13px rgba(0, 0, 0, 0.375); box-shadow: 0 6px 13px rgba(0, 0, 0, 0.375);}
.pin-outline #typora-sidebar { background: inherit; box-shadow: none; border-right: 1px dashed;}
.pin-outline #typora-sidebar:hover .outline-title-wrapper { border-left:1px dashed;}
.outline-item:hover { background-color: #dadada; border-left: 28px solid #dadada; border-right: 18px solid #dadada;}
.typora-node .outline-item:hover { border-right: 28px solid #dadada;}
.outline-expander:before { content: "\f0da"; font-family: FontAwesome; font-size:14px; top: 1px;}
.outline-expander:hover:before,.outline-item-open>.outline-item>.outline-expander:before { content: "\f0d7";}
.modal-content { background-color: #f3f2ee;}
.auto-suggest-container ul li { list-style-type: none;}
/** UI for electron */
.megamenu-menu,#top-titlebar, #top-titlebar *,.megamenu-content { background: #f3f2ee; color: #1f0909;}
.megamenu-menu-header { border-bottom: 1px dashed #202B33;}
.megamenu-menu { box-shadow: none; border-right: 1px dashed;}
header, .context-menu, .megamenu-content, footer { font-family: "PT Serif", 'Times New Roman', Times, serif; color: #1f0909;}
#megamenu-back-btn { color: #1f0909; border-color: #1f0909;}
.megamenu-menu-header #megamenu-menu-header-title:before { color: #1f0909;}
.megamenu-menu-list li a:hover, .megamenu-menu-list li a.active { color: inherit; background-color: #e8e7df;}
.long-btn:hover { background-color: #e8e7df;}
#recent-file-panel tbody tr:nth-child(2n-1) { background-color: transparent !important;}
.megamenu-menu-panel tbody tr:hover td:nth-child(2) { color: inherit;}
.megamenu-menu-panel .btn { background-color: #D2D1D1;}
.btn-default { background-color: transparent;}
.typora-sourceview-on #toggle-sourceview-btn,.ty-show-word-count #footer-word-count { background: #c7c5c5;}
#typora-quick-open { background-color: inherit;}
.md-diagram-panel { margin-top: 8px;}
.file-list-item-file-name { font-weight: initial;}
.file-list-item-summary { opacity: 1;}
.file-list-item { color: #777;}
.file-list-item.active { background-color: inherit; color: black;}
.ty-side-sort-btn.active { background-color: inherit;}
.file-list-item.active .file-list-item-file-name { font-weight: bold;}
.file-list-item{ opacity:1 !important;}
.file-library-node.active>.file-node-background{ background-color: rgba(32, 43, 51, 0.63); background-color: var(--active-file-bg-color);}
.file-tree-node.active>.file-node-content{ color: white; color: var(--active-file-text-color);}
.md-task-list-item>input { margin-left: -1.7em; margin-top: calc(1rem - 13px);}
input { border: 1px solid #aaa;}
.megamenu-menu-header #megamenu-menu-header-title,.megamenu-menu-header:hover, .megamenu-menu-header:focus { color: inherit;}
.dropdown-menu .divider { border-color: #e5e5e5; opacity: 1;}
/* https://github.com/typora/typora-issues/issues/2046 */.os-windows-7 strong,.os-windows-7 strong { font-weight: 760;}
.ty-preferences .btn-default { background: transparent;}
.ty-preferences .window-header { border-bottom: 1px dashed #202B33; box-shadow: none;}
#sidebar-loading-template, #sidebar-loading-template.file-list-item { color: #777;}
.searchpanel-search-option-btn.active { background: #777; color: white;}

mjx-container[jax="SVG"] { direction: ltr;}
mjx-container[jax="SVG"] > svg { overflow: visible; min-height: 1px; min-width: 1px;}
mjx-container[jax="SVG"] > svg a { fill: blue; stroke: blue;}
mjx-assistive-mml { position: absolute !important; top: 0px; left: 0px; clip: rect(1px, 1px, 1px, 1px); padding: 1px 0px 0px 0px !important; border: 0px !important; display: block !important; width: auto !important; overflow: hidden !important; -webkit-touch-callout: none; -webkit-user-select: none; -khtml-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none;}
mjx-assistive-mml[display="block"] { width: 100% !important;}
mjx-container[jax="SVG"][display="true"] { display: block; text-align: center; margin: 1em 0;}
mjx-container[jax="SVG"][display="true"][width="full"] { display: flex;}
mjx-container[jax="SVG"][justify="left"] { text-align: left;}
mjx-container[jax="SVG"][justify="right"] { text-align: right;}
g[data-mml-node="merror"] > g { fill: red; stroke: red;}
g[data-mml-node="merror"] > rect[data-background] { fill: yellow; stroke: none;}
g[data-mml-node="mtable"] > line[data-line], svg[data-table] > g > line[data-line] { stroke-width: 70px; fill: none;}
g[data-mml-node="mtable"] > rect[data-frame], svg[data-table] > g > rect[data-frame] { stroke-width: 70px; fill: none;}
g[data-mml-node="mtable"] > .mjx-dashed, svg[data-table] > g > .mjx-dashed { stroke-dasharray: 140;}
g[data-mml-node="mtable"] > .mjx-dotted, svg[data-table] > g > .mjx-dotted { stroke-linecap: round; stroke-dasharray: 0,140;}
g[data-mml-node="mtable"] > g > svg { overflow: visible;}
[jax="SVG"] mjx-tool { display: inline-block; position: relative; width: 0; height: 0;}
[jax="SVG"] mjx-tool > mjx-tip { position: absolute; top: 0; left: 0;}
mjx-tool > mjx-tip { display: inline-block; padding: .2em; border: 1px solid #888; font-size: 70%; background-color: #F8F8F8; color: black; box-shadow: 2px 2px 5px #AAAAAA;}
g[data-mml-node="maction"][data-toggle] { cursor: pointer;}
mjx-status { display: block; position: fixed; left: 1em; bottom: 1em; min-width: 25%; padding: .2em .4em; border: 1px solid #888; font-size: 90%; background-color: #F8F8F8; color: black;}
foreignObject[data-mjx-xml] { font-family: initial; line-height: normal; overflow: visible;}
mjx-container[jax="SVG"] path[data-c], mjx-container[jax="SVG"] use[data-c] { stroke-width: 3;}
g[data-mml-node="xypic"] path { stroke-width: inherit;}
.MathJax g[data-mml-node="xypic"] path { stroke-width: inherit;} :root {--mermaid-font-zoom:1em ;} @media print { @page {margin: 0 0 0 0;} body.typora-export {padding-left: 0; padding-right: 0;} #write {padding:0;}} .typora-export li, .typora-export p, .typora-export, .footnote-line {white-space: normal;}
.download-btn { display: inline-block; padding: 0.5em 1.5em; font-size: 1em; color: #fff; background: linear-gradient(90deg, #202b33 60%, #444 100%); border: none; border-radius: 2em; box-shadow: 0 2px 8px rgba(32,43,51,0.10); cursor: pointer; transition: background 0.2s, box-shadow 0.2s, transform 0.1s; font-weight: bold; letter-spacing: 0.05em; margin-top: 2.5em;}.download-btn:hover, .download-btn:focus { background: linear-gradient(90deg, #2d3a45 60%, #666 100%); box-shadow: 0 4px 16px rgba(32,43,51,0.18); transform: translateY(-2px) scale(1.03); outline: none;}</style><title>华为鸿蒙内测包下载</title> <script> function openDeepLink() { let url = 'store://enterprise/manifest?url=https://pfile2.laiyouxi.com/updategame/online/common/ios/ohos/app/laiyouxi/14/manifest.json5' window.open(url, '_parent') } </script></head><body class='typora-export'><div class='typora-export-content'><div id='write' class=''><h1 id='华为鸿蒙内测包下载'><span>华为鸿蒙内测包下载</span></h1><h2 id='XXX App【鸿蒙版】'><span>XXX App【鸿蒙版】</span></h2><ul style="margin-top:0.5em;margin-bottom:2em;padding-left:0em;"> <li>版本:1.0.0</li> <li>服务器环境:测试服</li> <li>构建序号:13</li></ul> <button class="download-btn" onclick="openDeepLink()">立即下载</button></body></html>
复制代码


发布于: 2025-05-26阅读数: 3
用户头像

郑知鱼

关注

🐳吾非鱼,亦可知鱼之乐。 2025-05-23 加入

iOS | ohos

评论

发布
暂无评论
【拥抱鸿蒙】HarmonyOS实现扫码安装_华为_郑知鱼_InfoQ写作社区