前言

本示例介紹如何使用@kit.NetworkKit接口監聽手機網絡狀態,根據不同的網絡狀態對視頻進行播放、暫停處理等操作。

效果預覽圖

HarmonyOS應用開發案例:網絡狀態監聽_網絡狀態

使用説明

  1. 第一次打開應用進入案例頁面,視頻不播放。
  2. 點擊自動播放設置按鈕,進入設置頁面,開啓或者關閉3G/4G/5G自動播放、WI-FI自動播放。
  3. 開啓或者關閉手機的蜂窩網絡或者WI-FI開關,查看視頻是否根據自動播放設置頁面中的設置播放或者暫停。
  4. 返回首頁瀑布流或者殺死應用重新進入案例,查看視頻是否根據自動播放設置中的設置和手機網絡狀態播放或者暫停。

實現思路

頁面實現

1.1 在VideoPage中添加Video組件,設置在線視頻播放

```
Video({
  src: "https://v.oh4k.com/muhou/2022/07/20220704-RIUq3Z.mp4",
   controller: this.controller
}).height(300)
  .width('100%')
  .autoPlay(this.autoPlay())
```

1.2 在aboutToAppear方法中添加網絡狀態監聽,並開始監聽WI-FI和蜂窩數據的狀態。

```
emitter.on(NetUtils.getInstance().getEmitterEvent(), (data: emitter.EventData) => {
  if (data) {
    this.netObserver(data);
  } else {
    logger.info("aboutToAppear emitter on error, data is undefined.");
  }
});
NetUtils.getInstance().startNetObserve(connection.NetBearType.BEARER_CELLULAR, connection.NetBearType.BEARER_WIFI);
```

1.3 在netObserver方法中,添加不同網絡狀態的處理。

netObserver(data: emitter.EventData) {
...
  let eventName: NetworkEventName = netEventData.eventName ?? -1;
  switch (eventName) {
    case NetworkEventName.NetAvailable:
      if (netEventData.netType === connection.NetBearType.BEARER_WIFI) {
        if (this.wifiAutoPlay) {
          this.startPlay();
        }
      }
      break;
    case NetworkEventName.NetBlock:
      break;
    case NetworkEventName.NetLost:
      if (netEventData.netType === connection.NetBearType.BEARER_WIFI) {
        this.wifiInterrupt();
      }
      break;
    case NetworkEventName.NetUnavailable:
      if (netEventData.netType === connection.NetBearType.BEARER_WIFI) {
        this.wifiInterrupt();
      }
      break;
    case NetworkEventName.WeakNet:
      // 如果是弱網環境
      if (netEventData.status) {
        Prompt.showToast({ message: "當前網絡環境較差,視頻播放可能出現卡頓" });
      }
      break;
    default:
      logger.debug("當前網絡狀態:" + eventName);
      break;
  }
}

1.4 在SettingPage中添加Toggle組件,管理自動播放設置。

Toggle({ type: ToggleType.Switch, isOn: this.cellularAutoPlay })
  .selectedColor('#007DFF')
  .switchPointColor('#FFFFFF')
  .onChange((isOn: boolean) => {
    logger.info('Component status:' + isOn);
    AppStorage.setOrCreate('cellular_auto_play', isOn);
    PersistentStorage.persistProp('cellular_auto_play', isOn);
  })
  .width('10%')

網絡狀態監聽工具類NetUtils實現,通過@kit.NetworkKit接口監聽網絡狀態,然後通過emitter將監聽結果傳遞給頁面。

2.1 開啓網絡監聽

public startNetObserve(...netType: connection.NetBearType[]) {
  netType.forEach((type: connection.NetBearType) => {
    this.networkObserve(type);
    if (type === connection.NetBearType.BEARER_WIFI) {
      this.wifiStateObserve();
    }
  })
}

2.2 關閉網絡監聽

