国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

鴻蒙應(yīng)用開(kāi)發(fā)-錄音并使用WebSocket實(shí)現(xiàn)實(shí)時(shí)語(yǔ)音識(shí)別

這篇具有很好參考價(jià)值的文章主要介紹了鴻蒙應(yīng)用開(kāi)發(fā)-錄音并使用WebSocket實(shí)現(xiàn)實(shí)時(shí)語(yǔ)音識(shí)別。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

功能介紹:

錄音并實(shí)時(shí)獲取RAW的音頻格式數(shù)據(jù),利用WebSocket上傳數(shù)據(jù)到服務(wù)器,并實(shí)時(shí)獲取語(yǔ)音識(shí)別結(jié)果,參考文檔使用AudioCapturer開(kāi)發(fā)音頻錄制功能(ArkTS),更詳細(xì)接口信息請(qǐng)查看接口文檔:AudioCapturer8+和@ohos.net.webSocket (WebSocket連接)。

知識(shí)點(diǎn):

  1. 熟悉使用AudioCapturer錄音并實(shí)時(shí)獲取RAW格式數(shù)據(jù)。
  2. 熟悉使用WebSocket上傳音頻數(shù)據(jù)并獲取識(shí)別結(jié)果。
  3. 熟悉對(duì)敏感權(quán)限的動(dòng)態(tài)申請(qǐng)方式,本項(xiàng)目的敏感權(quán)限為MICROPHONE。
  4. 關(guān)于如何搭建實(shí)時(shí)語(yǔ)音識(shí)別服務(wù),可以參考我的另外一篇文章:《識(shí)別準(zhǔn)確率竟如此高,實(shí)時(shí)語(yǔ)音識(shí)別服務(wù)》。

使用環(huán)境:

  • API 9
  • DevEco Studio 4.0 Release
  • Windows 11
  • Stage模型
  • ArkTS語(yǔ)言

所需權(quán)限:

  1. ohos.permission.MICROPHONE

效果圖:
鴻蒙應(yīng)用app播放webrtc流,鴻蒙應(yīng)用開(kāi)發(fā),harmonyos,websocket,語(yǔ)音識(shí)別,鴻蒙系統(tǒng),華為

核心代碼:

src/main/ets/utils/Permission.ets是動(dòng)態(tài)申請(qǐng)權(quán)限的工具:

import bundleManager from '@ohos.bundle.bundleManager';
import abilityAccessCtrl, { Permissions } from '@ohos.abilityAccessCtrl';

async function checkAccessToken(permission: Permissions): Promise<abilityAccessCtrl.GrantStatus> {
  let atManager = abilityAccessCtrl.createAtManager();
  let grantStatus: abilityAccessCtrl.GrantStatus;

  // 獲取應(yīng)用程序的accessTokenID
  let tokenId: number;
  try {
    let bundleInfo: bundleManager.BundleInfo = await bundleManager.getBundleInfoForSelf(bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_APPLICATION);
    let appInfo: bundleManager.ApplicationInfo = bundleInfo.appInfo;
    tokenId = appInfo.accessTokenId;
  } catch (err) {
    console.error(`getBundleInfoForSelf failed, code is ${err.code}, message is ${err.message}`);
  }

  // 校驗(yàn)應(yīng)用是否被授予權(quán)限
  try {
    grantStatus = await atManager.checkAccessToken(tokenId, permission);
  } catch (err) {
    console.error(`checkAccessToken failed, code is ${err.code}, message is ${err.message}`);
  }

  return grantStatus;
}

export async function checkPermissions(permission: Permissions): Promise<boolean> {
  let grantStatus: abilityAccessCtrl.GrantStatus = await checkAccessToken(permission);

  if (grantStatus === abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED) {
    return true
  } else {
    return false
  }
}

src/main/ets/utils/Recorder.ets是錄音工具類,進(jìn)行錄音和獲取錄音數(shù)據(jù)。

import audio from '@ohos.multimedia.audio';
import { delay } from './Utils';

