
场景介绍 应用可以通过观察蜂窝网络状态变化,来接收最新蜂窝网络服务状态信息、信号信息等。 接口说明 RadioStateObserver 类中提供了观察蜂窝网络状态变化的方法,为了能够实时观察蜂窝网络状态变化,应用必须包含以下权限。 观察状态名称 权限名称 网络状态信息(NETWORK_STATE) ohos.permission.GET_NETWORK_INFO 信号信息(SIGNAL_INFO) NA 需要使用 RadioInfoManager 的如下接口将继承 RadioStateObserver 类的对象注册到系统服务: 接口名 观察事件的掩码 描述 addObserver OBSERVE_MASK_NETWORK_STATE 观察蜂窝网络驻网状态信息。 OBSERVE_MASK_SIGNAL_INFO 观察蜂窝网络信号信息。 removeObserver N/A 停止观察所有状态的变化。 开发步骤 添加观察事件 调用 RadioInfoManager 的 getInstance 接口,获取到 RadioInfoManager 实例。 创建继承 RadioStateObserver 的类 MyRadioStateObserver,并覆写状态变化回调方法。 创建 MyRadioStateObserver 的对象 observer。 调用 RadioInfoManager 的 addObserver 方法,传入已创建的 MyRadioStateObserver 对象 observer 和需要观察的 mask。 // 获取RadioInfoManager对象。 RadioInfoManager radioInfoManager = RadioInfoManager.getInstance(context); // 创建继承RadioStateObserver的类MyRadioStateObserver class MyRadioStateObserver extends RadioStateObserver { // 构造方法,在当前线程的runner中执行回调,slotId需要传入要观察的卡槽ID(0或1)。 MyRadioStateObserver(int slotId) { super(slotId); } // 构造方法,在执行runner中执行回调。 MyRadioStateObserver(int slotId, EventRunner runner) { super(slotId, runner); } // 网络注册状态变化的回调方法。 @Override public void onNetworkStateUpdated(NetworkState state) { ... } // 信号信息变化的回调方法。 @Override public void onSignalInfoUpdated(List<SignalInformation> signalInfos) { ... } } // 执行回调的runner。 EventRunner runner = EventRunner.create(); // 创建MyRadioStateObserver的对象。 MyRadioStateObserver observer = new MyRadioStateObserver(slotId, runner); //...

场景介绍 应用通常需要获取用户所在蜂窝网络下信号信息,以便获取当前驻网质量。开发者可以通过本业务,获取到用户指定 SIM 卡当前所在网络下的信号信息。 接口说明 RadioInfoManager 类中提供了获取当前网络信号信息列表的方法。 功能分类 接口名 描述 所需权限 获取管理对象 getInstance(Context context) 获取网络管理对象。 无 信号强度信息 getSignalInfoList(int slotId) 获取当前注册蜂窝网络信号强度信息。 无 开发步骤 调用 RadioInfoManager 的 getInstance 接口,获取到 RadioInfoManager 实例。 调用 getSignalInfoList(slotId) 方法,返回所有 SignalInformation 列表。 遍历 SignalInformation 列表,并分别根据 signalNetworkType 转换为对应制式的 SignalInformation 子类对象。 调用子类中的方法,获取信号强度信息。 // 获取RadioInfoManager对象。 RadioInfoManager radioInfoManager = RadioInfoManager.getInstance(context); // 获取信号信息。 List<SignalInformation> signalList = radioInfoManager.getSignalInfoList(slotId); // 检查信号信息列表大小。 if (signalList.size() == 0) { return; } // 依次遍历list获取当前驻网networkType对应的信号信息。 LteSignalInformation lteSignal; for (SignalInformation signal : signalList) { int signalNetworkType = signal.getSignalNetworkType(); if (signalNetworkType == TelephonyConstants.NETWORK_TYPE_LTE) { lteSignal = (LteSignalInformation) signal; } } // 调用子类中相应方法,获取对应制式的信号强度信息。 int signalLevel = lteSignal.getSignalLevel();

