精品国产人成在线_亚洲高清无码在线观看_国产在线视频国产永久2021_国产AV综合第一页一个的一区免费影院黑人_最近中文字幕MV高清在线视频

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

鴻蒙OS開發(fā)實(shí)戰(zhàn):【穿戴應(yīng)用】

jf_46214456 ? 2024-04-01 16:16 ? 次閱讀

背景

HarmonyOS穿戴應(yīng)用研發(fā),僅僅是為了一線研發(fā)人員提供少許的幫助。

在有些公司,可能因?yàn)闃I(yè)務(wù)的需要,所以要求研發(fā)人員一定要在華為手表穿戴上研發(fā)特定的功能,并且理所應(yīng)當(dāng)?shù)恼J(rèn)為這個(gè)開發(fā)成本就一個(gè)順手的事情。

開發(fā)應(yīng)用順手的原因無非就幾點(diǎn)

  1. 宣傳 - HarmonyOS已經(jīng)看似非常成熟
  2. 實(shí)踐UI效果 - 研發(fā)人員在手機(jī)上也能寫出絢麗的頁面和功能
  3. 匯報(bào) - 會(huì)寫H5前端,就能立即開發(fā)HarmonyOS應(yīng)用

穿戴研發(fā)核心注意點(diǎn)

  1. developer.harmonyos.com 網(wǎng)站中的文檔,只能閱讀3.0版本
  2. 智能穿戴 和 輕穿戴 應(yīng)用均采用JS語言開發(fā)
  3. 智能穿戴 對(duì)應(yīng)產(chǎn)品 - HUAWEI WATCH 3
  4. 輕穿戴 對(duì)應(yīng)產(chǎn)品 - HUAWEI WATCH GT 2 Pro,HUAWEI WATCH GT 3
  5. 和你產(chǎn)品功能相關(guān)的API,切記真機(jī)驗(yàn)證
  6. JS調(diào)用Java的文檔一定要閱讀,因?yàn)榇┐髟O(shè)備上的JS API功能相對(duì)來說比較少
  7. JS語言開發(fā)的應(yīng)用啟動(dòng)時(shí)的第一個(gè)頁面是由 congfig.json 文件中的 module -> js -> pages 中的第一個(gè)位置文件決定的,比如如下截圖中的紅色框文件

重點(diǎn)-JS調(diào)用Java

場(chǎng)景

錄音docs.qq.com/doc/DUmN4VVhBd3NxdExK前往。

搜狗高速瀏覽器截圖20240326151547.png

效果圖

為了快速演示效果,效果圖來自IDE

代碼說明

這里暫且認(rèn)為你已閱讀過3.0的開發(fā)文檔,并且已經(jīng)知曉所有的目錄結(jié)構(gòu)和開發(fā)語言

js代碼包含三部分:1. hml頁面 2. js邏輯處理 3. css頁面樣式

布局

testrecordaudiopage.js

import router from '@system.router';
import featureAbility from '@ohos.ability.featureAbility';
import serviceBridge from '../../generated/ServiceBridge.js';

var vm = null

export default {
    data: {
        title: "",
        button_record: "錄音",
        show_button_record: true,
        button_play: "播放",
        show_button_play: true,
        record: null
    },
    onInit() {
        this.title = "JS 錄音";
        vm = this
    },
    onHide() {
        if(this.record){
            this.record.stopPlay()
            this.record.stopRecord()
        }
    },
    swipeEvent(e) {
        if (e.direction == "right") {
            router.back()
        }
    },
    async audioRecorderDemo(type) {

        this.record = new serviceBridge()

        if (type === 'recordaudio') {
            if(this.button_record === '錄音'){
                this.record.startRecord().then(value = > {
                    if(value.abilityResult == 3){
                        vm.button_record = '停止錄音'
                        vm.show_button_play = false
                    }
                });

            } else {
                this.record.stopRecord().then(value = > {
                    if(value.abilityResult == 1){
                        vm.button_record = '錄音'
                        vm.show_button_play = true
                    }
                });
            }

        } else if (type === 'playaudio') {

            if(this.button_play === '播放'){
                this.record.play().then(value = > {
                    if(value.abilityResult == 3){
                        vm.button_play = '停止播放'
                        vm.show_button_record = false

                        var playTimeStatus = setInterval(()= >{
                            this.record.isPlaying().then(value = > {
                                if(!value.abilityResult){
                                    vm.button_play = '播放'
                                    vm.show_button_record = true
                                    clearInterval(playTimeStatus)
                                }
                            })

                        }, 1000)
                    }
                })
            } else {
                this.record.stopPlay().then(value = > {
                    if(value.abilityResult == 1){
                        vm.button_play = '播放'
                        vm.show_button_record = true
                    }
                })
            }

        }

    }
}
復(fù)制

