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

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

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

OpenHarmony開(kāi)發(fā)案例:【分布式遙控器】

jf_46214456 ? 來(lái)源:jf_46214456 ? 作者:jf_46214456 ? 2024-04-16 16:44 ? 次閱讀

1.概述

目前家庭電視機(jī)主要通過(guò)其自帶的遙控器進(jìn)行操控,實(shí)現(xiàn)的功能較為單一。例如,當(dāng)我們要在TV端搜索節(jié)目時(shí),電視機(jī)在遙控器的操控下往往只能完成一些字母或數(shù)字的輸入,而無(wú)法輸入其他復(fù)雜的內(nèi)容。分布式遙控器將手機(jī)的輸入能力和電視遙控器的遙控能力結(jié)合為一體,從而快速便捷操控電視。

分布式遙控器的實(shí)現(xiàn)基于OpenHarmony的分布式能力和RPC通信能力,UI使用eTS進(jìn)行開(kāi)發(fā)。如下圖所示,分別用兩塊開(kāi)發(fā)板模擬TV端和手機(jī)端。

  1. 分布式組網(wǎng)后可以通過(guò)TV端界面的Controller按鈕手動(dòng)拉起手機(jī)端的遙控界面,在手機(jī)端輸入時(shí)會(huì)將輸入的內(nèi)容同步顯示在TV端搜索框,點(diǎn)擊搜索按鈕會(huì)根據(jù)輸入的內(nèi)容搜索相關(guān)節(jié)目。
  2. 還可以通過(guò)點(diǎn)擊方向鍵(上下左右)將焦點(diǎn)移動(dòng)到我們想要的節(jié)目上,再點(diǎn)擊播放按鈕進(jìn)行播放,按返回按鈕返回TV端主界面。
  3. 同時(shí)還可以通過(guò)手機(jī)遙控端關(guān)機(jī)按鈕同時(shí)關(guān)閉TV端和手機(jī)端界面。

UI效果圖如下:

圖1 TV端主頁(yè)默認(rèn)頁(yè)面

  • 圖2 手機(jī)端遙控頁(yè)面

    • 圖3 TV端視頻播放頁(yè)面

說(shuō)明: 本示例涉及使用系統(tǒng)接口,需要手動(dòng)替換Full SDK才能編譯通過(guò),具體操作可參考[替換指南]。

2.搭建OpenHarmony環(huán)境

完成本篇Codelab我們首先要完成開(kāi)發(fā)環(huán)境的搭建,本示例以RK3568開(kāi)發(fā)板為例,參照以下步驟進(jìn)行:

  1. [獲取OpenHarmony系統(tǒng)版本]:標(biāo)準(zhǔn)系統(tǒng)解決方案(二進(jìn)制)。
    以3.1版本為例:
  2. 搭建燒錄環(huán)境。
    1. [完成DevEco Device Tool的安裝]
    2. [完成RK3568開(kāi)發(fā)板的燒錄](méi)
    3. 鴻蒙開(kāi)發(fā)文檔指導(dǎo):[gitee.com/li-shizhen-skin/harmony-os/blob/master/README.md]
  3. 搭建開(kāi)發(fā)環(huán)境。
    1. 開(kāi)始前請(qǐng)參考[工具準(zhǔn)備],完成DevEco Studio的安裝和開(kāi)發(fā)環(huán)境配置。
    2. 開(kāi)發(fā)環(huán)境配置完成后,請(qǐng)參考[使用工程向?qū)創(chuàng)建工程(模板選擇“Empty Ability”),選擇JS或者eTS語(yǔ)言開(kāi)發(fā)。
    3. 工程創(chuàng)建完成后,選擇使用[真機(jī)進(jìn)行調(diào)測(cè)])。
      搜狗高速瀏覽器截圖20240326151450.png

3.分布式組網(wǎng)

