0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
电子发烧友
开通电子发烧友VIP会员 尊享10大特权
海量资料免费下载
精品直播免费看
优质内容免费畅学
课程9折专享价
創(chuàng)作中心

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

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

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

jf_46214456 ? 來源:jf_46214456 ? 作者:jf_46214456 ? 2024-04-16 16:44 ? 次閱讀

1.概述

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

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

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

UI效果圖如下:

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

  • 圖2 手機端遙控頁面

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

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

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

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

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

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

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

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

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

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

    配網(wǎng)完畢。

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

本篇Codelab只對核心代碼進行講解,首先來介紹下整個工程的代碼結(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端各個頁面。
      • TVindex.ets:TV端主頁面。
      • VideoPlay.ets:TV端視頻播放頁面。
  • PhoneAbility:存放應(yīng)用手機控制端主頁面。
    • pages/PhoneIndex.ets:手機控制端主頁面。
  • ServiceAbility:存放ServiceAbility相關(guān)文件。
    • service.ts:service服務(wù),用于跨設(shè)備連接后通訊。
  • resources :存放工程使用到的資源文件。
    • resources/rawfile:存放工程中使用的圖片資源文件。
  • config.json:配置文件。

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

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

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

  1. 實現(xiàn)TV端默認(rèn)頁面布局和樣式。
    • 在MainAbility/pages/TVIndex.ets 主界面文件中添加入口組件。頁面布局代碼如下:
      // 入口組件
      @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的圖片源和圖片名稱綁定,實現(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. 實現(xiàn)TV端視頻播放界面。
    • 在MainAbility/pages/VideoPlay.ets 文件中添加組件。頁面布局代碼如下:
      import router from '@system.router'
      @Entry
      @Component
      struct Play {
      // 取到Index頁面跳轉(zhuǎn)來時攜帶的source對應(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的圖片添加點擊事件,點擊圖片即可播放PicItem的視頻源。實現(xiàn)代碼如下:
      Image(this.picItem.image)
              ......
              .onClick(() = > {
                router.push({
                  uri: 'pages/VideoPlay',
                  params: { source: this.picItem.video }
                })
              })
      

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

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

  • PhoneAbility/pages/PhoneIndex.ets 主界面文件中添加入口組件。頁面布局代碼如下:
    @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)機鍵
            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.實現(xiàn)分布式拉起和RPC通信

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

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

    • 點擊TV端主頁上的"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 })
        }
      }
      
    • 點擊設(shè)備彈出框內(nèi)的Text組件會調(diào)用onStartRemoteAbility()方法拉起遠(yuǎn)端FA(手機端),將TV端的deviceId傳給手機端,并連接手機端的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. 成功拉起手機端界面后,通過接收TV端傳過來的deviceId連接TV端的Service。在手機端的生命周期內(nèi)增加aboutToAppear()事件,在界面被拉起的時候讀取對方的deviceId并調(diào)用onConnectRemoteService()方法,連接對方的Service,實現(xiàn)代碼如下:

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

    • 創(chuàng)建SubscribeEvent(),實現(xiàn)代碼如下:
    subscribeEvent() {
        let self = this;
        // 用于保存創(chuàng)建成功的訂閱者對象,后續(xù)使用其完成訂閱及退訂的動作
        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()事件,訂閱公共事件,實現(xiàn)代碼如下:
    async aboutToAppear() {
        this.subscribeEvent();
      }
    
  4. 成功連接遠(yuǎn)端Service服務(wù)后,在手機遙控器端進行按鈕或者輸入操作都會完成一次跨設(shè)備通訊,消息的傳遞是由手機遙控器端的FA傳遞到TV端的Service服務(wù)。這里將連接遠(yuǎn)端Service和發(fā)送消息抽象為ConnectModel,詳細(xì)代碼可查看MainAbility/model/ConnectModel.ets文件中sendMessageToRemoteService()方法。

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

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

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

審核編輯 黃宇

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

    關(guān)注

    18

    文章

    852

    瀏覽量

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

    關(guān)注

    1

    文章

    988

    瀏覽量

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

    關(guān)注

    59

    文章

    2543

    瀏覽量

    43840
  • HarmonyOS
    +關(guān)注

    關(guān)注

    80

    文章

    2085

    瀏覽量

    32349
  • OpenHarmony
    +關(guān)注

    關(guān)注

    28

    文章

    3840

    瀏覽量

    18259
收藏 0人收藏

    評論

    相關(guān)推薦
    熱點推薦

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

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

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

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

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

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

    OpenHarmony分布式軟總線流程分析

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

    基于潤和DAYU200開發(fā)套件的OpenHarmony分布式音樂播放

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

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

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

    OpenHarmony3.1分布式技術(shù)資料合集

    客戶端(ScreenClient):屏幕圖像顯示代理客戶端,用于在設(shè)備上顯示其他設(shè)備投射過來的屏幕圖像數(shù)據(jù)。3、OpenHarmony3.1的分布式手寫板1.介紹基于TS擴展的聲明開發(fā)
    發(fā)表于 04-11 11:50

    DAYU200 | 分布式遙控器

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

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

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

    開發(fā)樣例】OpenHarmony分布式購物車

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

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

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

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

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

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

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

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

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

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

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

    電子發(fā)燒友

    中國電子工程師最喜歡的網(wǎng)站

    • 2931785位工程師會員交流學(xué)習(xí)
    • 獲取您個性化的科技前沿技術(shù)信息
    • 參加活動獲取豐厚的禮品