export default class AudioCapturer {
  private audioCapturer: audio.AudioCapturer | undefined = undefined
  private isRecording: boolean = false
  private audioStreamInfo: audio.AudioStreamInfo = {
    samplingRate: audio.AudioSamplingRate.SAMPLE_RATE_16000, // 音頻采樣率
    channels: audio.AudioChannel.CHANNEL_1, // 錄音通道數(shù)
    sampleFormat: audio.AudioSampleFormat.SAMPLE_FORMAT_S16LE,
    encodingType: audio.AudioEncodingType.ENCODING_TYPE_RAW  // 音頻編碼類型
  }
  private audioCapturerInfo: audio.AudioCapturerInfo = {
    // 音源類型,使用SOURCE_TYPE_VOICE_RECOGNITION會(huì)有減噪功能,如果設(shè)備不支持,該用普通麥克風(fēng):SOURCE_TYPE_MIC
    source: audio.SourceType.SOURCE_TYPE_VOICE_RECOGNITION,
    capturerFlags: 0 // 音頻采集器標(biāo)志
  }
  private audioCapturerOptions: audio.AudioCapturerOptions = {
    streamInfo: this.audioStreamInfo,
    capturerInfo: this.audioCapturerInfo
  }

  // 初始化,創(chuàng)建實(shí)例,設(shè)置監(jiān)聽(tīng)事件
  constructor() {
    // 創(chuàng)建AudioCapturer實(shí)例
    audio.createAudioCapturer(this.audioCapturerOptions, (err, capturer) => {
      if (err) {
        console.error(`創(chuàng)建錄音器失敗, 錯(cuò)誤碼:${err.code}, 錯(cuò)誤信息:${err.message}`)
        return
      }
      this.audioCapturer = capturer
      console.info('創(chuàng)建錄音器成功')
    });
  }

  // 開(kāi)始一次音頻采集
  async start(callback: (state: number, data?: ArrayBuffer) => void) {
    // 當(dāng)且僅當(dāng)狀態(tài)為STATE_PREPARED、STATE_PAUSED和STATE_STOPPED之一時(shí)才能啟動(dòng)采集
    let stateGroup = [audio.AudioState.STATE_PREPARED, audio.AudioState.STATE_PAUSED, audio.AudioState.STATE_STOPPED]
    if (stateGroup.indexOf(this.audioCapturer.state) === -1) {
      console.error('啟動(dòng)錄音失敗')
      callback(audio.AudioState.STATE_INVALID)
      return
    }
    // 啟動(dòng)采集
    await this.audioCapturer.start()
    this.isRecording = true
    let bufferSize = 1920
    // let bufferSize: number = await this.audioCapturer.getBufferSize();

    while (this.isRecording) {
      let buffer = await this.audioCapturer.read(bufferSize, true)
      if (buffer === undefined) {
        console.error('讀取錄音數(shù)據(jù)失敗')
      } else {
        callback(audio.AudioState.STATE_RUNNING, buffer)
      }
    }
    callback(audio.AudioState.STATE_STOPPED)
  }

  // 停止采集
  async stop() {
    this.isRecording = false
    // 只有采集器狀態(tài)為STATE_RUNNING或STATE_PAUSED的時(shí)候才可以停止
    if (this.audioCapturer.state !== audio.AudioState.STATE_RUNNING && this.audioCapturer.state !== audio.AudioState.STATE_PAUSED) {
      console.warn('Capturer is not running or paused')
      return
    }
    await delay(200)
    // 停止采集
    await this.audioCapturer.stop()
    if (this.audioCapturer.state.valueOf() === audio.AudioState.STATE_STOPPED) {
      console.info('錄音停止')
    } else {
      console.error('錄音停止失敗')
    }
  }

  // 銷毀實(shí)例,釋放資源
  async release() {
    // 采集器狀態(tài)不是STATE_RELEASED或STATE_NEW狀態(tài),才能release
    if (this.audioCapturer.state === audio.AudioState.STATE_RELEASED || this.audioCapturer.state === audio.AudioState.STATE_NEW) {
      return
    }
    // 釋放資源
    await this.audioCapturer.release()
  }
}

還需要一些其他的工具函數(shù)src/main/ets/utils/Utils.ets,這個(gè)主要用于睡眠等待:

// 睡眠
export function delay(milliseconds : number) {
  return new Promise(resolve => setTimeout( resolve, milliseconds));
}