本章節(jié)以系統(tǒng)自帶的音樂(lè)播放器為例(具體以實(shí)際的應(yīng)用為準(zhǔn)),介紹如何完成兩臺(tái)設(shè)備的分布式組網(wǎng)。

  1. 硬件準(zhǔn)備:準(zhǔn)備兩臺(tái)燒錄相同的版本系統(tǒng)的RK3568開(kāi)發(fā)板A、B。

  2. 開(kāi)發(fā)板A、B連接同一個(gè)WiFi網(wǎng)絡(luò)。
    打開(kāi)設(shè)置-->WLAN-->點(diǎn)擊右側(cè)WiFi開(kāi)關(guān)-->點(diǎn)擊目標(biāo)WiFi并輸入密碼。

  3. 將設(shè)備A,B設(shè)置為互相信任的設(shè)備。

    • 找到系統(tǒng)應(yīng)用“音樂(lè)”。
    • 設(shè)備A打開(kāi)音樂(lè),點(diǎn)擊左下角流轉(zhuǎn)按鈕,彈出列表框,在列表中會(huì)展示遠(yuǎn)端設(shè)備的id。選擇遠(yuǎn)端設(shè)備B的id,另一臺(tái)開(kāi)發(fā)板(設(shè)備B)會(huì)彈出驗(yàn)證的選項(xiàng)框。
    • 設(shè)備B點(diǎn)擊允許,設(shè)備B將會(huì)彈出隨機(jī)PIN碼,將設(shè)備B的PIN碼輸入到設(shè)備A的PIN碼填入框中。

    配網(wǎng)完畢。

4.代碼結(jié)構(gòu)解讀

本篇Codelab只對(duì)核心代碼進(jìn)行講解,首先來(lái)介紹下整個(gè)工程的代碼結(jié)構(gòu):

  • MainAbility:
    • model:數(shù)據(jù)模型。
      • RemoteDeviceModel.ets:獲取組網(wǎng)內(nèi)的設(shè)備列表模型。
      • PicData.ets:圖片信息數(shù)據(jù)。
      • PicDataModel.ets:圖片信息模型。
      • ConnectModel.ets:連接遠(yuǎn)端Service和發(fā)送消息模型。
    • pages:存放TV端各個(gè)頁(yè)面。
      • TVindex.ets:TV端主頁(yè)面。
      • VideoPlay.ets:TV端視頻播放頁(yè)面。
  • PhoneAbility:存放應(yīng)用手機(jī)控制端主頁(yè)面。
    • pages/PhoneIndex.ets:手機(jī)控制端主頁(yè)面。
  • ServiceAbility:存放ServiceAbility相關(guān)文件。
    • service.ts:service服務(wù),用于跨設(shè)備連接后通訊。
  • resources :存放工程使用到的資源文件。
    • resources/rawfile:存放工程中使用的圖片資源文件。
  • config.json:配置文件。

5.實(shí)現(xiàn)TV端界面

在本章節(jié)中,您將學(xué)會(huì)開(kāi)發(fā)TV端默認(rèn)界面和TV端視頻播放界面,示意圖參考第一章圖1和圖3所示。

