
鸿蒙6.0应用开发——网络状态管理文章目录鸿蒙6.0应用开发——网络状态管理概述连接到指定网络场景场景描述实现方案开发步骤网络状态感知场景场景描述实现方案开发步骤概述Network Kit提供常用的网络信息查询与连接管理功能包括获取网络类型、检查网络可用性、监听网络状态变化、查询Wi-Fi及蜂窝网络信息等。这些能力帮助开发者灵活应对复杂多变的网络环境精准实现各类场景需求显著提升用户的网络使用体验。连接到指定网络场景场景描述在特定业务场景中如企业或校园内网应用必须通过指定的网络连接到专用服务器以获取关键数据。若连接指定网络失败将直接导致网络配置中断、身份认证受阻或核心资源无法访问从而中断业务流程。本章将通过以下示例介绍如何连接到指定的Wi-Fi。该示例具备以下功能判断设备是否已连接到指定的Wi-Fi获取系统扫描的Wi-Fi列表通过点击Wi-Fi列表连接到相应的Wi-Fi图1连接到指定网络效果图实现方案连接到指定Wi-Fi场景主要通过ohos.wifiManager (WLAN)模块结合ohos.net.connection (网络连接管理)模块相关API来实现。通过ohos.wifiManager模块检查Wi-Fi是否启用获取系统扫描的Wi-Fi列表选中指定Wi-Fi后发起连接请求通过ohos.net.connection模块检测网络连通性判断是否需要进行登录认证如 Portal 认证才能正常访问网络。流程图如下开发步骤网络权限声明在进行网络相关操作前需在应用的module.json5配置文件中声明所需权限。涉及的权限包括ohos.permission.GET_NETWORK_INFO用于获取网络信息如默认网络、网络类型等。ohos.permission.GET_WIFI_INFO用于获取Wi-Fi相关信息如Wi-Fi是否打开、Wi-Fi列表等。ohos.permission.SET_WIFI_INFO用于执行Wi-Fi连接操作。ohos.permission.INTERNET用于访问Internet网络。{module:{// ...requestPermissions:[{name:ohos.permission.INTERNET,// ...},{name:ohos.permission.GET_NETWORK_INFO,// ...},{name:ohos.permission.SET_WIFI_INFO,// ...},{name:ohos.permission.GET_WIFI_INFO,// ...},// ...]}}获取Wi-Fi信息判断是否连接到指定Wi-Fi先使用getDefaultNetSync()接口判断默认网络是否连接并通过getNetCapabilitiesSync()方法获取默认连接网络类型。若网络类型为Wi-Fi则使用getLinkedInfoSync()方法获取当前连接的Wi-Fi信息该信息包含SSID等内容。将获取到的SSID与指定Wi-Fi的SSID进行比对若一致则表示已连接到指定Wi-Fi。checkNetwork():void{try{// Use the synchronization method to obtain the default activated data network handle (default network)letnetHandleconnection.getDefaultNetSync();if(netHandle.netId0){// If there is no network connected, the netid of the obtained netHandler is 0showToast(this.uiContext,$r(app.string.no_network_tips));return;}// Obtain the capability information of the network corresponding to the netHandleletnetCapabilityconnection.getNetCapabilitiesSync(netHandle);letnetworkCapnetCapability.networkCap||[];letbearerTypes:connection.NetBearType[]netCapability.bearerTypes;letisWifibearerTypes.includes(connection.NetBearType.BEARER_WIFI);if(!isWifi){showToast(this.uiContext,$r(app.string.network_is_not_wifi));return;}// The network type is WIFI to get network connection informationletlinkedInfowifiManager.getLinkedInfoSync();letssid:stringlinkedInfo.ssid;if(ssidTARGET_WIFI_SSID){// Connected to the target wifi// ...}else{showToast(this.uiContext,$r(app.string.not_connected_spec_wifi));}}catch(err){leterrorerrasBusinessError;Logger.error(TAG,checkNetwork err, code:${error.code}, message:${error.message});}}代码逻辑走读获取默认网络句柄使用connection.getDefaultNetSync()方法获取默认激活的数据网络句柄。如果网络句柄的netId为0表示没有网络连接显示无网络提示。获取网络能力信息使用connection.getNetCapabilitiesSync(netHandle)方法获取网络对应的能力信息。检查网络能力中是否包含Wi-Fi类型如果不包含显示非Wi-Fi网络提示。获取Wi-Fi连接信息如果网络类型是Wi-Fi使用wifiManager.getLinkedInfoSync()获取网络连接信息。检查连接的SSID是否与目标SSID匹配如果匹配则表示已连接到指定Wi-Fi否则显示未连接到特定Wi-Fi的提示。异常处理使用try-catch块捕获可能的异常并记录错误信息。通过getNetCapabilitiesSync()方法获取网络能力信息对象其networkCap属性包含网络的具体能力。若networkCap中包含connection.NetCap.NET_CAPABILITY_VALIDATED则表示网络具备访问互联网的能力即网络可用若networkCap中包含connection.NetCap.NET_CAPABILITY_PORTAL则说明网络需要认证登录之后才能正常使用。if(ssidTARGET_WIFI_SSID){// Connected to the target wifiif(networkCap.includes(connection.NetCap.NET_CAPABILITY_VALIDATED)){showToast(this.uiContext,$r(app.string.connected_to_spec_wifi));}elseif(networkCap.includes(connection.NetCap.NET_CAPABILITY_PORTAL)){// Login verification is required for the current networkshowToast(this.uiContext,$r(app.string.network_need_auth));}else{showToast(this.uiContext,$r(app.string.result_network_unavailable));}}else{showToast(this.uiContext,$r(app.string.not_connected_spec_wifi));}获取系统扫描Wi-Fi列表在获取Wi-Fi列表之前需要通过isWifiActive()方法判断Wi-Fi开关是否已打开。如果已打开则通过调用getScanInfoList()方法获取系统扫描附近的Wi-Fi网络并返回一个包含所有扫描到的Wi-Fi信息的数组。数组中的每个元素包含了Wi-Fi的SSID、加密类型、信号强度等详细信息。getScanList():void{try{letisWifiActivewifiManager.isWifiActive();if(!isWifiActive){showToast(this.uiContext,$r(app.string.turn_on_wlan_tips));return;}this.getLinkedInfo();lettempwifiManager.getScanInfoList();if(temp.length0){// Remove duplicate WiFi datathis.scanInfoListthis.uniqueBySsid(temp);Logger.info(TAG,getScanList length:${this.scanInfoList.length});}}catch(err){leterrorerrasBusinessError;Logger.error(TAG,getScanList err, code:${error.code}, message:${error.message});}}代码逻辑走读定义getScanList方法无参数无返回值。尝试执行以下操作调用wifiManager.isWifiActive()检查当前WiFi是否激活将结果存储在isWifiActive变量中。如果isWifiActive为false调用showToast方法显示提示信息并使用return语句终止方法执行。如果WiFi已激活调用getLinkedInfo方法获取已链接的WiFi信息。调用wifiManager.getScanInfoList()获取扫描到的WiFi列表将结果存储在temp变量中。如果temp的长度大于0表示有扫描到的WiFi调用uniqueBySsid方法去除重复项并将结果存储在scanInfoList中。使用Logger.info记录scanInfoList的长度。如果尝试块中出现异常捕获异常并将其转换为BusinessError类型使用Logger.error记录错误代码和错误信息。连接到指定Wi-Fi首先创建一个包含要连接的Wi-Fi的SSID、密码及安全类型如WPA2_PSK等信息的Wi-Fi配置对象使用addCandidateConfig()方法传入该配置对象以添加候选网络配置。然后调用connectToCandidateConfig()方法发起连接请求。connectWifi(){// Add a candidate networkletconfig:wifiManager.WifiDeviceConfig{ssid:this.ssid,preSharedKey:this.wifiPassword,securityType:this.securityType}try{wifiManager.addCandidateConfig(config).then(result{Logger.info(TAG,addCandidateConfig success, networkId:${result});// Connect to a certain wifiwifiManager.connectToCandidateConfig(result);});}catch(err){Logger.error(TAG,connectWifi error:${JSON.stringify(err)});}}网络状态感知场景场景描述本章以网络视频播放场景为例围绕网络状态感知展开介绍如何在监听到网络状态变化后动态调整视频播放行为以优化播放体验。本章实现的网络视频播放优化体验如下当网络从Wi-Fi切换到蜂窝网络及时暂停播放并提醒用户已切换到蜂窝网络以避免产生流量费用。当网络从蜂窝切换到的Wi-Fi时自动播放之前暂停的视频让用户无需手动操作即可继续观看。当监听到弱网状态时提示用户当前网络不佳。同时系统可能会根据当前的网络质量情况切换网络。当监听到网络中断时提示用户检查网络连接以避免视频突然中断带来的不良体验。实现方案网络状态感知的实现方案以实时监测网络状态变化并联动视频播放业务的调整为核心主要依赖于ohos.net.connection网络连接管理模块和netQuality网络质量模块来实现。本章重点介绍网络视频播放时对网络状态变化的感知视频播放的具体实现可参考示例代码章节。为避免网络波动影响播放流畅性建议开发者进行缓存处理。网络状态的监听主要通过以下接口实现on(‘netCapabilitiesChange’)订阅网络能力变化事件当网络类型切换如从Wi-Fi切换到蜂窝网络、网络状态从无到有等该事件将被触发。on(‘netLost’)订阅网络丢失事件当网络严重中断或正常断开时触发该事件。on(‘netUnavailable’)订阅网络不可用事件当网络不可用时触发该事件。on(‘netAvailable’)订阅网络可用事件当网络可用时触发该事件。netQuality.on( ‘netSceneChange’)订阅网络场景信息如从正常网络进入到弱网环境。以视频播放场景为例网络状态感知体验如下网络状态感知网络类型变化网络能力变化网络能力变化网络能力变化网络能力变化网络能力变化Wi-Fi切蜂窝蜂窝切换Wi-Fi弱网场景网络断开网络不可用网络可用应用处理暂停播放提示将使用流量播放正常播放弹窗提示网络不佳。开发者可以提供切换视频清晰度播放的功能在弱网场景下提示用户切换清晰度。弹窗提示网络已断开视频加载失败后展示错误页面弹窗提示网络不可用视频加载失败后展示错误页面和网络类型变化规格一致开发步骤订阅网络可用/不可用事件使用on(‘netAvailable’)订阅网络可用事件通知接收到网络可用通知时检测当前网络是否具备访问Internet的能力。若网络能正常访问Internet且此前因网络问题导致播放失败则重置播放器并继续播放视频。import{connection}fromkit.NetworkKit;// Create a NetConnection objectthis.netConconnection.createNetConnection();// Subscribe to a network available event that triggers when the network is availablethis.netCon.on(netAvailable,(data:connection.NetHandle){Logger.info(TAG,on netAvailable, Succeeded to get netAvailable:${JSON.stringify(data)});this.isNetAvailableNetworkUtil.isNetworkAvailable();this.isCellularNetworkUtil.isCellular();if(this.isNetAvailablethis.isPlayError!this.isCellular){this.controller.reset();}});publicstaticisNetworkAvailable():boolean{try{letnetHandleconnection.getDefaultNetSync();if(netHandle.netId0){// If there is no network connected, the netid of the obtained netHandler is 0returnfalse;}letnetCapabilityconnection.getNetCapabilitiesSync(netHandle);letnetworkCaps:connection.NetCap[]netCapability.networkCap||[];returnnetworkCaps.includes(connection.NetCap.NET_CAPABILITY_VALIDATED);}catch(err){leterrorerrasBusinessError;Logger.error(TAG,getNetworkType err, errCode:${error.code}, error mesage:${error.message});}returnfalse;}使用on(‘netUnavailable’)订阅网络不可用事件通知接收到网络不可用事件时使用Toast弹窗提示用户网络不可用。// Subscribe to a network unavailability event that triggers when the network is unavailablethis.netCon.on(netUnavailable,(){Logger.info(TAG,on netUnavailable, Succeeded to get unavailable net event);this.isNetAvailablefalse;showToast(this.uiContext,$r(app.string.result_network_unavailable));});订阅网络能力变化事件通过on(‘netCapabilitiesChange’)方法可以订阅Wi-Fi和蜂窝网络切换的事件通知当网络切换为蜂窝时暂停播放否则继续播放视频。// Subscribe to network capability change events that trigger when network capability changes,// such as from no network to network with network, or when switching from WIFI to cellularthis.netCon.on(netCapabilitiesChange,(data:connection.NetCapabilityInfo){Logger.info(TAG,on netCapabilitiesChange, Succeeded to get netCapabilitiesChange:${JSON.stringify(data)});if(data.netCap.bearerTypes.includes(connection.NetBearType.BEARER_CELLULAR)){// For cellular networks, pause playbackthis.isCellulartrue;this.isShowControllerfalse;this.controller.pause();showToast(this.getUIContext(),$r(app.string.current_cellular_tips))this.isShowGoOntrue;}else{this.isCellularfalse;this.isShowControllertrue;this.controller.start();this.isShowGoOnfalse;}});从Wi-Fi切换为蜂窝网络效果图如下订阅网络丢失事件通过on(‘netLost’)方法可以订阅网络丢失的事件通知使用Toast提示用户网络已断开。// Subscribe to a network loss event, triggered when the network is severely interrupted or normally disconnected,// and the network interruption pauses playbackthis.netCon.on(netLost,(data:connection.NetHandle){Logger.info(TAG,on netLost, Succeeded to get netLost:${JSON.stringify(data)});this.isNetAvailablefalse;this.isCellularfalse;showToast(this.uiContext,$r(app.string.network_disconnect_tips));});网络断开时效果图当网络断开时将继续播放视频缓存缓存播放完毕后将触发Video组件的onError方法。若此时网络仍未连接需提示用户检查网络。Video({src:this.videoUrl,controller:this.controller})// ....onError((){Logger.error(TAG,Video onError);this.lastTimethis.currentTime;this.isShowControllerfalse;this.isPlayErrortrue;this.isPlayingfalse;this.isNetAvailableNetworkUtil.isNetworkAvailable();})播放错误时效果图订阅网络状态变化通知接下来需要调用register()接口用来订阅指定的网络状态变化通知该接口需在on()方法调用之后使用。例如若指定的网络可用将触发on(‘netAvailable’)、on(‘netCapabilitiesChange’)回调若超时时间内网络不可用将触发on(‘netUnavailable’)回调。若断网将触发on(‘netLost’)回调。this.netCon.register((error:BusinessError){if(error){Logger.error(TAG,networkListen fail:${JSON.stringify(error)});}});订阅网络场景变化使用netQuality.on(‘netSceneChange’)方法订阅网络场景变化通知当网络为弱信号场景weakSignal或者拥塞场景congestion时使用Toast弹窗提示用户当前网络不佳。建议开发者实现多种不同清晰度资源切换的功能在此场景下提示用户切换清晰度。import{netQuality}fromkit.NetworkBoostKit;onNetSceneChange(){// Subscribe to network scene informationtry{netQuality.on(netSceneChange,(list:netQuality.NetworkScene[]){Logger.info(TAG,on netSceneChange, Succeeded receive netSceneChange info:${list.length});if(list.length0){list.forEach((networkScene){if(networkScene.sceneweakSignal||networkScene.scenecongestion){this.promptAction.showToast({message:$r(app.string.network_bad_tips)});}});}});}catch(err){Logger.error(TAG,on netSceneChange err:${JSON.stringify(err)});}}取消订阅网络变化/取消订阅场景变化通知在退出页面时通过调用unregister()取消订阅网络状态变化通知使用netQuality.off(‘netSceneChange’)取消订阅场景变化。aboutToDisappear():void{// Unsubscribe from network status changesthis.netCon?.unregister((err:BusinessError){if(err){Logger.error(TAG,unregister failed, err:${JSON.stringify(err)});}});// Unsubscribe from network scenario informationtry{netQuality.off(netSceneChange);}catch(err){Logger.error(TAG,off netSceneChange err:${JSON.stringify(err)});}}