還需要在src/main/module.json5添加所需要的權(quán)限,注意是在module中添加,關(guān)于字段說(shuō)明,也需要在各個(gè)的string.json添加:

    "requestPermissions": [
      {
        "name": "ohos.permission.MICROPHONE",
        "reason": "$string:record_reason",
        "usedScene": {
          "abilities": [
            "EntryAbility"
          ],
          "when": "always"
        }
      }
    ]

頁(yè)面代碼如下:文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-858148.html

import abilityAccessCtrl, { Permissions } from '@ohos.abilityAccessCtrl';
import common from '@ohos.app.ability.common';
import webSocket from '@ohos.net.webSocket';
import AudioCapturer from '../utils/Recorder';
import promptAction from '@ohos.promptAction';
import { checkPermissions } from '../utils/Permission';
import audio from '@ohos.multimedia.audio';

// 需要?jiǎng)討B(tài)申請(qǐng)的權(quán)限
const permissions: Array<Permissions> = ['ohos.permission.MICROPHONE'];
// 獲取程序的上下文
const context = getContext(this) as common.UIAbilityContext;

@Entry
@Component
struct Index {
  @State recordBtnText: string = '按下錄音'
  @State speechResult: string = ''
  private offlineResult = ''
  private onlineResult = ''
  // 語(yǔ)音識(shí)別WebSocket地址
  private asrWebSocketUrl = "ws://192.168.0.100:10095"
  // 錄音器
  private audioCapturer?: AudioCapturer;
  // 創(chuàng)建WebSocket
  private ws;

  // 頁(yè)面顯示時(shí)
  async onPageShow() {
    // 判斷是否已經(jīng)授權(quán)
    let promise = checkPermissions(permissions[0])
    promise.then((result) => {
      if (result) {
        // 初始化錄音器
        if (this.audioCapturer == null) {
          this.audioCapturer = new AudioCapturer()
        }
      } else {
        this.reqPermissionsAndRecord(permissions)
      }
    })
  }

  // 頁(yè)面隱藏時(shí)
  async onPageHide() {
    if (this.audioCapturer != null) {
      this.audioCapturer.release()
    }
  }

  build() {
    Row() {
      RelativeContainer() {
        Text(this.speechResult)
          .id("resultText")
          .width('95%')
          .maxLines(10)
          .fontSize(18)
          .margin({ top: 10 })
          .alignRules({
            top: { anchor: '__container__', align: VerticalAlign.Top },
            middle: { anchor: '__container__', align: HorizontalAlign.Center }
          })
        // 錄音按鈕
        Button(this.recordBtnText)
          .width('90%')
          .id("recordBtn")
          .margin({ bottom: 10 })
          .alignRules({
            bottom: { anchor: '__container__', align: VerticalAlign.Bottom },
            middle: { anchor: '__container__', align: HorizontalAlign.Center }
          })
          .onTouch((event) => {
            switch (event.type) {
              case TouchType.Down:
                console.info('按下按鈕')
              // 判斷是否有權(quán)限
                let promise = checkPermissions(permissions[0])
                promise.then((result) => {
                  if (result) {
                    // 開(kāi)始錄音
                    this.startRecord()
                    this.recordBtnText = '錄音中...'
                  } else {
                    // 申請(qǐng)權(quán)限
                    this.reqPermissionsAndRecord(permissions)
                  }
                })
                break
              case TouchType.Up:
                console.info('松開(kāi)按鈕')
                // 停止錄音
                this.stopRecord()
                this.recordBtnText = '按下錄音'
                break
            }
          })
      }
      .height('100%')
      .width('100%')
    }
    .height('100%')
  }

  // 開(kāi)始錄音
  startRecord() {
    this.setWebSocketCallback()
    this.ws.connect(this.asrWebSocketUrl, (err) => {
      if (!err) {
        console.log("WebSocket連接成功");
        let jsonData = '{"mode": "2pass", "chunk_size": [5, 10, 5], "chunk_interval": 10, ' +
          '"wav_name": "HarmonyOS", "is_speaking": true, "itn": false}'
        // 要發(fā)完json數(shù)據(jù)才能錄音
        this.ws.send(jsonData)
        // 開(kāi)始錄音
        this.audioCapturer.start((state, data) => {
          if (state == audio.AudioState.STATE_STOPPED) {
            console.info('錄音結(jié)束')
            // 錄音結(jié)束,要發(fā)消息告訴服務(wù)器,結(jié)束識(shí)別
            let jsonData = '{"is_speaking": false}'
            this.ws.send(jsonData)
          } else if (state == audio.AudioState.STATE_RUNNING) {
            // 發(fā)送語(yǔ)音數(shù)據(jù)
            this.ws.send(data, (err) => {
              if (err) {
                console.log("WebSocket發(fā)送數(shù)據(jù)失敗,錯(cuò)誤信息:" + JSON.stringify(err))
              }
            });
          }
        })
      } else {
        console.log("WebSocket連接失敗,錯(cuò)誤信息: " + JSON.stringify(err));
      }
    });
  }