场景介绍 应用需要发送一条短信给一个指定的号码时,使用本业务。发送信息需要经过短信中心,短信中心号码可以是运营商默认的,也可以由应用自己指定。 如果设备支持同时插入 2 张 SIM 卡,且 2 张 SIM 卡均在位时,短信会从默认 SIM 卡发出。应用可通过调用 getDefaultSmsSlotId 来获取当前发短信的默认 SIM 卡位置。目前 API 暂不支持短信发送结果通知和送达报告。 接口说明 ShortMessageManager 为开发者提供短信管理功能,具体功能分类如下表。 功能分类 接口名 描述 所需权限 能力获取 hasSmsCapability() 检查当前设备是否支持短信收发。 无 获取管理对象 getInstance(Context context) 获取短信管理对象。 无 获取默认短信卡 getDefaultSmsSlotId() 获取默认短信卡对应卡槽ID。 无 长短信转化 splitMessage(String content) 将超过140个字节的长短信(如中文70个字符,英文160个字符)拆分成多条短信。 ohos.permission.SEND_MESSAGES 发送短信 sendMessage(String destinationHost, String serviceCenter, String content) 发送单条短信。 ohos.permission.SEND_MESSAGES sendMultipartMessage(String destinationHost, String serviceCenter, ArrayList<String> parts) 发送拆分后的多条短信。 ohos.permission.SEND_MESSAGES 开发步骤 调用 ShortMessageManager 的 getInstance 接口,创建/获取短信收发管理对象。 调用 hasSmsCapability() 接口获取当前设备短信收发能力,如果支持继续下一步;如果不支持则无法收发短信。 发送短信。 // 创建短信收发管理对象 ShortMessageManager smManager = ShortMessageManager.getInstance(context); // 检查短信能力 if (!smManager.hasSmsCapability()) { return; } // 如果设备支持收发短信,则继续发送短信 // 发送短信前可先调用splitMessage()接口判断拆分后的短信条数,然后决定调用长短信或普通短信发送接口 ArrayList<String> msgs = smManager.splitMessage(messageContent); if (msgs.size() > 1) { // 长短信拆分发送 smManager.sendMultipartMessage(destinationNumber, serviceCenter, msgs); } else { // 一般文本短信发送 smManager.sendMessage(destinationNumber, serviceCenter, messageContent); }

场景介绍 当应用需要发起一路呼叫给一个指定的号码时,使用本业务。呼叫可以是音频呼叫,也可以是视频呼叫。 如果设备支持同时插入两张 SIM 卡,且拨打电话时两张SIM 卡均在位,呼叫时会弹出弹框让用户选择从卡 1 还是卡 2 呼出。 接口说明 DistributedCallManager 为开发者提供呼叫管理功能,具体功能分类如下表。 功能分类 接口名 描述 所需权限 能力获取 hasVoiceCapability() 检查当前设备是否支持语音呼叫。 无 获取管理对象 getInstance(Context context) 获取呼叫管理对象。 无 发起呼叫 dial(String number, boolean isVideoCall) 发起音频或视频呼叫。 ohos.permission.PLACE_CALL 观察通话业务状态变化 addObserver(CallStateObserver observer, int mask) 观察通话业务状态变化。 ohos.permission.READ_CALL_LOG(获取通话号码需要该权限) 开发步骤 调用 DistributedCallManager 的 getInstance 接口,创建/获取呼叫管理对象。 调用 hasVoiceCapability() 接口获取当前设备呼叫能力,如果支持继续下一步;如果不支持则无法发起呼叫。 发起一路呼叫。 注册观察呼叫状态变化。 // 创建呼叫管理对象 DistributedCallManager dcManager = DistributedCallManager.getInstance(context); // 调用查询能力接口 if (!dcManager.hasVoiceCapability()) { return; } // 如果设备支持呼叫能力,则继续发起呼叫 dcManager.dial(destinationNum, isVideoCall); // 创建继承CallStateObserver的类MyCallStateObserver class MyCallStateObserver extends CallStateObserver { // 构造方法,在当前线程的runner中执行回调,slotId需要传入要观察的卡槽ID(0或1) MyCallStateObserver(int slotId) { super(slotId); } // 构造方法,在执行runner中执行回调,slotId需要传入要观察的卡槽ID(0或1) MyCallStateObserver(int slotId, EventRunner runner) { super(slotId, runner); } // 通话状态变化的回调方法 @Override public void onCallStateUpdated(int state, String number) { ... } } // 执行回调的runner EventRunner runner = EventRunner.create(); // 创建MyCallStateObserver的对象 MyCallStateObserver observer = new MyCallStateObserver(slotId, runner); // 观察OBSERVE_CALL_STATE的变化 dcManager.addObserver(observer, CallStateObserver.OBSERVE_CALL_STATE);