建立數(shù)據(jù)模型,將圖片ID、圖片源、圖片名稱和視頻源綁定成一個(gè)數(shù)據(jù)模型。詳情代碼可以查看MainAbility/model/PicData.ets和MainAbility/model/PicDataModel.ets兩個(gè)文件。

  1. 實(shí)現(xiàn)TV端默認(rèn)頁(yè)面布局和樣式。
    • 在MainAbility/pages/TVIndex.ets 主界面文件中添加入口組件。頁(yè)面布局代碼如下:
      // 入口組件
      @Entry
      @Component
      struct Index {
        private letters: string[] = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9']
        private source: string
        @State text: string = ''
        @State choose: number = -1
      
        build() {
          Flex({ direction: FlexDirection.Column }) {
            TextInput({text: this.text, placeholder: 'Search' })
              .onChange((value: string) = > {
                this.text = value
              })
      
            Row({space: 30}) {
              Text('Clear')
                .fontSize(16)
                .backgroundColor('#ABB0BA')
                .textAlign(TextAlign.Center)
                .onClick(() = > {
                  this.text = ''
                })
                .clip(true)
                .borderRadius(10)
      
              Text('Backspace')
                .fontSize(16)
                .backgroundColor('#ABB0BA')
                .textAlign(TextAlign.Center)
                .onClick(() = > {
                  this.text = this.text.substring(0, this.text.length - 1)
                })
                .clip(true)
                .borderRadius(10)
      
              Text('Controller')
                .fontSize(16)
                .backgroundColor('#ABB0BA')
                .textAlign(TextAlign.Center)
                .onClick(() = > {
                  ......
                })
                .clip(true)
                .borderRadius(10)
      
            }
      
            Grid() {
              ForEach(this.letters, (item) = > {
                GridItem() {
                  Text(item)
                    .fontSize(20)
                    .backgroundColor('#FFFFFF')
                    .textAlign(TextAlign.Center)
                    .onClick(() = > {
                      this.text += item
                      })
                    .clip(true)
                    .borderRadius(5)
                }
              }, item = > item)
      
            }
            .rowsTemplate('1fr 1fr 1fr 1fr')
            .columnsTemplate('1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr')
            .columnsGap(8)
            .rowsGap(8)
            .width('75%')
            .height('25%')
            .margin(5)
            .backgroundColor('#D2D3D8')
            .clip(true)
            .borderRadius(10)
      
            Grid() {
              ForEach(this.picItems, (item: PicData) = > {
                GridItem() {
                  PicGridItem({ picItem: item })
                }
              }, (item: PicData) = > item.id.toString())
            }
            .rowsTemplate('1fr 1fr 1fr')
            .columnsTemplate('1fr 1fr')
            .columnsGap(5)
            .rowsGap(8)
            .width('90%')
            .height('58%')
            .backgroundColor('#FFFFFF')
            .margin(5)
          }
          .width('98%')
          .backgroundColor('#FFFFFF')
        }
      }
      
    • 其中PicGridItem將PicItem的圖片源和圖片名稱綁定,實(shí)現(xiàn)代碼如下:
      // 九宮格拼圖組件
      @Component
      struct PicGridItem {
        private picItem: PicData
        build() {
          Column() {
            Image(this.picItem.image)
              .objectFit(ImageFit.Contain)
              .height('85%')
              .width('100%')
              .onClick(() = > {
                ......
                })
              })
            Text(this.picItem.name)
              .fontSize(20)
              .fontColor('#000000')
          }
          .height('100%')
          .width('90%')
        }
      }
      
  2. 實(shí)現(xiàn)TV端視頻播放界面。
    • 在MainAbility/pages/VideoPlay.ets 文件中添加組件。頁(yè)面布局代碼如下:
      import router from '@system.router'
      @Entry
      @Component
      struct Play {
      // 取到Index頁(yè)面跳轉(zhuǎn)來(lái)時(shí)攜帶的source對(duì)應(yīng)的數(shù)據(jù)。
        private source: string = router.getParams().source
      
        build() {
          Column() {
            Video({
              src: this.source,
            })
              .width('100%')
              .height('100%')
              .autoPlay(true)
              .controls(true)
          }
        }
      }
      
    • 在MainAbility/pages/TVIndex.ets中,給PicGridItem的圖片添加點(diǎn)擊事件,點(diǎn)擊圖片即可播放PicItem的視頻源。實(shí)現(xiàn)代碼如下:
      Image(this.picItem.image)
              ......
              .onClick(() = > {
                router.push({
                  uri: 'pages/VideoPlay',
                  params: { source: this.picItem.video }
                })
              })
      

6.實(shí)現(xiàn)手機(jī)遙控端界面

