基于原生能力的网络状态感知

场景一:APP获取当前连接网络信息

方案

1.以下属性基于netConn对象的getNetCapabilities函数,获取到的netCapabilities对象获取。

 

网络类型

上行带宽

下行带宽

网络能力

属性

bearerTypes

linkUpBandwidthKbps

linkDownBandwidthKbps

networkCap

类型

Array<NetBearType>

number

number

Array<NetCap>

单位

\

kb/s

kb/s

\

2.以下属性基于netConn的getConnectionProperties获取到的ConnectionProperties对象中获取。

 

网卡名称

所属域

最大传输单元

链路信息

路由信息

网络地址

属性

interfaceName

domains

mtu

linkAddresses

routes

dnses

类型

string

string

number

Array<LinkAddress>

Array<RouteInfo>

Array<NetAddress>

单位

\

\

bytes

\

\

\

3.基于@ohos.net.statistics (流量管理)能力提供的getUidTxBytes接口,获取应用实时网速(bytes)。

核心代码

1.基于netConn对象的getNetCapabilities函数,获取netCapabilities对象。

let netHandle = await connection.getDefaultNet();
let netCapabilities: connection.NetCapabilities = await connection.getNetCapabilities(netHandle);

2.基于netCapabilities对象获取上下行带宽(单位kb/s,0为无法评估当前网络带宽)。

// 获取上行带宽
let upKbps = netCapabilities.linkUpBandwidthKbps;
// 获取下行带宽
let downKbps = netCapabilities.linkDownBandwidthKbps ;

3.基于netCapabilities获取网络类型。

tips:当Wi-Fi和蜂窝同时连接的时候,通过网络能力获取bearType实际只返回Wi-Fi的状态信息,此为现象为系统规格。

let type:connection.NetBearType = netCapabilities.bearerTypes[0];

获取到的返回值和如下枚举对应:

名称

说明

BEARER_CELLULAR

0

蜂窝网络

BEARER_WIFI

1

Wi-Fi网络

BEARER_ETHERNET

3

以太网网络

BEARER_VPN

4

VPN网络

4.基于netCapabilities获取网络具体能力。

let cap:Array<NetCap> = netCapabilities.networkCap;

获取到的返回值和如下枚举对应:

名称

说明

NET_CAPABILITY_MMS

0

表示网络可以访问运营商的MMSC(Multimedia Message Service,多媒体短信服务)发送和接收彩信

NET_CAPABILITY_NOT_METERED

11

表示网络流量未被计费

NET_CAPABILITY_INTERNET

12

表示该网络应具有访问Internet的能力,该能力由网络提供者设置

NET_CAPABILITY_NOT_VPN

15

表示网络不使用VPN(Virtual Private Network,虚拟专用网络)

NET_CAPABILITY_VALIDATED

16

表示该网络访问Internet的能力被网络管理成功验证,该能力由网络管理模块设置

NET_CAPABILITY_PORTAL12+

17

表示系统发现该网络存在强制网络门户,需要用户登陆认证,该能力由网络管理模块设置

5.基于netConn的getConnectionProperties函数获取网络连接信息。

// 获取网卡名称
let interfaceName: string = properties.interfaceName;
// 获取所属域
let domains: string = properties.domains;
// 获取最大传输单元
let mtu: number= properties.mtu;
// 获取链路信息
let linkAddresses: Array<LinkAddress> = properties.linkAddresses;
// 获取路由信息
let routes: Array<RouteInfo> = properties.routes;
// 获取网络地址
let dnses: Array<NetAddress> = properties.dnses;

6.基于@ohos.net.statistics能力,获取当前应用的网络传输速度。

获取应用的网络传输速度依赖于getUidTxBytes/getUidRxBytes函数,其中函数入参uid为应用唯一标识,和应用一一对应。

Tips: 注意uid在应用卸载重装后会发生变化。

// 导入模块
import { statistics } from '@kit.NetworkKit';
import bundleManager from '@ohos.bundle.bundleManager';
 
// 获取应用程序uid(设备上该应用的唯一标识,和应用一一对应,卸载重装后会发生变化)
let bundleFlags = bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_APPLICATION;
let bundleInfo = await bundleManager.getBundleInfoForSelf(bundleFlags);
let uid = bundleInfo.appInfo.uid;
 
// 通过应用uid获取当前应用的上下行带宽
let txBytes = statistics.getUidTxBytes(uid);
let rxBytes = statistics.getUidRxBytes(uid);

场景二:APP感知当前连接网络的状态

方案