testrecordaudiopage.hml

< div class="container" onswipe="swipeEvent" >
    < text class="title" >
        {{ title }}
    < /text >

    < div class="audiobutton" >
        < button class="buttons_record" show="{{show_button_record}}" onclick="audioRecorderDemo('recordaudio')" >{{button_record}}< /button >
        < button class="buttons_play" show="{{show_button_play}}" onclick="audioRecorderDemo('playaudio')" >{{button_play}}< /button >
    < /div >

< /div >
復(fù)制

testrecordaudiopage.css

.container {
    width: 100%;
    flex-direction: column;
    background-color: black;
}

.title {
    font-size: 25fp;
    text-align: center;
    width: 100%;
    margin: 20px;
}

.audiobutton {
    width: 100%;
    display: flex;
    flex-direction: column;
    align-items: center;
}

.buttons_record {
    width: 45%;
    height: 15%;
    font-size: 20fp;
    text-color: white;
    background-color: #1F71FF;
}

.buttons_play {
    width: 45%;
    height: 15%;
    font-size: 20fp;
    margin-top: 10vp;
    text-color: white;
    background-color: #1F71FF;
}
復(fù)制

Java API實(shí)現(xiàn)的功能

js/generated/ServiceBridge.js,注意這個(gè)文件是自動(dòng)生成的.

關(guān)于自動(dòng)生成js代碼的指導(dǎo),參見:docs.qq.com/doc/DUmN4VVhBd3NxdExK

// This file is automatically generated. Do not modify it!
const ABILITY_TYPE_EXTERNAL = 0;
const ABILITY_TYPE_INTERNAL = 1;
const ACTION_SYNC = 0;
const ACTION_ASYNC = 1;
const BUNDLE_NAME = 'com.harvey.hw.wear';
const ABILITY_NAME = 'com.harvey.hw.wear.ServiceBridgeStub';
......
const OPCODE_startRecord = 11;
const OPCODE_stopRecord = 12;
const OPCODE_stopPlay = 13;
const OPCODE_isPlaying = 14;
const OPCODE_play = 15;
const sendRequest = async (opcode, data) = > {
    var action = {};
    action.bundleName = BUNDLE_NAME;
    action.abilityName = ABILITY_NAME;
    action.messageCode = opcode;
    action.data = data;
    action.abilityType = ABILITY_TYPE_INTERNAL;
    action.syncOption = ACTION_SYNC;
    return FeatureAbility.callAbility(action);
}
class ServiceBridge {
   ......
 
   async startRecord() {
      if (arguments.length != 0) {
         throw new Error("Method expected 0 arguments, got " + arguments.length);
      }
      let data = {};
      const result = await sendRequest(OPCODE_startRecord, data);
      return JSON.parse(result);
   }
   async stopRecord() {
      if (arguments.length != 0) {
         throw new Error("Method expected 0 arguments, got " + arguments.length);
      }
      let data = {};
      const result = await sendRequest(OPCODE_stopRecord, data);
      return JSON.parse(result);
   }
   async stopPlay() {
      if (arguments.length != 0) {
         throw new Error("Method expected 0 arguments, got " + arguments.length);
      }
      let data = {};
      const result = await sendRequest(OPCODE_stopPlay, data);
      return JSON.parse(result);
   }
   async isPlaying() {
      if (arguments.length != 0) {
         throw new Error("Method expected 0 arguments, got " + arguments.length);
      }
      let data = {};
      const result = await sendRequest(OPCODE_isPlaying, data);
      return JSON.parse(result);
   }
   async play() {
      if (arguments.length != 0) {
         throw new Error("Method expected 0 arguments, got " + arguments.length);
      }
      let data = {};
      const result = await sendRequest(OPCODE_play, data);
      return JSON.parse(result);
   }
}
export default ServiceBridge;
復(fù)制