电话服务系统,除了为用户提供拨打语音/视频呼叫以及发送标准短信的功能以外,还提供了一系列的 API 用于获取无线蜂窝网络和 SIM 卡相关的一些信息。 其中拨打电话相关功能由 DistributedCallManager 提供,短信服务能力由 ShortMessageManager 提供。 应用还可以通过调用 RadioInfoManager 中的 API,来获取当前注册网络名称、网络服务状态以及信号强度等信息;以及调用 SimInfoManager 中的 API,来获取 SIM 卡的相关信息。 约束与限制 部分 API 接口需要一定访问权限才能调用,因此三方应用在调用有权限控制的API时,需要先申请对应权限,权限申请详见权限章节。 语音呼叫和短信功能暂不支持传入卡槽编号(SlotId),双卡场景下的使用规则详见发起一路呼叫和发送一条文本信息的场景介绍。 注册获取 SIM 卡状态接口仅针对有 SIM 卡在位场景生效,若用户拔出 SIM 卡,则接收不到回调事件。应用可通过调用 hasSimCard 接口来确定当前卡槽是否有卡在位。

场景介绍 应用重复打开一个相同网页时,可以优先从缓存文件里读取内容,从而减少数据流量,降低设备功耗,提升应用性能。 接口说明 管理 HTTP 缓存的功能主要由 HttpResponseCache 类提供。 接口名 功能描述 install(File directory, long size) 使能 HTTP 缓存,设置缓存保存目录及大小。 getInstalled() 获取缓存实例。 flush() 立即保存缓存信息到文件系统中。 close() 关闭缓存功能。 delete() 关闭并清除缓存内容。 开发步骤 配置缓存目录及最大缓存空间。 保存缓存。 关闭缓存。 // 初始化时设置缓存目录dir及最大缓存空间 HttpResponseCache.install(dir, 10 * 1024 * 1024); // 访问URL // 为确保缓存保存到文件系统可以执行flush操作 HttpResponseCache.getInstalled().flush(); // 结束时关闭缓存 HttpResponseCache.getInstalled().close();

场景介绍 应用通过调用 API 接口,可以获取蜂窝网络、所有网卡、指定应用或指定网卡的数据流量统计值。 接口说明 应用进行流量统计,所使用的接口主要由 DataFlowStatistics 提供。 接口名 功能描述 getCellularRxBytes() 获取蜂窝数据网络的下行流量。 getCellularTxBytes() 获取蜂窝数据网络的上行流量。 getAllRxBytes() 获取所有网卡的下行流量。 getAllTxBytes() 获取所有网卡的上行流量。 getUidRxBytes(int uid) 获取指定UID的下行流量。 getUidTxBytes(int uid) 获取指定UID的上行流量。 getIfaceRxBytes(String nic) 获取指定网卡的下行流量。 getIfaceTxBytes(String nic) 获取指定网卡的上行流量。 开发步骤 调用 DataFlowStatistics 的接口可进行流量统计,以统计指定应用进程的流量为例。 long rx = DataFlowStatistics.getUidRxBytes(uid); long tx = DataFlowStatistics.getUidTxBytes(uid); // 进行数据收发 // 统计流量 rx = DataFlowStatistics.getUidRxBytes(uid) - rx; tx = DataFlowStatistics.getUidTxBytes(uid) - tx;