基于@ohos.net.connection模块能力,监听网络可用,网络切换,网络不可用,网络丢失等事件,使用前需要调用register开启监听,监听结束后需要调用unregister关闭当前监听请求。

Tips: 各事件监听没有各自独立的off函数,也就是说所有使用该能力监听的事件,只能一起随着unregister的调用关闭监听。

各种场景切换说明:

  1. 当Wi-Fi以及蜂窝都断开的情况下,设备从无网络到有网络会触发netAvailable事件,netCapabilitiesChange事件和netConnectionPropertiesChange事件。
  2. 当Wi-Fi或蜂窝某一个正常连接的情况下,设备从有网络到无网络状态会触发netLost事件。
  3. 当Wi-Fi和蜂窝都正常连接的情况下,设备从Wi-Fi到蜂窝会触发netLost事件(Wi-Fi丢失)之后触发 netAvaliable事件(蜂窝可用)。

核心代码

回调参数解析

1.下列监听回调中connection.NetHandle类型参数data为数据网络句柄,主要关注其netid属性,此属性可以对网络进行唯一标识。

例如:通过监听on('netAvailable'),保存当前网络的netId,当切换网络时回调该接口,通过比对netId判断是否同一网络。

2.netCapabilitiesChange回调中的参数data为connection.NetCapabilityInfo类型,包含netHandle和netCap两个属性,其中netHandle属性同其它回调一样,此处不再赘述。netCap属性用来存储数据网络的传输能力和承载类型,主要关注其中networkCap(网络能力)和bearType(网络类型)两个属性,用来观察当前网络的能力和类型变化。

// 无效值常量
private static COMMON_INIT_VAL: number = -1
// 保存上次可用的netId
private lastAvailableNetId: number = Index.COMMON_INIT_VAL;
 
//监听网络是否可用
this.netConn.on('netAvailable', (data: connection.NetHandle) => {
  if (this.lastAvailableNetId === Index.COMMON_INIT_VAL) {
    this.lastAvailableNetId = data.netId;
  } else if (this.lastAvailableNetId === data.netId) { // 当前再次恢复可用的网络和之前的网络为同一网络
    // TODO
  } else { // 当前再次恢复可用的网络和之前的网络为不同网络
    // TODO
  }
})
 
//网络丢失(比如网络断开)
this.netConn.on("netLost",(data: connection.NetHandle) => {
  console.log("net lost" + JSON.stringify(data))
})
 
//网络不可用(比如已连接Wi-Fi,但是Wi-Fi图标上有感叹号)
this.netConn.on("netUnavailable", () => {
  console.log("net unavailable id is " + this.lastAvailableNetId);
})
 
this.netConn.on('netCapabilitiesChange', (data: connection.NetCapabilityInfo) => {
  console.log('net capabilities change: ' + JSON.stringify(data));
  let currentNetCap = data.netCap.networkCap
  // TODO 对比及对比出现异同的处理逻辑由开发者自定义
 
  // 获取当前网络类型,可与之前保存的网络类型做对比(之前在哪里保存,由开发者自定义)
  let currentBearType = data.netCap.bearerTypes;
  // TODO 对比及对比出现异同的处理逻辑由开发者自定义
 
  // 获取netid,与之前保存的做对比
  let currentNetId = data.netHandle.netId;
  // TODO 对比及对比出现异同的处理逻辑由开发者自定义
});
 
listenNetConnEvent(): void {
  //开启监听事件
  this.netConn.register((error: BusinessError) => {
  console.log('netConn register error: ' + JSON.stringify(error));
});
 
// 使用unregister接口取消订阅
this.netConn.unregister((error: BusinessError) => {
  console.log('netConn unregister error: ' + JSON.stringify(error));
});
}

常见问题

1.如何实现弱网自动切换?

应用中实时感知当前网络速度,在网络可用且网速低于某一阈值(由用户根据自己的实际场景定义)的情况下由应用进行切换。

2.网络管理部分的系统原生能力是否支持应用主动进行网络切换?

不支持,仅支持通过回调感知系统网络切换。

说明:

netConn均代表connection.NetConnection对象,该对象在创建时,根据关注的网络类型不同有所区别。当关注蜂窝网络时,需要传入相关的网络特征,Wi-Fi则不需要。

Wi-Fi:

let netConn = connection.createNetConnection();

蜂窝:

let netConn= netConn.createNetConnection({
  netCapabilities: {
    bearerTypes: [connection.NetBearType.BEARER_CELLULAR]
  }
});

  • 25
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值