  // 停止錄音
  stopRecord() {
    if (this.audioCapturer != null) {
      this.audioCapturer.stop()
    }
  }

  // 綁定WebSocket事件
  setWebSocketCallback() {
    // 創(chuàng)建WebSocket
    this.ws = webSocket.createWebSocket();
    // 接收WebSocket消息
    this.ws.on('message', (err, value: string) => {
      console.log("WebSocket接收消息,結(jié)果如下:" + value)
      // 解析數(shù)據(jù)
      let result = JSON.parse(value)
      let is_final = result['is_final']
      let mode = result['mode']
      let text = result['text']
      if (mode == '2pass-offline') {
        this.offlineResult = this.offlineResult + text
        this.onlineResult = ''
      } else {
        this.onlineResult = this.onlineResult + text
      }
      this.speechResult = this.offlineResult + this.onlineResult
      // 如果是最后的數(shù)據(jù)就關(guān)閉WebSocket
      if (is_final) {
        this.ws.close()
      }
    });
    // WebSocket關(guān)閉事件
    this.ws.on('close', () => {
      console.log("WebSocket關(guān)閉連接");
    });
    // WebSocket發(fā)生錯(cuò)誤事件
    this.ws.on('error', (err) => {
      console.log("WebSocket出現(xiàn)錯(cuò)誤,錯(cuò)誤信息: " + JSON.stringify(err));
    });
  }

  // 申請(qǐng)權(quán)限
  reqPermissionsAndRecord(permissions: Array<Permissions>): void {
    let atManager = abilityAccessCtrl.createAtManager();
    // requestPermissionsFromUser會(huì)判斷權(quán)限的授權(quán)狀態(tài)來(lái)決定是否喚起彈窗
    atManager.requestPermissionsFromUser(context, permissions).then((data) => {
      let grantStatus: Array<number> = data.authResults;
      let length: number = grantStatus.length;
      for (let i = 0; i < length; i++) {
        if (grantStatus[i] === 0) {
          // 用戶授權(quán),可以繼續(xù)訪問(wèn)目標(biāo)操作
          console.info('授權(quán)成功')
          if (this.audioCapturer == null) {
            this.audioCapturer = new AudioCapturer()
          }
        } else {
          promptAction.showToast({ message: '授權(quán)失敗,需要授權(quán)才能錄音' })
          return;
        }
      }
    }).catch((err) => {
      console.error(`requestPermissionsFromUser failed, code is ${err.code}, message is ${err.message}`);
    })
  }
}