在本章節(jié)中,您將學(xué)會(huì)開(kāi)發(fā)手機(jī)遙控端默認(rèn)界面,示意圖參考第一章圖2所示。

  • PhoneAbility/pages/PhoneIndex.ets 主界面文件中添加入口組件。頁(yè)面布局代碼如下:
    @Entry
    @Component
    struct Index {
      build() {
        Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center }) {
          Row() {
            Image($rawfile('TV.png'))
              .width(25)
              .height(25)
            Text('華為智慧屏').fontSize(20).margin(10)
          }
          // 文字搜索框
          TextInput({ placeholder: 'Search' })
            .margin(20)
            .onChange((value: string) = > {
              if (connectModel.mRemote){
                ......
              }
            })
    
          Grid() {
            GridItem() {
          // 向上箭頭
              Button({ type: ButtonType.Circle, stateEffect: true }) {
                Image($rawfile('up.png')).width(80).height(80)
              }
              .onClick(() = > {
                ......
              })
              .width(80)
              .height(80)
              .backgroundColor('#FFFFFF')
            }
            .columnStart(1)
            .columnEnd(5)
    
            GridItem() {
          // 向左箭頭
              Button({ type: ButtonType.Circle, stateEffect: true }) {
                Image($rawfile('left.png')).width(80).height(80)
              }
              .onClick(() = > {
                ......
              })
              .width(80)
              .height(80)
              .backgroundColor('#FFFFFF')
            }
    
            GridItem() {
          // 播放鍵
              Button({ type: ButtonType.Circle, stateEffect: true }) {
                Image($rawfile('play.png')).width(60).height(60)
              }
              .onClick(() = > {
                ......
              })
              .width(80)
              .height(80)
              .backgroundColor('#FFFFFF')
            }
    
            GridItem() {
          // 向右箭頭
              Button({ type: ButtonType.Circle, stateEffect: true }) {
                Image($rawfile('right.png')).width(70).height(70)
              }
              .onClick(() = > {
                ......
              })
              .width(80)
              .height(80)
              .backgroundColor('#FFFFFF')
            }
    
            GridItem() {
          // 向下箭頭
              Button({ type: ButtonType.Circle, stateEffect: true }) {
                Image($rawfile('down.png')).width(70).height(70)
              }
              .onClick(() = > {
                ......
              })
              .width(80)
              .height(80)
              .backgroundColor('#FFFFFF')
            }
            .columnStart(1)
            .columnEnd(5)
          }
          .rowsTemplate('1fr 1fr 1fr')
          .columnsTemplate('1fr 1fr 1fr')
          .backgroundColor('#FFFFFF')
          .margin(10)
          .clip(new Circle({ width: 325, height: 325 }))
          .width(350)
          .height(350)
    
          Row({ space:100 }) {
            // 返回鍵
            Button({ type: ButtonType.Circle, stateEffect: true }) {
              Image($rawfile('return.png')).width(40).height(40)
            }
            .onClick(() = > {
              ......
            })
            .width(100)
            .height(100)
            .backgroundColor('#FFFFFF')
    
            // 關(guān)機(jī)鍵
            Button({ type: ButtonType.Circle, stateEffect: true }) {
              Image($rawfile('off.png')).width(40).height(40)
            }
            .onClick(() = > {
              ......
            })
            .width(100)
            .height(100)
            .backgroundColor('#FFFFFF')
    
            // 搜索鍵
            Button({ type: ButtonType.Circle, stateEffect: true }) {
              Image($rawfile('search.png')).width(40).height(40)
            }
            .onClick(() = > {
              ......
            })
            .width(100)
            .height(100)
            .backgroundColor('#FFFFFF')
          }
          .padding({ left:100 })
        }
        .backgroundColor('#E3E3E3')
      }
    }
    

7.實(shí)現(xiàn)分布式拉起和RPC通信

