“每日格言”概述
“每日格言”是一个展示格言的元服务。每天格言不重复,感受文字带来的力量!
1. 项目详情及使用方式
通过滑动界面,可以刷新查看最新的格言;可以根据关键字来搜索格言;可以朗读格言的内容。每天格言不重复,感受文字带来的力量!
2. 项目的亮点
程序简洁容易操作;功能内聚;无需操作手册即可上手。
3. 功能界面展示
以下是“每日格言”元服务核心功能界面展示。
首页:各个功能的入口;可以根据关键字进行搜索。
详情:查看格言详情页;可以朗读格言。
“每日格言”核心技术分析
“每日格言”使用最新 HarmonyOS 6 开发。项目中涉及的关键技术:
- @Builder 装饰器自定义格言详情界面;
- 基于 HarmonyOS 的场景化语音服务等AI能力实现本文朗读。
1. Navigation 实现页面的切换
在主页 Index.ets 文件中,Navigation 组件用于实现页面的切换。
// 创建一个导航控制器对象并传入NavigationpageInfos: NavPathStack = new NavPathStack();build() { Navigation(this.pageInfos) { // ... } .mode(NavigationMode.Stack) .hideTitleBar(true)}
2. Grid 和 Stack 实现首页布局
Grid 和 Stack 实现首页布局。
Stack() { Image($r('app.media.bg')) .objectFit(ImageFit.Fill) .width('100%') .height('100%') Scroll() { Column() { Row() { Search({ value: this.searchContent, placeholder: '关键字搜索...', controller: this.controller }) .searchIcon(new SymbolGlyphModifier($r('sys.symbol.magnifyingglass')).fontColor([$r('app.color.main_background')])) .cancelButton({ style: CancelButtonStyle.CONSTANT, icon: new SymbolGlyphModifier($r('sys.symbol.xmark')).fontColor([Color.Green]) }) .searchButton('搜索') .width('70%') .height(40) .backgroundColor('#F5F5F5') .placeholderColor(Color.Grey) .placeholderFont({ size: 14, weight: 400 }) .textFont({ size: 14, weight: 400 }) .margin(20) .onSubmit((value: string) => { this.searchContent = value; this.doSearch(this.searchContent) }) }.width('100%') .justifyContent(FlexAlign.Start) Grid(this.scroller, this.layoutOptions) { // ... } .columnsGap(8) .rowsGap(8) .columnsTemplate('1fr') .width('100%') .height('100%') .padding({ left: 10, right: 10, bottom: 40 }) } .width('100%') .height('100%') .margin({ bottom: 10 }) }.width('100%') .scrollBar(BarState.Off)}
其中,Stack 的作用是将子组件堆叠起来,并设置堆叠顺序。在最底层,使用 Image 组件将背景图片填充到整个屏幕。 Grid 组件用于实现网格布局,并设置列数和列间距。
3. LazyForEach 实现数据懒加载
LazyForEach 组件用于实现数据懒加载。
Grid(this.scroller, this.layoutOptions) { LazyForEach(this.dataSource, (item: Poet) => { GridItem() { // 根据数据渲染格言卡片 Text(`${item.title}(${item.author})`) .width('100%') .height(28) .margin(10) .fontColor($r('sys.color.font_primary')) .fontSize(24) .maxLines(1) .textOverflow({ overflow: TextOverflow.Ellipsis }) .onClick(e => { // 切换到Detail页面 // 将name指定的NaviDestination页面信息入栈,传递的参数为item this.pageInfos.pushPathByName('PageDetail', item); console.log('切换到Detail页面'); }) } }, (item: Poet) => item.id + '' )}
懒加载组件 LazyForEach 接收两个参数:数据源和数据渲染函数。数据源是一个数组,数据渲染函数是一个函数,用于根据数据源中的数据渲染组件。
懒加载组件会根据数据源中的数据,自动创建对应的组件。这里的组件比较简单,用 Text 组件来渲染格言卡片。
格言卡片主要是显示格言的标题和作者。
点击格言卡片,会跳转到 PageDetail 页面,并显示该格言的详情。
4. @Builder 装饰器自定义格言详情界面
@Builder 装饰器用于自定义格言详情界面。
@Builderfunction TextLineBuilder(poet: Poet, color: string, index: number) { if (poet) { Stack() { Image($r('app.media.type_' + index)) .objectFit(ImageFit.Fill) .width('100%') .height('100%') Column(){ Text(poet.title) .fontSize(24) .fontWeight(FontWeight.Bold) .fontColor(color) .backgroundColor(Color.White) Text(poet.author) .fontSize(20) .fontWeight(FontWeight.Medium) .fontColor(color) .backgroundColor(Color.White) ForEach(poet.paragraphs, (paragraph: string, index: number) => { Text(paragraph) .fontSize(22) .fontWeight(FontWeight.Lighter) .fontColor(color) .backgroundColor(Color.White) }) }.width('100%') .height('100%') .justifyContent(FlexAlign.Center) } .width('100%') .height('100%') }}
上述函数同样是使用了 Stack 布局:在最底层,使用 Image 组件将背景图片填充到整个屏幕;上层是将格言的标题、作者和内容分别放在三个 Text 组件中。
5. 场景化语音服务实现本文朗读
借助 HarmonyOS 的场景化语音服务等 AI 能力,可以轻松实现本文的朗读功能。
Button('朗读').onClick(() => { // 初始化文章列表 this.readInfoList = [ { id: this.poet.id + '', title: { text: this.poet.title, isClickable: true }, author: { text: this.poet.author, isClickable: true }, bodyInfo: this.poet.paragraphs.join('\n') } ] this.selectedReadInfo = this.readInfoList[0] // 朗读控件执行朗读 TextReader.start(this.readInfoList, this.selectedReadInfo?.id) .catch((error: BusinessError) => { console.error(`start failed, code: ${error.code}, message: ${error.message}`) })}).margin(10)
从开发到上架经验总结
本节以“每日格言”应用上架为例,记录完整的鸿蒙 HamonyOS 应用上架手动签名与发布流程。
(一)上架手动签名
HarmonyOS 应用/元服务通过数字证书( .cer 文件)和 Profile 文件( .p7b 文件)来保证应用/元服务的完整性。
在申请数字证书和 Profile 文件前,首先需要通过 DevEco Studio 来生成密钥(存储在格式为 .p12 的密钥库文件中)和证书请求文件( .csr 文件)。
然后,申请调试数字证书和调试 Profile 文件。最后,将密钥( .p12 )文件、数字证书( .cer )文件和 Profile(.p7b)文件配置到工程中。
基本概念
- 密钥:格式为 .p12,包含非对称加密中使用的公钥和私钥,存储在密钥库文件中,公钥和私钥对用于数字签名和验证。
- 证书请求文件:格式为 .csr,全称为 Certificate Signing Request,包含密钥对中的公钥和公共名称、组织名称、组织单位等信息,用于向 AppGallery Connect 申请数字证书。
- 数字证书:格式为 .cer,由华为 AppGallery Connect 颁发。
- Profile 文件:格式为 .p7b,包含 HarmonyOS 应用/元服务的包名、数字证书信息、描述应用/元服务允许申请的证书权限列表,以及允许应用/元服务调试的设备列表(如果应用/元服务类型为 Release 类型,则设备列表为空)等内容,每个应用/元服务包中均必须包含一个 Profile 文件。
1. 生成密钥文件
在 DevEco Studio 中生成密钥文件。
设置存储路径:比如本例 D:\dev\harmonyos\keystore\birlower_20250916.p12
输入密码
设置别名:比如本例 birlower_20250916
2. 生成证书请求文件
基于上一步的密钥文件,生成证书请求文件。
设置存储路径:比如本例 D:\dev\harmonyos\keystore\birlower_20250916.csr
3. 新增数字证书
登录 AppGallery Connect,点击左侧导航栏的“数字证书”,点击“新增数字证书”。
填写证书信息,并上传上一步生成的证书请求文件。
证书名称:比如本例 birlower_20250916
证书类型:发布证书
下载数字证书文件到指定目录待用。
4. 添加 Profile
点击“ Profile ”,添加 Profile。
Profile 名称:birlower_20250916
类型:发布
选择证书:选择上一步新增的数字证书
下载Profile文件到指定目录待用。
5. 手动配置签名信息
在 DevEco Studio 中配置密钥( .p12 )文件、申请的调试证书( .cer )文件和调试 Profile( .p7b )文件。
在 File > Project Structure > Project > Signing Configs 窗口中,取消勾选“ Automatically generate signature ”,然后配置工程的签名信息。
Store file:选择第 1 步生成的密钥库文件,文件后缀为 .p12,该文件为生成密钥和证书请求文件中生成的 .p12 文件。
Store password:输入第 1 步的密钥库密码,该密码与生成密钥和证书请求文件中填写的密钥库密码保持一致。
Key alias:输入第 1 步的密钥的别名信息,与生成密钥和证书请求文件中填写的别名保持一致。
Key password:输入第 1 步的密钥的密码,与生成密钥和证书请求文件中填写的 Store Password 保持一致。
Sign alg:签名算法,固定为 SHA256withECDSA。
Profile file:选择第 4 步生成的申请调试证书和调试 Profile 文件中生成的 Profile 文件,文件后缀为 .p7b。
Certpath file:选择第 3 步生成的申请调试证书和调试 Profile 文件中生成的数字证书文件,文件后缀为 .cer。
(二)构建软件包
打包 APP 时,DevEco Studio 会将工程目录下的所有 HAP/HSP 模块打包到 APP 中,因此,如果工程目录中存在不需要打包到 APP 的 HAP/HSP 模块,请手动删除后再进行编译构建生成 APP。
单击 Build > Build Hap(s)/APP(s) > Build APP(s),等待编译构建完成已签名的应用包。
当未指定构建模式时,构建 APP 包,默认 Release 模式;构建 HAP/HSP/HAR 包,默认 Debug 模式。即 Build APP(s) 时,默认构建的 APP 包为 Release 类型,符合上架要求,开发者无需进行另外设置。
编译构建完成后,可以在工程目录 build > outputs > default 下,获取带签名的应用包,例如“ DailyQuotesAtomicService-default-signed.app ”。
(三)上传软件包
AGC 软件包管理,选择测试和正式上架,上述上一步的软件包“ DailyQuotesAtomicService-default-signed.app ”。
(四)分发
AGC 版本信息,软件版本选择上一步的软件版本。
正确填写应用多语言信息,有助于增加应用在应用市场曝光,输入的文字会以文本方式展示,不支持 html 标签。
设置下隐私声明,建议是使用隐私声明托管。
以上就是我元服务从开发到上架的详细过程,希望对大家有所帮助。
如果大家对鸿蒙开发感兴趣,也参与到当中来,期待与你相遇。