README_zh.md
1# 网络状态监听
2
3### 介绍
4
5本示例介绍如何使用[@kit.NetworkKit](https://docs.openharmony.cn/pages/v5.0/zh-cn/application-dev/network/net-mgmt-overview.md)接口监听手机网络状态,根据不同的网络状态对视频进行播放、暂停处理等操作。
6
7### 效果预览
8
9| 视频播放 | 网络设置 |
10|------------------------------------------------------|-------------------------------------------------------|
11| <img src="./screenshot/video_play.jpg" width="200"/> | <img src="./screenshot/net_setting.jpg" width="200"/> |
12
13**使用说明**
14
151. 打开应用进入视频播放页面,视频不播放。
162. 点击自动播放设置按钮,进入设置页面,开启或者关闭3G/4G/5G自动播放、WI-FI自动播放。
173. 开启或者关闭蜂窝网络或者WI-FI开关,查看视频是否根据自动播放设置页面中的设置播放或者暂停。
184. 返回首页瀑布流或者杀死应用重新进入首页,查看视频是否根据自动播放设置中的设置和手机网络状态播放或者暂停。
19
20
21### 工程目录
22
23 ```
24 |entry/src/main/ets
25 | |---entryablity
26 | | |---EntryAbility.ts // 程序入口类
27 | |---pages
28 | | |---SettingPage.ets // 自动播放设置页面
29 | | |---VideoPage.ets // 视频播放页面
30 | |---utils
31 | | |---EmitterData.ets // emitter数据结构
32 | | |---Logger.ets // 日志打印
33 | | |---NetUtils.ets // 网络监听工具类
34 ```
35
36### 实现思路
37
381. 页面实现
39
40 1.1 在[VideoPage](entry/src/main/ets/pages/VideoPage.ets)中添加Video组件,设置在线视频播放
41
42 ```
43 Video({
44 src: "https://v.oh4k.com/muhou/2022/07/20220704-RIUq3Z.mp4",
45 controller: this.controller
46 }).height(300)
47 .width('100%')
48 .autoPlay(this.autoPlay())
49 ```
50
51 1.2 在aboutToAppear方法中添加网络状态监听,并开始监听WI-FI和蜂窝数据的状态。
52
53 ```
54 emitter.on(NetUtils.getInstance().getEmitterEvent(), (data: emitter.EventData) => {
55 if (data) {
56 this.netObserver(data);
57 } else {
58 logger.info("aboutToAppear emitter on error, data is undefined.");
59 }
60 });
61 NetUtils.getInstance().startNetObserve(connection.NetBearType.BEARER_CELLULAR, connection.NetBearType.BEARER_WIFI);
62 ```
63
64 1.3 在netObserver方法中,添加不同网络状态的处理。
65
66 ```
67 netObserver(data: emitter.EventData) {
68 ...
69 let eventName: NetworkEventName = netEventData.eventName ?? -1;
70 switch (eventName) {
71 case NetworkEventName.NetAvailable:
72 if (netEventData.netType === connection.NetBearType.BEARER_WIFI) {
73 if (this.wifiAutoPlay) {
74 this.startPlay();
75 }
76 }
77 break;
78 case NetworkEventName.NetBlock:
79 break;
80 case NetworkEventName.NetLost:
81 if (netEventData.netType === connection.NetBearType.BEARER_WIFI) {
82 this.wifiInterrupt();
83 }
84 break;
85 case NetworkEventName.NetUnavailable:
86 if (netEventData.netType === connection.NetBearType.BEARER_WIFI) {
87 this.wifiInterrupt();
88 }
89 break;
90 case NetworkEventName.WeakNet:
91 // 如果是弱网环境
92 if (netEventData.status) {
93 Prompt.showToast({ message: "当前网络环境较差,视频播放可能出现卡顿" });
94 }
95 break;
96 default:
97 logger.debug("当前网络状态:" + eventName);
98 break;
99 }
100 }
101 ```
102
103 1.4 在[SettingPage](entry/src/main/ets/pages/SettingPage.ets)中添加Toggle组件,管理自动播放设置。
104
105 ```
106 Toggle({ type: ToggleType.Switch, isOn: this.cellularAutoPlay })
107 .selectedColor('#007DFF')
108 .switchPointColor('#FFFFFF')
109 .onChange((isOn: boolean) => {
110 logger.info('Component status:' + isOn);
111 AppStorage.setOrCreate('cellular_auto_play', isOn);
112 PersistentStorage.persistProp('cellular_auto_play', isOn);
113 })
114 .width('10%')
115 ```
116
1172. 网络状态监听工具类[NetUtils](entry/src/main/ets/utils/NetUtils.ets)实现,通过[@kit.NetworkKit](https://docs.openharmony.cn/pages/v5.0/zh-cn/application-dev/network/net-mgmt-overview.md)接口监听网络状态,然后通过emitter将监听结果传递给页面。
118
119 2.1 开启网络监听
120
121
122 ```
123 public startNetObserve(...netType: connection.NetBearType[]) {
124 netType.forEach((type: connection.NetBearType) => {
125 this.networkObserve(type);
126 if (type === connection.NetBearType.BEARER_WIFI) {
127 this.wifiStateObserve();
128 }
129 })
130 }
131 ```
132
133 2.2 关闭网络监听
134
135 ```
136 public stopNetObserve(netType: connection.NetBearType) {
137 this.connectionMap.get(netType).unregister(() => {
138 logger.info("Success unregister:" + netType.toString());
139 })
140 }
141 ```
142
143 2.3 网络状态监听
144
145 ```
146 networkObserve(netType: connection.NetBearType) {
147 let netConnection: connection.NetConnection = connection.createNetConnection({
148 netCapabilities: {
149 bearerTypes: [netType]
150 }
151 })
152 netConnection.register((error: BusinessError) => {
153 let result = true;
154 if (error) {
155 logger.info("NetUtils", "NetType :" + netType + ", network register failed: " + JSON.stringify(error));
156 result = false;
157 }
158 logger.info("NetUtils", "NetType :" + netType + ", network register succeed");
159 this.postEvent(NetworkEventName.NetObserverRegister, result, netType);
160 });
161
162 netConnection.on('netCapabilitiesChange', (data: connection.NetCapabilityInfo) => {
163 logger.info("NetUtils", "NetType :" + netType + ", network netCapabilitiesChange: " + JSON.stringify(data));
164 this.postEvent(NetworkEventName.NetCapabilitiesChange, data, netType);
165 })
166
167 netConnection.on("netAvailable", (data: connection.NetHandle) => {
168 logger.info("NetUtils", "NetType :" + netType + ", network succeeded to get netAvailable: " + JSON.stringify(data));
169 // 检查默认数据网络是否被激活,使用同步方式返回接口,如果被激活则返回true,否则返回false。
170 this.postEvent(NetworkEventName.NetAvailable, connection.hasDefaultNetSync(), netType);
171 });
172
173 // 订阅网络阻塞状态事件,当网络阻塞时,如网络性能下降、数据传输出现延迟等情况时,会触发该事件
174 netConnection.on('netBlockStatusChange', (data: connection.NetBlockStatusInfo) => {
175 logger.info("NetUtils", "NetType :" + netType + ", network netBlockStatusChange " + JSON.stringify(data));
176 this.postEvent(NetworkEventName.NetBlock, data, netType)
177 });
178
179 netConnection.on('netConnectionPropertiesChange', (data: connection.NetConnectionPropertyInfo) => {
180 logger.info("NetUtils", "NetType :" + netType + ", network netConnectionPropertiesChange " + JSON.stringify(data));
181 this.postEvent(NetworkEventName.NetConnectionPropertiesChange, data, netType);
182 });
183
184 // 订阅网络丢失事件,当网络严重中断或正常断开时触发该事件
185 // 网络丢失是指网络严重中断或正常断开事件,当断开Wi-Fi时,是属于正常断开网络连接,会触发netLost事件
186 netConnection.on('netLost', (data: connection.NetHandle) => {
187 this.postEvent(NetworkEventName.NetLost, true, netType)
188 logger.info("NetUtils", "NetType :" + netType + ", Succeeded to get netLost: " + JSON.stringify(data));
189 });
190
191 // 订阅网络不可用事件,当网络不可用时触发该事件
192 // 网络不可用是指网络不可用事件,当连接的网络不能使用时,会触发netUnavailable事件。
193 netConnection.on('netUnavailable', () => {
194 logger.info("NetUtils", "NetType :" + netType + ", Succeeded to get unavailable net event");
195 this.postEvent(NetworkEventName.NetUnavailable, true, netType);
196 });
197
198 this.connectionMap.set(netType, netConnection);
199 }
200 ```
201 2.4 通过emitter将网络监听状态传递给页面
202
203 ```
204 private postEvent(eventName: NetworkEventName, status: NetworkData, netType?: connection.NetBearType,
205 priority?: emitter.EventPriority) {
206 this.emitterEvent.priority = priority;
207 emitter.emit(this.emitterEvent, {
208 data: new NetEventData(eventName, status, netType)
209 })
210 }
211 ```
212
213### 相关权限
214
215| 权限名 | 权限说明 | 级别 |
216|---|---|---|
217|ohos.permission.INTERNET|允许使用Internet网络|normal|
218|ohos.permission.GET_WIFI_INFO|允许应用获取Wi-Fi信息|normal|
219|ohos.permission.GET_NETWORK_INFO|允许应用获取数据网络信息|normal|
220
221### 依赖
222
223本示例需要在有流量卡/Wi-Fi的设备上使用。
224
225### 约束与限制
226
2271. 本示例仅支持标准系统上运行。
228
2292. 本示例为Stage模型,从API version 12开始支持。SDK版本号:5.0.0.71 Release,镜像版本号:OpenHarmony 5.0.1.107。
230
2313. 本示例需要使用DevEco Studio 5.0.2 Release (Build Version: 5.0.7.200, built on January 23, 2025)编译运行。
232
233### 下载
234
235如需单独下载本工程,执行如下命令:
236
237```shell
238git init
239git config core.sparsecheckout true
240echo code/BasicFeature/Connectivity/NetworkObserver/ > .git/info/sparse-checkout
241git remote add origin https://gitee.com/openharmony/applications_app_samples.git
242git pull origin master
243```
244
245