在本章節(jié)中,您將學(xué)會(huì)如何拉起在同一組網(wǎng)內(nèi)的設(shè)備上的FA,并且連接遠(yuǎn)端Service服務(wù)。

  1. 首先通過(guò)TV端拉起手機(jī)端界面,并將本端的deviceId發(fā)送到手機(jī)端。

    • 點(diǎn)擊TV端主頁(yè)上的"Controller"按鈕,增加.onClick()事件。調(diào)用RegisterDeviceListCallback()發(fā)現(xiàn)設(shè)備列表,并彈出設(shè)備列表選擇框CustomDialogExample,選擇設(shè)備后拉起遠(yuǎn)端FA。CustomDialogExample()代碼如下:
      // 設(shè)備列表彈出框
      @CustomDialog
      struct CustomDialogExample {
        @State editFlag: boolean = false
        controller: CustomDialogController
        cancel: () = > void
        confirm: () = > void
      
        build() {
          Column() {
            List({ space: 10, initialIndex: 0 }) {
              ForEach(DeviceIdList, (item) = > {
                ListItem() {
                  Row() {
                    Text(item)
                      .width('87%')
                      .height(50)
                      .fontSize(10)
                      .textAlign(TextAlign.Center)
                      .borderRadius(10)
                      .backgroundColor(0xFFFFFF)
                      .onClick(() = > {
                        onStartRemoteAbility(item);
                        this.controller.close();
                      })
                  }
                }.editable(this.editFlag)
              }, item = > item)
            }
          }.width('100%').height(200).backgroundColor(0xDCDCDC).padding({ top: 5 })
        }
      }
      
    • 點(diǎn)擊設(shè)備彈出框內(nèi)的Text組件會(huì)調(diào)用onStartRemoteAbility()方法拉起遠(yuǎn)端FA(手機(jī)端),將TV端的deviceId傳給手機(jī)端,并連接手機(jī)端的Service。因此在featureAbility.startAbility()成功的回調(diào)中也要調(diào)用onConnectRemoteService()方法。這里將連接遠(yuǎn)端Service和發(fā)送消息抽象為ConnectModel,詳細(xì)代碼可查看MainAbility/model/ConnectModel.ets文件中onConnectRemoteService()方法。onStartRemoteAbility()方法的代碼如下:
      function onStartRemoteAbility(deviceId) {
        AuthDevice(deviceId);
        let numDevices = remoteDeviceModel.deviceList.length;
        if (numDevices === 0) {
          prompt.showToast({
            message: "onStartRemoteAbility no device found"
          });
          return;
        }
      
        var params = {
          remoteDeviceId: localDeviceId
        }
      
        var wantValue = {
          bundleName: 'com.example.helloworld0218',
          abilityName: 'com.example.helloworld0218.PhoneAbility',
          deviceId: deviceId,
          parameters: params
        };
      
        featureAbility.startAbility({
          want: wantValue
        }).then((data) = > {
          // 拉起遠(yuǎn)端后,連接遠(yuǎn)端service
          connectModel.onConnectRemoteService(deviceId)
        });
      }
      
    • 需要注意的是,配置文件config.json中ServiceAbility的屬性visible要設(shè)置為true,代碼如下:
      "abilities": [
            ...
            {
              "visible": true,
              "srcPath": "ServiceAbility",
              "name": ".ServiceAbility",
              "icon": "$media:icon",
              "srcLanguage": "ets",
              "description": "$string:description_serviceability",
              "type": "service"
            }
      ],
      
  2. 成功拉起手機(jī)端界面后,通過(guò)接收TV端傳過(guò)來(lái)的deviceId連接TV端的Service。在手機(jī)端的生命周期內(nèi)增加aboutToAppear()事件,在界面被拉起的時(shí)候讀取對(duì)方的deviceId并調(diào)用onConnectRemoteService()方法,連接對(duì)方的Service,實(shí)現(xiàn)代碼如下:

    async aboutToAppear() {
        await featureAbility.getWant((error, want) = > {
          // 遠(yuǎn)端被拉起后,連接對(duì)端的service
          if (want.parameters.remoteDeviceId) {
            let remoteDeviceId = want.parameters.remoteDeviceId
            connectModel.onConnectRemoteService(remoteDeviceId)
          }
        });
      }
    
  3. 建立一個(gè)ServiceAbility處理收到的消息并發(fā)布公共事件,詳細(xì)代碼請(qǐng)看ServiceAbility/service.ts文件。TV端訂閱本端Service的公共事件,并接受和處理消息。

    • 創(chuàng)建SubscribeEvent(),實(shí)現(xiàn)代碼如下:
    subscribeEvent() {
        let self = this;
        // 用于保存創(chuàng)建成功的訂閱者對(duì)象,后續(xù)使用其完成訂閱及退訂的動(dòng)作
        var subscriber;
        // 訂閱者信息
        var subscribeInfo = {
          events: ["publish_change"],
          priority: 100
        };
    
        // 設(shè)置有序公共事件的結(jié)果代碼回調(diào)
        function SetCodeCallBack() {
        }
        // 設(shè)置有序公共事件的結(jié)果數(shù)據(jù)回調(diào)
        function SetDataCallBack() {
        }
        // 完成本次有序公共事件處理回調(diào)
        function FinishCommonEventCallBack() {
        }
        // 訂閱公共事件回調(diào)
        function SubscribeCallBack(err, data) {
          let msgData = data.data;
          let code = data.code;
          // 設(shè)置有序公共事件的結(jié)果代碼
          subscriber.setCode(code, SetCodeCallBack);
          // 設(shè)置有序公共事件的結(jié)果數(shù)據(jù)
          subscriber.setData(msgData, SetDataCallBack);
          // 完成本次有序公共事件處理
          subscriber.finishCommonEvent(FinishCommonEventCallBack)
          // 處理接收到的數(shù)據(jù)data
          ......
    
        // 創(chuàng)建訂閱者回調(diào)
        function CreateSubscriberCallBack(err, data) {
          subscriber = data;
          // 訂閱公共事件
          commonEvent.subscribe(subscriber, SubscribeCallBack);
        }
    
        // 創(chuàng)建訂閱者
        commonEvent.createSubscriber(subscribeInfo, CreateSubscriberCallBack);
      }
    }
    
    • 在TV端的生命周期內(nèi)增加aboutToAppear()事件,訂閱公共事件,實(shí)現(xiàn)代碼如下:
    async aboutToAppear() {
        this.subscribeEvent();
      }
    
  4. 成功連接遠(yuǎn)端Service服務(wù)后,在手機(jī)遙控器端進(jìn)行按鈕或者輸入操作都會(huì)完成一次跨設(shè)備通訊,消息的傳遞是由手機(jī)遙控器端的FA傳遞到TV端的Service服務(wù)。這里將連接遠(yuǎn)端Service和發(fā)送消息抽象為ConnectModel,詳細(xì)代碼可查看MainAbility/model/ConnectModel.ets文件中sendMessageToRemoteService()方法。

