HarmonyOS開發實例—蜜蜂AI助手(上篇)

CSDN 2023-12-15 10:41:14
1.前言

自華爲宣布HarmonyOS NEXT全面啓動,近期新浪、B站、小紅書、支付寶等各領域頭部企業紛紛啓動鴻蒙原生應用開發。據媒體統計,如今Top20的應用裏,已經有近一半開始了鴻蒙原生應用開發。雖然目前HarmonyOS NEXT還未面向個人開發者開放,但我們可以體驗並使用最新的API9和開發工具,嘗試開發元服務,這個鴻蒙新的應用形態。體驗未來在HarmonyOS NEXT上實現的應用開發。但需要注意的是,基于API9開發的應用或元服務是不可以適配HarmonyOS NEXT版本的,大家也可以期待一下明年推出的適配HarmonyOS NEXT新版本。

本文主要是基于蜜蜂AI元服務的開發案例,主要的功能有

元服務內部功能:1、提供兩個Tabs,首頁和我的;

2、用戶只有登錄之後才可以去使用蜜蜂AI的功能;

3、目前現有的知識庫包括知識百科小助手,節日小助手,文本翻譯小助手,産品名稱小助手,以及道歉信小助手等;

4、用戶使用小助手之後,我們可以保存對話到列表內,下次快速的進行訪問。

元服務卡片:1、提供2-4的卡片,卡片界面展示每日妙語,點擊即可刷新;

2、提供1-2的卡片,實現快速訪問首頁;

3、提供2-2卡片,可以快速使用包括知識百科小助手,節日小助手,文本翻譯小助手,産品名稱小助手;

4、提供4-4卡片,可以快速到達登陸頁面,訪問小助手等。