既然這個(gè)文件是自動(dòng)生成的,那么繼續(xù)看工程配置。

首先,在 工程根目錄/entry/src/main/java 文件夾下的包名(文章舉例使用:com.harvey.hw.wear)中創(chuàng)建一個(gè)名為ServiceBridge.java的文件

其次,配置初始化和聲明ServiceBridge.js文件的注解。為什么注冊(cè)路徑文件是MainAbility, 因?yàn)槌跏蓟拇a是在MainAbility.java文件中

package com.harvey.hw.wear;

import com.harvey.hw.wear.bluetooth.BLEMain;
import ohos.annotation.f2pautogen.ContextInject;
import ohos.annotation.f2pautogen.InternalAbility;
import ohos.app.AbilityContext;
import ohos.bundle.IBundleManager;
import ohos.dcall.DistributedCallManager;
import ohos.hiviewdfx.HiLog;
import ohos.hiviewdfx.HiLogLabel;
import ohos.media.audio.*;

import java.io.*;
import java.util.Arrays;

@InternalAbility(registerTo = "com.harvey.hw.wear.MainAbility")
public class ServiceBridge {

    private static final HiLogLabel LABEL_LOG = new HiLogLabel(3, 0xD001100, "ServiceBridge");

    @ContextInject
    AbilityContext abilityContext;

    ......
    
    //樣例:錄音
    /**
     * 錄音 - 啟動(dòng)
     * @return
     */
    public int startRecord() {
        if(isRecording){
            return 1;
        }

        if(abilityContext.verifySelfPermission("ohos.permission.MICROPHONE") == IBundleManager.PERMISSION_DENIED){
            requestPermissions();
            return 2;
        }
        HiLog.error(LABEL_LOG, "RecordServiceAbility::onStart");
        init();
        runRecord();


        return 3;
    }

    /**
     * 錄音 - 停止
     * @return
     */
    public int stopRecord() {
        if (isRecording && audioCapturer.stop()) {
            audioCapturer.release();
        }
        isRecording = false;
        return 1;
    }

    private AudioRenderer renderer;
    private static boolean isPlaying = false;

    /**
     * 播放 - 停止
     * @return
     */
    public int stopPlay() {
        if(isPlaying && renderer.stop()){
            renderer.release();
        }
        isPlaying = false;
        return 1;
    }

    /**
     * 獲取音頻播放狀態(tài)
     * @return
     */
    public boolean isPlaying(){
        return isPlaying;
    }