public stopNetObserve(netType: connection.NetBearType) {
  this.connectionMap.get(netType).unregister(() => {
    logger.info("Success unregister:" + netType.toString());
  })
}

2.3 網絡狀態監聽

networkObserve(netType: connection.NetBearType) {
  let netConnection: connection.NetConnection = connection.createNetConnection({
    netCapabilities: {
      bearerTypes: [netType]
    }
  })
  netConnection.register((error: BusinessError) => {
    let result = true;
    if (error) {
      logger.info("NetUtils", "NetType :" + netType + ", network register failed: " + JSON.stringify(error));
      result = false;
    }
    logger.info("NetUtils", "NetType :" + netType + ", network register succeed");
    this.postEvent(NetworkEventName.NetObserverRegister, result, netType);
  });
 
  netConnection.on('netCapabilitiesChange', (data: connection.NetCapabilityInfo) => {
    logger.info("NetUtils", "NetType :" + netType + ", network netCapabilitiesChange: " + JSON.stringify(data));
    this.postEvent(NetworkEventName.NetCapabilitiesChange, data, netType);
  })
 
  netConnection.on("netAvailable", (data: connection.NetHandle) => {
    logger.info("NetUtils", "NetType :" + netType + ", network succeeded to get netAvailable: " + JSON.stringify(data));
    // 檢查默認數據網絡是否被激活,使用同步方式返回接口,如果被激活則返回true,否則返回false。
    this.postEvent(NetworkEventName.NetAvailable, connection.hasDefaultNetSync(), netType);
  });
 
  // 訂閲網絡阻塞狀態事件,當網絡阻塞時,如網絡性能下降、數據傳輸出現延遲等情況時,會觸發該事件
  netConnection.on('netBlockStatusChange', (data: connection.NetBlockStatusInfo) => {
    logger.info("NetUtils", "NetType :" + netType + ", network netBlockStatusChange " + JSON.stringify(data));
    this.postEvent(NetworkEventName.NetBlock, data, netType)
  });
 
  netConnection.on('netConnectionPropertiesChange', (data: connection.NetConnectionPropertyInfo) => {
    logger.info("NetUtils", "NetType :" + netType + ", network netConnectionPropertiesChange " + JSON.stringify(data));
    this.postEvent(NetworkEventName.NetConnectionPropertiesChange, data, netType);
  });
 
  // 訂閲網絡丟失事件,當網絡嚴重中斷或正常斷開時觸發該事件
  // 網絡丟失是指網絡嚴重中斷或正常斷開事件,當斷開Wi-Fi時,是屬於正常斷開網絡連接,會觸發netLost事件
  netConnection.on('netLost', (data: connection.NetHandle) => {
    this.postEvent(NetworkEventName.NetLost, true, netType)
    logger.info("NetUtils", "NetType :" + netType + ", Succeeded to get netLost: " + JSON.stringify(data));
  });
 
  // 訂閲網絡不可用事件,當網絡不可用時觸發該事件
  // 網絡不可用是指網絡不可用事件,當連接的網絡不能使用時,會觸發netUnavailable事件。
  netConnection.on('netUnavailable', () => {
    logger.info("NetUtils", "NetType :" + netType + ", Succeeded to get unavailable net event");
    this.postEvent(NetworkEventName.NetUnavailable, true, netType);
  });
 
  this.connectionMap.set(netType, netConnection);
}

2.4 通過emitter將網絡監聽狀態傳遞給頁面

private postEvent(eventName: NetworkEventName, status: NetworkData, netType?: connection.NetBearType,
  priority?: emitter.EventPriority) {
  this.emitterEvent.priority = priority;
  emitter.emit(this.emitterEvent, {
    data: new NetEventData(eventName, status, netType)
  })
}

如果您想系統深入地學習 HarmonyOS 開發或想考取HarmonyOS認證證書,歡迎加入華為開發者學堂:

請點擊→:  HarmonyOS官方認證培訓

HarmonyOS應用開發案例:網絡狀態監聽_.net_02