到了這里,關(guān)于鴻蒙應(yīng)用開(kāi)發(fā)-錄音并使用WebSocket實(shí)現(xiàn)實(shí)時(shí)語(yǔ)音識(shí)別的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 【鴻蒙應(yīng)用ArkTS開(kāi)發(fā)系列】- 選擇圖片、文件和拍照功能實(shí)現(xiàn)

    【鴻蒙應(yīng)用ArkTS開(kāi)發(fā)系列】- 選擇圖片、文件和拍照功能實(shí)現(xiàn)

    在使用App的時(shí)候,我們經(jīng)常會(huì)在一些社交軟件中聊天時(shí)發(fā)一些圖片或者文件之類的多媒體文件,那在鴻蒙原生應(yīng)用中,我們?cè)趺撮_(kāi)發(fā)這樣的功能呢? 本文會(huì)給大家對(duì)這個(gè)功能點(diǎn)進(jìn)行講解,我們采用的是拉起系統(tǒng)組件來(lái)進(jìn)行圖片、文件的選擇,拉起系統(tǒng)相機(jī)進(jìn)行拍照的這樣一種

    2024年02月04日
    瀏覽(23)
  • arkTS開(kāi)發(fā)鴻蒙OS應(yīng)用(登錄頁(yè)面實(shí)現(xiàn),連接數(shù)據(jù)庫(kù))

    arkTS開(kāi)發(fā)鴻蒙OS應(yīng)用(登錄頁(yè)面實(shí)現(xiàn),連接數(shù)據(jù)庫(kù))

    喜歡的朋友可在抖音、小紅書(shū)、微信公眾號(hào)、嗶哩嗶哩搜索“淼學(xué)派對(duì)”。知乎搜索“編程淼”。

    2024年03月24日
    瀏覽(25)
  • 【鴻蒙應(yīng)用ArkTS開(kāi)發(fā)系列】- 導(dǎo)航欄Tab組件使用講解

    【鴻蒙應(yīng)用ArkTS開(kāi)發(fā)系列】- 導(dǎo)航欄Tab組件使用講解

    現(xiàn)在市場(chǎng)上的大部分應(yīng)用,主頁(yè)都是才用底部導(dǎo)航欄菜單作為頁(yè)面主體框架來(lái)展示, 在鴻蒙中是使用Tabs組件實(shí)現(xiàn),下面我們開(kāi)始講解Tab組件的使用。 Tabs是一個(gè)通過(guò)頁(yè)簽進(jìn)行內(nèi)容視圖切換的容器組件,每個(gè)頁(yè)簽對(duì)應(yīng)一個(gè)內(nèi)容視圖,它僅可包含子組件TabContent,同時(shí)搭配 TabsCo

    2024年01月16日
    瀏覽(37)
  • HarmonyOS鴻蒙應(yīng)用開(kāi)發(fā)( 四、重磅組件List列表組件使用詳解)

    HarmonyOS鴻蒙應(yīng)用開(kāi)發(fā)( 四、重磅組件List列表組件使用詳解)

    List列表組件,是一個(gè)非常常用的組件??梢哉f(shuō)在一個(gè)應(yīng)用中,它的身影無(wú)處不在。它包含一系列相同寬度的列表項(xiàng),適合連續(xù)、多行呈現(xiàn)同類數(shù)據(jù),如商品列表、圖片列表和和文本列表等。ArkUI 框架采用 List 容器組件創(chuàng)建列表(類似 Android 的 RecycleView、Compose 的 LazyColumn)。

    2024年01月24日
    瀏覽(19)
  • 【鴻蒙應(yīng)用ArkTS開(kāi)發(fā)系列】- http網(wǎng)絡(luò)庫(kù)使用講解和封裝

    【鴻蒙應(yīng)用ArkTS開(kāi)發(fā)系列】- http網(wǎng)絡(luò)庫(kù)使用講解和封裝

    現(xiàn)在網(wǎng)上的應(yīng)用,基本都是網(wǎng)絡(luò)應(yīng)用,需要進(jìn)行聯(lián)網(wǎng)獲取數(shù)據(jù),而常用的聯(lián)網(wǎng)獲取數(shù)據(jù)的方式有http、socket、websocket等。 在鴻蒙應(yīng)用、服務(wù)中,stage模式開(kāi)發(fā)下,鴻蒙官方為我們提供了一個(gè)網(wǎng)絡(luò)組件庫(kù) http ,我們通過(guò) import http from ‘@ohos.net.http’; 即可以完成引用。 @ohos.net.http

    2024年02月15日
    瀏覽(28)
  • 【鴻蒙應(yīng)用ArkTS開(kāi)發(fā)系列】- Har包中子組件中監(jiān)聽(tīng)生命周期實(shí)現(xiàn)

    在鴻蒙應(yīng)用開(kāi)發(fā)中,有時(shí)候我們會(huì)創(chuàng)建HAR 模塊封裝一些SDK能力提供給第三方APP進(jìn)行集成。 鴻蒙的har 包并不支持定義page頁(yè)面對(duì)外導(dǎo)出,也不支持配置路由信息,因此我們多是在har包中提供組件,通過(guò)導(dǎo)出組件的形式,提供給App引用使用。 在鴻蒙中,非@Entry裝飾的組件,只能

    2024年02月14日
    瀏覽(21)
  • 鴻蒙應(yīng)用開(kāi)發(fā)學(xué)習(xí):改進(jìn)小魚(yú)動(dòng)畫(huà)實(shí)現(xiàn)按鍵一直按下時(shí)控制小魚(yú)移動(dòng)和限制小魚(yú)移出屏幕

    鴻蒙應(yīng)用開(kāi)發(fā)學(xué)習(xí):改進(jìn)小魚(yú)動(dòng)畫(huà)實(shí)現(xiàn)按鍵一直按下時(shí)控制小魚(yú)移動(dòng)和限制小魚(yú)移出屏幕

    一、前言 近期我在學(xué)習(xí)鴻蒙應(yīng)用開(kāi)發(fā),跟著B(niǎo)站UP主黑馬程序員的視頻教程做了一個(gè)小魚(yú)動(dòng)畫(huà)應(yīng)用,UP主提供的小魚(yú)動(dòng)畫(huà)源代碼僅僅實(shí)現(xiàn)了移動(dòng)組件的功能,還存在一些問(wèn)題,如默認(rèn)進(jìn)入頁(yè)面是豎屏而頁(yè)面適合橫屏顯示;真機(jī)測(cè)試發(fā)現(xiàn)手機(jī)的狀態(tài)欄影響到了返回鍵對(duì)按鍵事件的

    2024年02月01日
    瀏覽(23)
  • HarmonyOS 鴻蒙應(yīng)用開(kāi)發(fā)(十一、面向鴻蒙開(kāi)發(fā)的JavaScript基礎(chǔ))

    HarmonyOS 鴻蒙應(yīng)用開(kāi)發(fā)(十一、面向鴻蒙開(kāi)發(fā)的JavaScript基礎(chǔ))

    ArkTS 是HarmonyOS(鴻蒙操作系統(tǒng))原生應(yīng)用開(kāi)發(fā)的首選語(yǔ)言。它是用于構(gòu)建用戶界面的一種TypeScript方言,擴(kuò)展了TypeScript以適應(yīng)HarmonyOS生態(tài)系統(tǒng)的UI開(kāi)發(fā)需求。ArkTS 融合了TypeScript的靜態(tài)類型系統(tǒng)和現(xiàn)代UI框架的設(shè)計(jì)理念,為開(kāi)發(fā)者提供了一種更安全高效的方式來(lái)編寫(xiě)HarmonyOS應(yīng)用。

    2024年02月20日
    瀏覽(35)
  • 鴻蒙實(shí)戰(zhàn):ArkTs 開(kāi)發(fā)一個(gè)鴻蒙應(yīng)用

    鴻蒙實(shí)戰(zhàn):ArkTs 開(kāi)發(fā)一個(gè)鴻蒙應(yīng)用

    學(xué)習(xí)過(guò)的 ArkTs 知識(shí)點(diǎn),一步一步開(kāi)發(fā)一個(gè)小的鴻蒙應(yīng)用示例,涉及到 ?ArkTs 語(yǔ)法、注解 @Entry 、 @Component 、 @state 、路由、生命周期、 @Prop 、 @Link 、常用組件的使用等等知識(shí)點(diǎn)。 要開(kāi)發(fā)一個(gè)鴻蒙應(yīng)用,首先我們需要知道 系統(tǒng)是如何找到頁(yè)面的啟動(dòng)入口 。 鴻蒙如何啟動(dòng)應(yīng)用

    2024年02月22日
    瀏覽(25)
  • 【HarmonyOS】開(kāi)發(fā)一個(gè)可以看小姐姐的鴻蒙應(yīng)用 鴻蒙開(kāi)發(fā)入門(mén)

    【HarmonyOS】開(kāi)發(fā)一個(gè)可以看小姐姐的鴻蒙應(yīng)用 鴻蒙開(kāi)發(fā)入門(mén)

    先整張效果圖,丑點(diǎn)是丑點(diǎn),但可以用,買不起鴻蒙系統(tǒng)手機(jī)的我,只配用虛擬機(jī)。 要說(shuō)目前最火的手機(jī)操作系統(tǒng),要我來(lái)看的話那必然是鴻蒙無(wú)疑。16號(hào)剛剛結(jié)束了第五次鴻蒙內(nèi)測(cè),在看到這次的內(nèi)測(cè)名單之后,居然有970的機(jī)器,這是不是說(shuō)明俺這手里奮戰(zhàn)了三年的榮耀

    2024年02月15日
    瀏覽(28)

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包