    /**
     * 播放 - 啟動(dòng)
     * @return
     */
    public int play() {
        if(isPlaying){
            return 1;
        }

        isPlaying = true;
        String Path = "/data/data/"+abilityContext.getBundleName()+"/files/record.pcm";
        File pcmFilePath = new File(Path);
        if(!pcmFilePath.isFile() || !pcmFilePath.exists()){
            isPlaying = false;
            return 2;
        }

        new Thread(new Runnable() {
            @Override
            public void run() {
                AudioStreamInfo audioStreamInfo = new AudioStreamInfo.Builder().sampleRate(SAMPLE_RATE)
                        .encodingFormat(ENCODING_FORMAT)
                        .channelMask(CHANNEL_OUT_MASK)
                        .streamUsage(AudioStreamInfo.StreamUsage.STREAM_USAGE_MEDIA)
                        .build();

                AudioRendererInfo audioRendererInfo = new AudioRendererInfo.Builder().audioStreamInfo(audioStreamInfo)
                        .audioStreamOutputFlag(AudioRendererInfo.AudioStreamOutputFlag.AUDIO_STREAM_OUTPUT_FLAG_DIRECT_PCM)
                        .sessionID(AudioRendererInfo.SESSION_ID_UNSPECIFIED)
                        .bufferSizeInBytes(BUFFER_SIZE)
                        .isOffload(false)
                        .build();

                renderer = new AudioRenderer(audioRendererInfo, AudioRenderer.PlayMode.MODE_STREAM);
                AudioInterrupt audioInterrupt = new AudioInterrupt();
                AudioManager audioManager = new AudioManager();
                audioInterrupt.setStreamInfo(audioStreamInfo);
                audioInterrupt.setInterruptListener(new AudioInterrupt.InterruptListener() {
                    @Override
                    public void onInterrupt(int type, int hint) {
                        if (type == AudioInterrupt.INTERRUPT_TYPE_BEGIN
                                && hint == AudioInterrupt.INTERRUPT_HINT_PAUSE) {
                            renderer.pause();
                        } else if (type == AudioInterrupt.INTERRUPT_TYPE_BEGIN
                                && hint == AudioInterrupt.INTERRUPT_HINT_NONE) {

                        } else if (type == AudioInterrupt.INTERRUPT_TYPE_END && (
                                hint == AudioInterrupt.INTERRUPT_HINT_NONE
                                        || hint == AudioInterrupt.INTERRUPT_HINT_RESUME)) {
                            renderer.start();
                        } else {
                            HiLog.error(LABEL_LOG, "unexpected type or hint");
                        }
                    }
                });
                audioManager.activateAudioInterrupt(audioInterrupt);

                AudioDeviceDescriptor[] devices = AudioManager.getDevices(AudioDeviceDescriptor.DeviceFlag.INPUT_DEVICES_FLAG);
                for(AudioDeviceDescriptor des:devices){
                    if(des.getType() == AudioDeviceDescriptor.DeviceType.SPEAKER){
                        renderer.setOutputDevice(des);
                        break;
                    }
                }

                renderer.setVolume(1.0f);
                renderer.start();

                BufferedInputStream bis1 = null;
                try {
                    bis1 = new BufferedInputStream(new FileInputStream(pcmFilePath));
                    int minBufferSize = renderer.getMinBufferSize(SAMPLE_RATE, ENCODING_FORMAT,
                            CHANNEL_OUT_MASK);
                    byte[] buffers = new byte[minBufferSize];
                    while ((bis1.read(buffers)) != -1) {
                        if(isPlaying){
                            renderer.write(buffers, 0, buffers.length);
                            renderer.flush();
                        }
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    if (bis1 != null) {
                        try {
                            bis1.close();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                }

                stopPlay();
            }
        }).start();

        return 3;
    }

    private AudioCapturer audioCapturer;
    private static final AudioStreamInfo.EncodingFormat ENCODING_FORMAT = AudioStreamInfo.EncodingFormat.ENCODING_PCM_16BIT;
    private static final AudioStreamInfo.ChannelMask CHANNEL_IN_MASK = AudioStreamInfo.ChannelMask.CHANNEL_IN_STEREO;
    private static final AudioStreamInfo.ChannelMask CHANNEL_OUT_MASK = AudioStreamInfo.ChannelMask.CHANNEL_OUT_STEREO;
    private static final int SAMPLE_RATE = 16000;
    private static final int BUFFER_SIZE = 1024;
    private static boolean isRecording = false;

    private void init() {
        AudioDeviceDescriptor[] devices = AudioManager.getDevices(AudioDeviceDescriptor.DeviceFlag.INPUT_DEVICES_FLAG);
        AudioDeviceDescriptor currentAudioType = null;
        for(AudioDeviceDescriptor des:devices){
            if(des.getType() == AudioDeviceDescriptor.DeviceType.MIC){
                currentAudioType = des;
                break;
            }
        }

        AudioCapturerInfo.AudioInputSource source = AudioCapturerInfo.AudioInputSource.AUDIO_INPUT_SOURCE_MIC;
        AudioStreamInfo audioStreamInfo = new AudioStreamInfo.Builder().audioStreamFlag(
                        AudioStreamInfo.AudioStreamFlag.AUDIO_STREAM_FLAG_AUDIBILITY_ENFORCED)
                .encodingFormat(ENCODING_FORMAT)
                .channelMask(CHANNEL_IN_MASK)
                .streamUsage(AudioStreamInfo.StreamUsage.STREAM_USAGE_MEDIA)
                .sampleRate(SAMPLE_RATE)
                .build();
        AudioCapturerInfo audioCapturerInfo = new AudioCapturerInfo.Builder().audioStreamInfo(audioStreamInfo)
                .audioInputSource(source)
                .build();
        audioCapturer = new AudioCapturer(audioCapturerInfo, currentAudioType);
    }

    private void runRecord() {
        isRecording = true;

        new Thread(new Runnable() {
            @Override
            public void run() {
                //啟動(dòng)錄音
                audioCapturer.start();

                File file = new File("/data/data/"+abilityContext.getBundleName()+"/files/record.pcm");
                if (file.isFile()) {
                    file.delete();
                }
                try (FileOutputStream outputStream = new FileOutputStream(file)) {
                    byte[] bytes = new byte[BUFFER_SIZE];
                    while (audioCapturer.read(bytes, 0, bytes.length) != -1) {
                        outputStream.write(bytes);
                        bytes = new byte[BUFFER_SIZE];
                        outputStream.flush();
                        if(!isRecording){
                            outputStream.close();
                            break;
                        }
                    }
                } catch (IOException exception) {
                    HiLog.error(LABEL_LOG, "record exception," + exception.getMessage());
                }

            }
        }).start();

    }

    private void requestPermissions() {
        String[] permissions = {
                "ohos.permission.MICROPHONE"
        };
        abilityContext.requestPermissionsFromUser(Arrays.stream(permissions)
                .filter(permission - > abilityContext.verifySelfPermission(permission) != IBundleManager.PERMISSION_GRANTED).toArray(String[]::new), 0);
    }

}
復(fù)制

第三,如何初始化ServiceBridge.java呢?創(chuàng)建一個(gè)中間文件,命名為ServiceBridgeStub.java。

public class MainAbility extends AceAbility {
    @Override
    public void onStart(Intent intent) {
        ServiceBridgeStub.register(this);
        ......
    }
    
    ......
}
復(fù)制

ServiceBridgeStub.java

package com.harvey.hw.wear;

import java.lang.Object;
import java.lang.String;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;
import ohos.ace.ability.AceInternalAbility;
import ohos.app.AbilityContext;
import ohos.rpc.IRemoteObject;
import ohos.rpc.MessageOption;
import ohos.rpc.MessageParcel;
import ohos.rpc.RemoteException;
import ohos.utils.zson.ZSONObject;

public class ServiceBridgeStub extends AceInternalAbility {
  public static final String BUNDLE_NAME = "com.harvey.hw.wear";

  public static final String ABILITY_NAME = "com.harvey.hw.wear.ServiceBridgeStub";

  public static final int ERROR = -1;

  public static final int SUCCESS = 0;

  ......

  public static final int OPCODE_startRecord = 11;

  public static final int OPCODE_stopRecord = 12;

  public static final int OPCODE_stopPlay = 13;

  public static final int OPCODE_isPlaying = 14;

  public static final int OPCODE_play = 15;

  private static ServiceBridgeStub instance;

  private ServiceBridge service;

  private AbilityContext abilityContext;

  public ServiceBridgeStub() {
    super(BUNDLE_NAME, ABILITY_NAME);
  }

  public boolean onRemoteRequest(int code, MessageParcel data, MessageParcel reply,
      MessageOption option) {
    Map< String, Object > result = new HashMap< String, Object >();
    switch(code) {
    
      ......
      
      case OPCODE_startRecord: {
      java.lang.String zsonStr = data.readString();
      ZSONObject zsonObject = ZSONObject.stringToZSON(zsonStr);
      result.put("code", SUCCESS);
      result.put("abilityResult", service.startRecord());
      break;}
      case OPCODE_stopRecord: {
      java.lang.String zsonStr = data.readString();
      ZSONObject zsonObject = ZSONObject.stringToZSON(zsonStr);
      result.put("code", SUCCESS);
      result.put("abilityResult", service.stopRecord());
      break;}
      case OPCODE_stopPlay: {
      java.lang.String zsonStr = data.readString();
      ZSONObject zsonObject = ZSONObject.stringToZSON(zsonStr);
      result.put("code", SUCCESS);
      result.put("abilityResult", service.stopPlay());
      break;}
      case OPCODE_isPlaying: {
      java.lang.String zsonStr = data.readString();
      ZSONObject zsonObject = ZSONObject.stringToZSON(zsonStr);
      result.put("code", SUCCESS);
      result.put("abilityResult", service.isPlaying());
      break;}
      case OPCODE_play: {
      java.lang.String zsonStr = data.readString();
      ZSONObject zsonObject = ZSONObject.stringToZSON(zsonStr);
      result.put("code", SUCCESS);
      result.put("abilityResult", service.play());
      break;}
      default: reply.writeString("Opcode is not defined!");
      return false;
    }
    return sendResult(reply, result, option.getFlags() == MessageOption.TF_SYNC);
  }

  private boolean sendResult(MessageParcel reply, Map< String, Object > result, boolean isSync) {
    if (isSync) {
      reply.writeString(ZSONObject.toZSONString(result));
    } else {
      MessageParcel response = MessageParcel.obtain();
      response.writeString(ZSONObject.toZSONString(result));
      IRemoteObject remoteReply = reply.readRemoteObject();
      try {
        remoteReply.sendRequest(0, response, MessageParcel.obtain(), new MessageOption());
        response.reclaim();
      } catch (RemoteException exception) {
        return false;
      }
    }
    return true;
  }

  public static void register(AbilityContext abilityContext) {
    instance = new ServiceBridgeStub();
    instance.onRegister(abilityContext);
  }

  private void onRegister(AbilityContext abilityContext) {
    this.abilityContext = abilityContext;
    this.service = new ServiceBridge();
    this.setInternalAbilityHandler(this::onRemoteRequest);
    try {
      Field field = ServiceBridge.class.getDeclaredField("abilityContext");
      field.setAccessible(true);
      field.set(this.service, abilityContext);
      field.setAccessible(false);
    } catch (NoSuchFieldException | IllegalAccessException e) {
      ohos.hiviewdfx.HiLog.error(new ohos.hiviewdfx.HiLogLabel(0, 0, null), "context injection fail.");
    }
  }

  public static void deregister() {
    instance.onDeregister();
  }

  private void onDeregister() {
    abilityContext = null;
    this.setInternalAbilityHandler(null);
  }
}
復(fù)制

最后,對(duì)自動(dòng)生成js代碼的功能,做編譯配置

entry 主模塊的 build.gradle 文件中添加如下代碼

apply plugin: 'com.huawei.ohos.hap'
apply plugin: 'com.huawei.ohos.decctest'

ohos {
    compileSdkVersion 6
    defaultConfig {
        compatibleSdkVersion 6

        // 在文件頭部定義JS模板代碼生成路徑
        def jsOutputDir = project.file("src/main/js/default/generated").toString()

        // 在ohos - > defaultConfig中設(shè)置JS模板代碼生成路徑
        javaCompileOptions {
            annotationProcessorOptions {
                arguments = ["jsOutputDir": jsOutputDir] // JS模板代碼生成賦值
            }
        }
    }

    ......

    compileOptions {
        f2pautogenEnabled true // 此處為啟用js2java-codegen工具的開關(guān)
    }

}

......
復(fù)制

至此,關(guān)于穿戴應(yīng)用研發(fā)的重點(diǎn)介紹已完成。

如果你還有興趣,可以嘗試實(shí)踐一下BLE傳輸數(shù)據(jù)

結(jié)尾

這是去年研發(fā)穿戴應(yīng)用的一個(gè)Demo應(yīng)用工程結(jié)構(gòu)

備注

看的HarmonyOS文檔多了, 對(duì)于開發(fā)語言和文檔中的描述容易產(chǎn)生混淆,這里附上一張簡(jiǎn)單的HarmonyOS 3.0 到 3.1版本的說明

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 移動(dòng)開發(fā)
    +關(guān)注

    關(guān)注

    0

    文章

    52

    瀏覽量

    9698
  • 鴻蒙系統(tǒng)
    +關(guān)注

    關(guān)注

    183

    文章

    2634

    瀏覽量

    66224
  • HarmonyOS
    +關(guān)注

    關(guān)注

    79

    文章

    1967

    瀏覽量

    30035
  • OpenHarmony
    +關(guān)注

    關(guān)注

    25

    文章

    3665

    瀏覽量

    16161
  • 鴻蒙OS
    +關(guān)注

    關(guān)注

    0

    文章

    188

    瀏覽量

    4371
收藏 人收藏

    評(píng)論

    相關(guān)推薦

    鴻蒙OS崛起,鴻蒙應(yīng)用開發(fā)工程師成市場(chǎng)新寵

    應(yīng)用的形態(tài)也在發(fā)生著翻天覆地的變化。作為全球領(lǐng)先的移動(dòng)操作系統(tǒng)和智能終端制造商,華為公司自主研發(fā)的鴻蒙OS應(yīng)運(yùn)而生,致力于構(gòu)建一個(gè)統(tǒng)一的分布式操作系統(tǒng),為各行各業(yè)的應(yīng)用開發(fā)帶來全新的可能性。 一、
    發(fā)表于 04-29 17:32

    鴻蒙Flutter實(shí)戰(zhàn):07混合開發(fā)

    # 鴻蒙Flutter實(shí)戰(zhàn):混合開發(fā) 鴻蒙Flutter混合開發(fā)主要有兩種形式。 ## 1.基于har 將flutter module
    發(fā)表于 10-23 16:00

    初識(shí)鴻蒙OS

    1.0版本的設(shè)計(jì)和開發(fā);2018年,華為公司完成了鴻蒙內(nèi)核2.0版本的設(shè)計(jì)和研發(fā);2019年,華為的智慧屏率先搭載鴻蒙操作系統(tǒng);2020年9月11日,華為正式發(fā)布鴻蒙操作系統(tǒng),并舉行
    發(fā)表于 09-10 15:28

    鴻蒙OS應(yīng)用程序開發(fā)

    這份學(xué)習(xí)文檔主要是帶領(lǐng)大家在鴻蒙OS上學(xué)習(xí)開發(fā)一個(gè)應(yīng)用程序,主要知識(shí)點(diǎn)如下:1、U-Boot引導(dǎo)文件燒寫方式;2、內(nèi)核鏡像燒寫方式;3、鏡像運(yùn)行。
    發(fā)表于 09-11 14:39

    鴻蒙OS適用的全場(chǎng)景到底什么意思?

    鴻蒙系統(tǒng)(HarmonyOS),第一款基于微內(nèi)核的全場(chǎng)景分布式OS,是華為自主研發(fā)的操作系統(tǒng)。華為在開發(fā)者大會(huì)HDC.2019上正式發(fā)布了鴻蒙系統(tǒng),該系統(tǒng)將率先部署在智慧屏、車載終端、
    發(fā)表于 09-25 09:25

    鴻蒙os系統(tǒng)是什么意思 鴻蒙os系統(tǒng)有什么作用

    適配智慧屏,未來它將適配手機(jī),平板,電腦,智能汽車,可穿戴設(shè)備等多終端設(shè)備。鴻蒙微內(nèi)核是基于微內(nèi)核的全場(chǎng)景分布式OS,可按需擴(kuò)展,實(shí)現(xiàn)更廣泛的系統(tǒng)安全,主要用于物聯(lián)網(wǎng),特點(diǎn)是低時(shí)延,甚至可到毫秒級(jí)乃至亞
    發(fā)表于 12-17 11:34

    鴻蒙 OS 應(yīng)用開發(fā)初體驗(yàn)

    的操作系統(tǒng)平臺(tái)和開發(fā)框架。HarmonyOS 的目標(biāo)是實(shí)現(xiàn)跨設(shè)備的無縫協(xié)同和高性能。 DevEco Studio 對(duì)標(biāo) Android Studio,開發(fā)鴻蒙 OS 應(yīng)用的 IDE。
    發(fā)表于 11-02 19:38

    華為鴻蒙OS又有嚇人的設(shè)計(jì) 蘋果的Carplay在鴻蒙OS面前真的自嘆不如

    的終端,包括汽車、電視機(jī)、手機(jī)、可穿戴設(shè)備等等終端上,所以華為鴻蒙OS的使用范圍從介紹上來看還是非常廣泛地。
    的頭像 發(fā)表于 08-27 10:25 ?8842次閱讀

    華為鴻蒙OS 2.0帶來哪些智慧體驗(yàn)?

    華為已經(jīng)定于12月16日在北京發(fā)布鴻蒙OS 2.0手機(jī)開發(fā)者Beta版本。這不僅是手機(jī)鴻蒙OS的首次亮相,同時(shí)也意味著手機(jī)
    的頭像 發(fā)表于 12-15 15:10 ?2051次閱讀

    鴻蒙OS 2.0手機(jī)開發(fā)者Beta版發(fā)布會(huì)在京舉辦

    三個(gè)月前,鴻蒙OS 2.0正式在華為開發(fā)者大會(huì)2020亮相。12月16日,鴻蒙OS 2.0手機(jī)開發(fā)
    的頭像 發(fā)表于 12-16 09:29 ?1.9w次閱讀

    華為發(fā)布鴻蒙OS Beta版

    昨天華為發(fā)布鴻蒙OS Beta版了?鴻蒙系統(tǒng)一直在按照既有步伐前進(jìn),現(xiàn)在華為發(fā)布鴻蒙OS Beta版,而且一些生態(tài)
    的頭像 發(fā)表于 12-17 08:41 ?2854次閱讀

    鴻蒙OS與Lite OS的區(qū)別是什么

    鴻蒙OS鴻蒙OS面向未來、面向全場(chǎng)景、分布式。在單設(shè)備系統(tǒng)能力基礎(chǔ)上,鴻蒙OS提出了基于同一套系
    的頭像 發(fā)表于 12-24 12:40 ?4930次閱讀

    鴻蒙os怎么升級(jí)

    6月2日,華為正式發(fā)布了鴻蒙armonyOS 2系統(tǒng),那么鴻蒙os如何升級(jí)?現(xiàn)將鴻蒙os升級(jí)方式告知如下。
    的頭像 發(fā)表于 06-08 16:26 ?2713次閱讀

    華為開發(fā)者大會(huì)2021鴻蒙os在哪場(chǎng)

    華為開發(fā)者大會(huì)2021將在10月22日-24日舉辦,地點(diǎn)為東莞松山湖,鴻蒙os 3.0或?qū)⑴c我們見面,那么華為開發(fā)者大會(huì)2021鴻蒙
    的頭像 發(fā)表于 10-22 15:24 ?1880次閱讀

    RISC-V MCU開發(fā)實(shí)戰(zhàn) (三):移植鴻蒙OS項(xiàng)目

    移植鴻蒙OS項(xiàng)目
    的頭像 發(fā)表于 11-01 11:08 ?2901次閱讀
    RISC-V MCU<b class='flag-5'>開發(fā)</b><b class='flag-5'>實(shí)戰(zhàn)</b> (三):移植<b class='flag-5'>鴻蒙</b><b class='flag-5'>OS</b>項(xiàng)目