8.設(shè)置遙控器遠(yuǎn)端事件

手機(jī)端應(yīng)用對(duì)TV端能做出的控制有:向上移動(dòng)、向下移動(dòng)、向左移動(dòng)、向右移動(dòng)、確定、返回、關(guān)閉。在手機(jī)端按鍵上增加點(diǎn)擊事件,通過(guò)sendMessageToRemoteService()的方法發(fā)送到TV端Service。TV端根據(jù)發(fā)送code以及數(shù)據(jù),進(jìn)行數(shù)據(jù)處理,這里只展示TV端數(shù)據(jù)處理部分的核心代碼:

// code = 1時(shí),將手機(jī)遙控端search框內(nèi)數(shù)據(jù)同步到TV端
if (code == 1) {
  self.text = data.parameters.dataList;
}
// code = 2時(shí),增加選中圖片效果
if (code == 2) {
  // 如果在圖片序號(hào)范圍內(nèi)就選中圖片,否則不更改
  var tmp: number = +data.parameters.dataList;
  if ((self.choose + tmp <= 5) && (self.choose + tmp >= 0)) {
    self.choose += tmp;
  }
}
// code = 3時(shí),播放選中圖片對(duì)應(yīng)的視頻
if (code == 3) {
  self.picItems.forEach(function (item) {
    if (item.id == self.choose) {
      router.push({
        uri: 'pages/VideoPlay',
        params: { source: item.video }
      })
    }
  })
}
// code = 4時(shí),回到TV端默認(rèn)頁(yè)面
if (code == 4) {
  router.push({
    uri: 'pages/TVIndex',
  })
}
// code = 5時(shí),關(guān)閉程序
if (code == 5) {
  featureAbility.terminateSelf()
}
// code = 6時(shí),搜索圖片名稱并增加選中特效
if (code == 6) {
  self.picItems.forEach(function (item) {
    if (item.name == self.text) {
      self.choose = Number(item.id)
    }
  })
}