[video(video-PvzNNP19-1702449952333)(type-csdn)(url-https://live.csdn.net/v/embed/351202)(image-https://video-community.csdnimg.cn/vod-84deb4/a04a6c72997f71ee8e134531949c0102/snapshots/35306a269ab4407d9fc2f098f42c4273-00005.jpg?auth_key=4856048370-0-0-2063e9cd3c9204fe6cb9208f14e242e0)(title-armonyOS開發實例—蜜蜂AI助手演示視頻)]

1.1 HarmonyOS

HarmonyOS是華爲公司開發的操作系統,它的設計理念是面向未來的全場景智慧體驗,可在各種設備上運行,包括手機、平板電腦、智能手表、智能音箱等。HarmonyOS采用分布式技術,可以將不同設備之間的計算資源連接起來,實現設備間的協同工作,提高系統的性能和穩定性。此外,HarmonyOS還擁有高度自適應的界面、多屏協同等特性,使用戶能夠在不同設備上實現無縫的體驗。

1.2元服務

在萬物互聯時代,人均持有設備量不斷攀升,設備和場景的多樣性,使應用開發變得更加複雜、應用入口更加多樣。在此背景下,應用提供方和用戶迫切需要一種新的服務提供方式,使應用開發更簡單、服務(如聽音樂、打車等)的獲取和使用更便捷。爲此,HarmonyOS除支持傳統方式的需要安裝的應用(以下簡稱傳統應用)外,還支持更加方便快捷的免安裝的應用(即元服務)。

1.3 介紹 AppGallery Connect(AGC)

AppGallery Connect(簡稱AGC)致力于爲應用的創意、開發、分發、運營、經營各環節提供一站式服務,構建全場景智慧化的應用生態體驗。

1.4蜜蜂 AI元服務助手背景

目前AI正火,而我自己也有辛參與到大模型的訓練中來,于是有了蜜蜂這個作品。

元服務與傳統應用對比

項目

元服務

傳統應用

軟件包形態

App Pack(.app)

App Pack(.app)

分發平台

由應用市場(AppGallery)管理和分發

由應用市場(AppGallery)管理和分發

安裝後有無桌面icon

無桌面icon,但可手動添加到桌面,顯示形式爲服務卡片

有桌面icon

HAP免安裝要求

所有HAP(包括Entry HAP和Feature HAP)均需滿足免安裝要求

所有HAP(包括Entry HAP和Feature HAP)均爲非免安裝的

新建元服務應用

開通

AI平台https://fulitimes.com/登陸賬號17752170152

https://ai.fulitimes.com/model?modelId=

如何運行

2.准備工作

2.1 HarmonyOS 應用開發環境

工欲善其事,必先利其器,我們首先要做的就是搭建開發環境

這裏面我們分爲三步走

2.1.1環境安裝

首先在這邊安裝最新的IDE:

下載鏈接:https://developer.harmonyos.com/cn/develop/deveco-studio/#download

我的是M1,所以我們下載這一個就可以

2.1.2 環境配置

下載完成之後,我們就開始配置開發環境。下載SDK及工具鏈,首次使用DevEco Studio,工具的配置向導會引導您下載SDK及工具鏈。配置向導默認下載API Version 9的SDK及工具鏈,我們選擇默認就好

下載nodejs和ohpm,記得最好HarmonyOS SDK路徑中不能包含中文字符。

下載完成之後,我們下載HarmonyOS SDK

在彈出的SDK下載信息頁面,單擊Next,並在彈出的License Agreement窗口,閱讀License協議,需同意License協議後,單擊Next。

目前最新的應該是3.2.13.5。

確認設置項的信息,點擊Next開始安裝。

等待Node.js、ohpm和SDK下載完成後,單擊Finish,界面會進入到DevEco Studio歡迎頁。

2.1.3創建 HelloWord

1.在DevEco Studio的歡迎頁,選擇Create Project開始創建一個新工程。

2.根據工程創建向導,在HarmonyOS頁簽,選擇“Empty Ability”模板,單擊Next。

3.單擊Next,各個參數保持默認值即可,單擊Finish,

2.1.4運行 Helloword

1.將搭載HarmonyOS手機與電腦連接。

2.單擊File>Project Structure >Project > SigningConfigs界面勾選“支持HarmonyOS,以及Automatically generate signature”,等待自動簽名完成即可,單擊OK。如右所示:。

3.在編輯窗口右上角的工具欄,單擊運行,等待編譯完成即可便運行在設備上。

這個時候真機就可以看到HelloWord。接下來我們就創建蜜蜂AI元服務。

2.2創建蜜蜂 AI元服務

這裏我們的模版就不再選空模板了,而是直接選擇最後一個端雲一體化模版

然後其他的就按照上面的配置就可以。完成項目的配置。

這裏有個區別就是我們需要關聯雲資源。所以我們創建的應用包名要牢記,這個要在後面我們雲端配置的時候使用。

爲工程關聯雲開發所需的資源,即在DevEco Studio中選擇您的華爲開發者賬號加入的開發者團隊,將該團隊在AGC的同包名應用關聯到當前工程,具體操作如下:

若尚未登錄 DevEco Studio,單擊“Sign in”,拉起浏覽器在彈出的賬號登錄頁面,使用已實名認證的華爲開發者賬號完成登錄。

單擊“Team”下拉框,選擇開發團隊。選中團隊後,系統根據工程包名自動查詢團隊下的同包名應用。若爲首次創建且團隊下未創建同包名的應用,則提示需要在AGC平台創建應用。

單擊“AppGallery Connect”

打開AGC

應用創建向導,填寫應用信息,單擊“

確認”

按鈕創建應用。

完成以上操作後,DevEco Studio即可獲取到同包名應用對應的項目信息。

2.3 AGC配置

我們登陸雲側,創建元服務

然後我們開通手機登陸和郵箱登錄服務。

3.實現登錄

當前AGC認證服務爲HarmonyOS應用/服務提供的登錄認證方式有手機、郵箱兩種方式。本工程使用“手機號碼+驗證碼”的方式作爲應用的登錄入口。而且我們在前面已經開通。

在登陸這一塊,用戶首次登陸的時候,我們會首先利用首選項檢查他的登陸狀態。

首選項工具類

/**

* 首選項操作類

*/

import { PreferenceDBUtil } from '../utils/PreferencesDBUtil';

const preDbService = new PreferenceDBUtil();

preDbService.getPreStorage();

export const getDBPre = async (key: string) => {

const value = await preDbService.getPreVal(key);

return value;

};

export const putDBPre = async (key: string, value: string) => {

await preDbService.putPreData(key, value);

};

然後跳用調用AGConnectAuth.requestEmailVerifyCode申請驗證碼,在entry/src/main/ets/services/Auth.ts認證工具類中添加郵箱驗證碼獲取方法。

import { MainPage } from "@hw-agconnect/auth-component-ohos"

import router from '@ohos.router'

import { LogUtil } from '../common/utils/LogUtil';

import { Constants } from '../common/Constants';

import { putPre } from '../common/service/PreService';

import { UserInfo } from '../common/UserInfo';

@Entry

@Component

struct Index {

@State icon: Resource = router.getParams()['icon'];

@State isAgreement:boolean = router.getParams()['isAgreement'];

@State agreementContent:string = router.getParams()['agreementContent'];

@State onSuccess: Function = router.getParams()['onSuccess'];

@State onError: Function = router.getParams()['onError'];

build() {

Column() {

MainPage({

icon: this.icon,

agreement: {

isAgreement: this.isAgreement,

agreementContent: this.agreementContent,

},

onSuccess: async (user) => {

LogUtil.info(`登錄用戶信息:${JSON.stringify(user)}`);

const loginUser = user['user'];

const userInfo: UserInfo = {

uid: loginUser['uid'],

email: loginUser['email'],

phone: loginUser['phone'] === undefined ? "" : loginUser['phone'].split('-')[1],

displayName: loginUser['displayName'] === undefined ? "" : loginUser['displayName'],

photoUrl: loginUser['photoUrl'] === undefined ? "/common/imgs/ic_user.svg" : loginUser['photoUrl']

}

await putPre(Constants.LOGIN_USER_KEY, JSON.stringify(userInfo));

router.back();

},

onError: (err) => {

LogUtil.error(`登錄用戶信息:${JSON.stringify(err)}`);

}

})

}

}

aboutToAppear() {

}

}

未登錄彈窗

/***未登錄彈窗*/importcommonfrom'@ohos.app.ability.common';importrouterfrom'@ohos.router';import{ GlobalConstant }from'../common/constants/GlobalConstant';@CustomDialogexportstruct LoginTipDialogView {loginTipCtrl:CustomDialogController;build() {Column({space:GlobalConstant.SIZE_8}) {Row({space:GlobalConstant.SIZE_4}) {Image($r('app.media.ic_tip')).width(GlobalConstant.SIZE_32).height(GlobalConstant.SIZE_32)Text('溫馨提示').fontSize($r('app.float.font_size_24')).fontColor($r('app.color.tip_color')).fontWeight(FontWeight.Bolder)}.width(GlobalConstant.PAGE_FULL).height(GlobalConstant.SIZE_64).padding({left:GlobalConstant.SIZE_16})Text('您還未登錄,請登錄後體驗功能!').height(GlobalConstant.SIZE_48).fontSize(Color.Black).fontSize($r('app.float.font_size_18')).fontWeight(FontWeight.Normal)Row({space:GlobalConstant.SIZE_8}) {Button('退出',{type:ButtonType.Normal}).borderRadius(GlobalConstant.SIZE_4).backgroundColor($r('app.color.embellishment_color')).fontColor($r('app.color.text_color_9')).onClick(()=>{constctx=getContext(this)ascommon.UIAbilityContext;ctx.terminateSelf();})Button('去登錄',{type:ButtonType.Normal}).borderRadius(GlobalConstant.SIZE_4).backgroundColor($r('app.color.embellishment_color')).fontColor($r('app.color.auxiliary_color')).onClick(()=>{this.loginTipCtrl.close();router.pushUrl({params:{isAgreement:true,agreementContent:"",icon:"",type:["HWID_VERIFY_CODE","PHONE"]},url:'@bundle:com.jianguo.ai/common/ets/LoginComponent/LoginPage',})})}.width(GlobalConstant.PAGE_FULL).justifyContent(FlexAlign.Center)}.width(GlobalConstant.PAGE_96).padding({bottom:GlobalConstant.SIZE_20}).borderRadius(GlobalConstant.SIZE_16).backgroundColor(Color.White)}}

4.實現蜜蜂 AI助手頁面

我們這個應用主要的一個功能就是AI助手,所以這一塊我們分爲三塊。

4.1蜜蜂 AI列表頁

關于列表頁,我們使用一個列表就可以

/***首頁*/import{ ConfigConstant }from'../common/constants/ConfigConstant'import{ GlobalConstant }from'../common/constants/GlobalConstant'import{ AiAppConfig }from'../common/dto/AiAppConfig';importrouterfrom'@ohos.router'import{ getDBPre }from'../common/api/PreDbService';@Componentexportstruct HomeView {@StateaiAppList:Array<AiAppConfig>=ConfigConstant.DEFAULT_AI_APP_LIST;}build() {Column() {List() {ForEach(this.aiAppList,(item:AiAppConfig)=>{ListItem() {Row({space:GlobalConstant.SIZE_8}) {Row() {Image(item.avatar).width(GlobalConstant.SIZE_64).height(GlobalConstant.SIZE_64).borderRadius(GlobalConstant.SIZE_32)}.height(GlobalConstant.PAGE_FULL).layoutWeight(1)Column({space:GlobalConstant.SIZE_16}) {Text(item.name).fontSize($r('app.float.font_size_18'))Text(item.intro).fontSize($r('app.float.font_size_14')).fontColor($r('app.color.text_color_9'))}.height(GlobalConstant.PAGE_FULL).layoutWeight(3).justifyContent(FlexAlign.Center).alignItems(HorizontalAlign.Start)}.width(GlobalConstant.PAGE_96).height(GlobalConstant.SIZE_100).paddingStyle().borderRadius(GlobalConstant.SIZE_16).shadow({radius:GlobalConstant.SIZE_16,color:$r('app.color.main_color')}).onClick(()=>{router.pushUrl({url:"pages/detail/index",params:{"AiAppConfig":item}})})}.width(GlobalConstant.PAGE_FULL).paddingStyle().borderRadius(GlobalConstant.SIZE_16)})}.listDirection(Axis.Vertical)}.width(GlobalConstant.PAGE_FULL).height(GlobalConstant.PAGE_FULL).padding(GlobalConstant.SIZE_8)}}

效果圖

4.2 對話頁

關鍵代碼

build() {Column({space:GlobalConstant.SIZE_8}) {Stack({alignContent:Alignment.Bottom}) {Column() {Column({space:GlobalConstant.SIZE_4}) {Text("蜜蜂AI助手").fontSize($r('app.float.font_size_16')).fontColor(Color.Black).fontWeight(FontWeight.Bolder)Text("介紹").fontSize($r('app.float.font_size_12')).fontColor($r('app.color.text_color_9')).fontWeight(FontWeight.Lighter)}.width(GlobalConstant.PAGE_FULL).justifyContent(FlexAlign.Center).padding({top:GlobalConstant.SIZE_4,bottom:GlobalConstant.SIZE_8})Scroll() {Column({space:GlobalConstant.SIZE_8}) {ForEach(this.chatContentArr,(chat:ChatInfo)=>{if(chat.role==="assistant") {Row() {Row({space:GlobalConstant.SIZE_8}) {Image(chat.avatar).width(GlobalConstant.SIZE_24).height(GlobalConstant.SIZE_24)Row() {Text(chat.content).fontSize($r('app.float.font_size_14')).fontColor(Color.Black)}.width(chat.content.length>15?GlobalConstant.PAGE_76:'auto').backgroundColor($r('app.color.embellishment_color')).padding({left:GlobalConstant.SIZE_16,right:GlobalConstant.SIZE_16,top:GlobalConstant.SIZE_8,bottom:GlobalConstant.SIZE_8}).borderRadius({topRight:GlobalConstant.SIZE_4,bottomLeft:GlobalConstant.SIZE_8,bottomRight:GlobalConstant.SIZE_4})}.justifyContent(FlexAlign.Start).alignItems(VerticalAlign.Top)}.width(GlobalConstant.PAGE_FULL).justifyContent(FlexAlign.Start)}if(chat.role==="user") {Row() {Row({space:GlobalConstant.SIZE_8}) {Row() {Text(chat.content).fontSize($r('app.float.font_size_14')).fontColor(Color.Black)}.width(chat.content.length>15?GlobalConstant.PAGE_76:'auto').backgroundColor($r('app.color.tab_default_color')).padding({left:GlobalConstant.SIZE_16,right:GlobalConstant.SIZE_16,top:GlobalConstant.SIZE_8,bottom:GlobalConstant.SIZE_8}).borderRadius({topLeft:GlobalConstant.SIZE_4,bottomLeft:GlobalConstant.SIZE_4,bottomRight:GlobalConstant.SIZE_8})Image(chat.avatar).width(GlobalConstant.SIZE_24).height(GlobalConstant.SIZE_24)}.justifyContent(FlexAlign.End).alignItems(VerticalAlign.Top)}.width(GlobalConstant.PAGE_FULL).justifyContent(FlexAlign.End)}})}.width(GlobalConstant.PAGE_FULL)}.width(GlobalConstant.PAGE_96).scrollable(ScrollDirection.Vertical).flexShrink(1)}.width(GlobalConstant.PAGE_FULL).height(GlobalConstant.PAGE_FULL).padding({bottom:GlobalConstant.SIZE_50})Row({space:GlobalConstant.SIZE_8}) {TextInput({placeholder:"請輸入提示詞...",text:this.inputValue}).height(GlobalConstant.SIZE_48).fontSize($r('app.float.font_size_16')).placeholderFont({size:$r('app.float.font_size_16') }).placeholderColor($r('app.color.text_color_9')).borderRadius($r('app.float.size_8')).backgroundColor($r('app.color.card_bg_color')).flexShrink(1).onChange((value:string)=>{this.inputValue=value;})Image($r('app.media.ic_send')).width(GlobalConstant.SIZE_32).height(GlobalConstant.SIZE_32).onClick(async()=>{this.loadingCtrl.open();if(this.inputValue==="") {promptAction.showToast({message:"發送內容不能爲空!"})return;}awaitthis.getAiResult();})}.width(GlobalConstant.PAGE_FULL).padding({left:GlobalConstant.SIZE_8,right:GlobalConstant.SIZE_8}).backgroundColor($r('app.color.card_bg_color'))}.width(GlobalConstant.PAGE_FULL).height(GlobalConstant.PAGE_FULL)}.width(GlobalConstant.PAGE_FULL).height(GlobalConstant.PAGE_FULL)}

效果圖

加載中

問答後

本篇文章還未完,見下篇!

0 阅读:1

CSDN

簡介:成就一億技術人,成爲技術人交流與成長的家園