场景介绍 应用可以调用 API 接口来使用指定网络进行数据传输。在进行数据传输前,需要先建立自定义的网络类型。 接口说明 应用使用指定网络进行数据访问,所使用的接口说明如下。 类名 接口名 功能描述 NetSpecifier Builder() 创建一个指定网络实例。 NetManager setupSpecificNet(NetSpecifier netSpecifier, NetStatusCallback callback) 建立指定的数据网络。 removeNetStatusCallback(NetStatusCallback callback) 停止获取数据网络状态。 开发步骤 调用 NetSpecifier.Builder( )构建指定数据网络的实例。 调用 NetManager.setupSpecificNet() 建立数据网络,通过 callback 获取网络状态变化。 进行数据发送。 NetManager netManager = NetManager.getInstance(null); private class MmsCallback extends NetStatusCallback { @Override public void onAvailable(NetHandle netHandle) { // 通过setAppNet把后续应用所有的请求都通过该网络进行发送 netManager.setAppNet(netHandle); try { HttpURLConnection connection = null; String urlString = "https://www.huawei.com/"; URL url = new URL(urlString); URLConnection urlConnection = netHandle.openConnection(url, java.net.Proxy.NO_PROXY); if (urlConnection instanceof HttpURLConnection) { connection = (HttpURLConnection) urlConnection; } connection.setRequestMethod("GET"); connection.connect(); // 之后可进行url的其他操作 } finally { connection.disconnect(); } // 如果业务执行完毕,可以停止获取 netManager.removeNetStatusCallback(this); } } MmsCallback callback = new MmsCallback(); // 配置一个彩信类型的蜂窝网络 NetSpecifier req = new NetSpecifier.Builder() .addCapability(NetCapabilities.NET_CAPABILITY_MMS) .addBearer(NetCapabilities.BEARER_CELLULAR) .build(); // 建立数据网络,通过callback获取网络变更状态 netManager.setupSpecificNet(req, callback);

场景介绍 应用使用当前的数据网络进行 Socket 数据传输。 接口说明 应用使用当前网络进行 Socket 数据传输,所使用的接口说明如下。 类名 接口名 功能描述 NetManager getByName(String host) 解析主机名,获取其 IP 地址。 bindSocket(Socket socket) 绑定 Socket 到该数据网络。 NetHandle bindSocket(DatagramSocket socket) 绑定 DatagramSocket 到该数据网络。 开发步骤 调用 NetManager.getInstance(Context) 获取网络管理的实例对象。 调用 NetManager.getDefaultNet() 获取默认的数据网络。 调用 NetHandle.bindSocket() 绑定网络。 使用 socket 发送数据。 NetManager netManager = NetManager.getInstance(null); if (!netManager.hasDefaultNet()) { return; } NetHandle netHandle = netManager.getDefaultNet(); // 通过Socket绑定来进行数据传输 try { InetAddress address = netHandle.getByName("www.huawei.com"); DatagramSocket socket = new DatagramSocket(); netHandle.bindSocket(socket); byte[] buffer = new byte[1024]; DatagramPacket request = new DatagramPacket(buffer, buffer.length, address, port); // buffer赋值 // 发送数据 socket.send(request); } catch(IOException e) { e.printStackTrace(); }

Vultr怎么样?Vultr是来自美国的知名VPS销售商,成立于2014年,目前支持支付宝、微信、PayPal、信用卡等多种方式充值购买,是一个按小时计费的商家,不用了可以随时删除VPS,不会造成任何浪费,更不要担心IP被屏蔽问题,可以随时删除VPS再购买。Vultr的VPS产品对于国内用户来说虽然线路上并不是特别优秀,但是产品稳定性非常好的、带宽也比较稳定,更不要担心跑路等问题。目前Vultr有日本、新加坡、美国、欧洲等15大数据中心可以选择,所以基本上是想用那个数据中心就购买哪个,不用了删除掉购买一台当前需要的新机房就可以了,使用非常灵活 接下来带来美国檀香山实测数据分享,仅供大家参考。 官方网站:https://www.vultr.com/ CPU型号AMD EPYC-Rome Processor,主频大致2.0GHz,启用了BBR,支持IPv6,IP归属美国,当前I/O测试结果大致551MB/S FIO测试,大致数据如下: 国内三网多节点测速: speedtest国际节点测速: speedtest亚洲区域节点测速: iperf3测试数据: 国内三网多节点的延迟测试数据: 电信去程:骨干网对接GTT去机房 联通去程:骨干网对接COGENT去机房 移动去程:直连移动香港节点转COGENT去机房 三网回程: 电信回程:走cogent回国 联通回程:走gtt回国 移动回程:走cogent回国 tiktok解锁: 流媒体解锁: 欺诈分数以及IP质量检测: 大致总结下: 目前云服务器性能不错,一般用户无需担心性能; 网络方面,回程电信移动cogent回国,联通走gtt回国,速度都还行。