審核編輯 黃宇

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

    關(guān)注

    18

    文章

    829

    瀏覽量

    65867
  • 分布式
    +關(guān)注

    關(guān)注

    1

    文章

    858

    瀏覽量

    74439
  • 鴻蒙
    +關(guān)注

    關(guān)注

    57

    文章

    2302

    瀏覽量

    42689
  • HarmonyOS
    +關(guān)注

    關(guān)注

    79

    文章

    1966

    瀏覽量

    29962
  • OpenHarmony
    +關(guān)注

    關(guān)注

    25

    文章

    3635

    瀏覽量

    16061
收藏 人收藏

    評(píng)論

    相關(guān)推薦

    OpenHarmony分布式開(kāi)發(fā)前奏

    分布式軟總線是手機(jī)、平板、智能穿戴、智慧屏、車機(jī)等分布式設(shè)備的通信基座,為設(shè)備之間的互聯(lián)互通提供了統(tǒng)一的分布式通信能力,為設(shè)備之間的無(wú)感發(fā)現(xiàn)和零等待傳輸創(chuàng)造了條件。開(kāi)發(fā)者只需聚焦于業(yè)務(wù)
    的頭像 發(fā)表于 12-01 14:14 ?1215次閱讀
    <b class='flag-5'>OpenHarmony</b><b class='flag-5'>分布式</b><b class='flag-5'>開(kāi)發(fā)</b>前奏

    OpenHarmony開(kāi)發(fā)案例:【分布式計(jì)算

    使用分布式能力實(shí)現(xiàn)了一個(gè)簡(jiǎn)單的計(jì)算應(yīng)用,可以進(jìn)行簡(jiǎn)單的數(shù)值計(jì)算,支持遠(yuǎn)程拉起另一個(gè)設(shè)備的計(jì)算應(yīng)用,兩個(gè)計(jì)算應(yīng)用進(jìn)行協(xié)同計(jì)算。
    的頭像 發(fā)表于 04-11 15:24 ?974次閱讀
    <b class='flag-5'>OpenHarmony</b><b class='flag-5'>開(kāi)發(fā)案</b>例:【<b class='flag-5'>分布式</b>計(jì)算<b class='flag-5'>器</b>】

    OpenHarmony南向開(kāi)發(fā)案例:【分布式畫(huà)板】

    使用OpenHarmony3.1-Release開(kāi)發(fā)的應(yīng)用。通過(guò)OpenHarmony分布式技術(shù),使多人能夠一起畫(huà)畫(huà)。
    的頭像 發(fā)表于 04-12 14:40 ?966次閱讀
    <b class='flag-5'>OpenHarmony</b>南向<b class='flag-5'>開(kāi)發(fā)案</b>例:【<b class='flag-5'>分布式</b>畫(huà)板】

    OpenHarmony 2.2 Beta2 版本發(fā)布,具備典型的分布式能力和媒體類產(chǎn)品開(kāi)發(fā)能力

    。OpenHarmony 具備了典型的分布式能力和媒體類產(chǎn)品開(kāi)發(fā)能力。即日起,全球開(kāi)發(fā)者可通過(guò) Gitee 和鏡像站點(diǎn)下載完整代碼(https://gitee.com/
    發(fā)表于 08-09 15:15

    OpenHarmony分布式軟總線流程分析

    OpenHarmony分布式軟總線流程分析,大神總結(jié),大家可以下載去學(xué)習(xí)了~.~
    發(fā)表于 11-19 15:56

    基于潤(rùn)和DAYU200開(kāi)發(fā)套件的OpenHarmony分布式音樂(lè)播放

    :參考DevEco Studio(OpenHarmony)使用指南搭建OpenHarmony應(yīng)用開(kāi)發(fā)環(huán)境、并導(dǎo)入本工程進(jìn)行編譯、運(yùn)行。運(yùn)行結(jié)果截圖:【分布式流轉(zhuǎn)體驗(yàn)】硬件準(zhǔn)備:準(zhǔn)備兩臺(tái)
    發(fā)表于 03-14 09:07

    OpenHarmony標(biāo)準(zhǔn)設(shè)備應(yīng)用開(kāi)發(fā)(三)——分布式數(shù)據(jù)管理

    (以下內(nèi)容來(lái)自開(kāi)發(fā)者分享,不代表 OpenHarmony 項(xiàng)目群工作委員會(huì)觀點(diǎn))邢碌上一章,我們通過(guò)分布式音樂(lè)播放、分布式***、
    發(fā)表于 04-07 18:48

    DAYU200 | 分布式遙控器

    遙控器將手機(jī)的輸入能力和電視遙控器遙控能力結(jié)合為一體,從而快速便捷操控電視。分布式遙控器的實(shí)現(xiàn)基于Op
    發(fā)表于 05-25 15:47

    【學(xué)習(xí)打卡】OpenHarmony分布式任務(wù)調(diào)度

    之前我們分享過(guò)分布式軟總線和分布式數(shù)據(jù)管理,今天主要說(shuō)一下OpenHarmony分布式任務(wù)調(diào)度,分布式任務(wù)調(diào)度是建立在
    發(fā)表于 07-18 17:06

    開(kāi)發(fā)樣例】OpenHarmony分布式購(gòu)物車

    設(shè)計(jì)OpenHarmony技術(shù)特性eTS UI分布式調(diào)度分布式數(shù)據(jù)管理3.支持OpenHarmony版本OpenHarmony 3.0 LT
    發(fā)表于 07-29 14:17

    OpenHarmony 分布式硬件關(guān)鍵技術(shù)

    的視頻會(huì)議;在影音娛樂(lè)場(chǎng)景下,能夠輕松地把手機(jī)音視頻放到電視和音箱上播放,還可以讓家里的燈光自動(dòng)跟隨電影和音樂(lè)進(jìn)行變化,實(shí)現(xiàn)非常震撼的家庭影院的效果。 期待越來(lái)越多的開(kāi)發(fā)者參與OpenHarmony的生態(tài)中來(lái),共同研究和探討分布式
    發(fā)表于 08-24 17:25

    基于OpenHarmony分布式應(yīng)用開(kāi)發(fā)框架使用教程

    電子發(fā)燒友網(wǎng)站提供《基于OpenHarmony分布式應(yīng)用開(kāi)發(fā)框架使用教程.zip》資料免費(fèi)下載
    發(fā)表于 04-12 11:19 ?9次下載

    OpenHarmony技術(shù)論壇:分布式相機(jī)和分布式圖庫(kù)功能

    OpenHarmony Tech Day·技術(shù)日》 技術(shù)論壇 新增分布式相機(jī)和分布式圖庫(kù)功能 相比OpenHarmony 3.0版本,OpenHa
    的頭像 發(fā)表于 04-25 15:06 ?1773次閱讀
    <b class='flag-5'>OpenHarmony</b>技術(shù)論壇:<b class='flag-5'>分布式</b>相機(jī)和<b class='flag-5'>分布式</b>圖庫(kù)功能

    分布式數(shù)據(jù)對(duì)象的產(chǎn)生背景、原理及開(kāi)發(fā)案

    在3月底發(fā)布的OpenHarmony v3.1 Release版本中,新增了分布式數(shù)據(jù)對(duì)象特性。什么是分布式數(shù)據(jù)對(duì)象呢?本期就讓我們一起來(lái)了解一下。
    的頭像 發(fā)表于 04-27 15:01 ?1185次閱讀
    <b class='flag-5'>分布式</b>數(shù)據(jù)對(duì)象的產(chǎn)生背景、原理及<b class='flag-5'>開(kāi)發(fā)案</b>例

    OpenHarmony知識(shí)賦能No.29-DAYU200分布式應(yīng)用開(kāi)發(fā)

    OpenHarmony標(biāo)準(zhǔn)系統(tǒng)北向開(kāi)發(fā)高手。 ? 嘉賓介紹: 徐建國(guó) 資深技術(shù)專家(江蘇潤(rùn)開(kāi)鴻數(shù)字科技有限公司) ? 課程內(nèi)容: 1.OpenHarmony分布式API介紹 a.
    的頭像 發(fā)表于 05-04 09:57 ?804次閱讀
    <b class='flag-5'>OpenHarmony</b>知識(shí)賦能No.29-DAYU200<b class='flag-5'>分布式</b>應(yīng)用<b class='flag-5'>開(kāi)發(fā)</b>