针对受限的卫星网络进行开发

卫星网络总有一天会足够强大,能够像普通网络一样运行,并与所有应用使用情形无缝协作;但就目前而言,这些网络上的数据是一种稀缺资源。对数据使用有限制的基于卫星的网络称为受限卫星网络

由于存在这些限制,Android 应用默认情况下不会使用这些网络。如果您希望应用在受限的卫星网络上运行,则必须将应用标识为针对卫星数据使用情况进行了优化,并调整应用的使用情形,以便在连接到受限的卫星网络时节省资源。

调整应用的用例

您只需选择启用,即可允许应用访问受限卫星网络,但您可能需要进一步更改应用的行为,以负责任的方式使用有限的网络资源。在优化受限的数据使用量时,请考虑以下事项:

  • 卫星网络的运行条件比地面 LTE/5G 网络受到的限制要多得多,其特点是吞吐量较低,延迟时间较长。虽然我们通常建议尽量减少数据使用量以提高可靠性,但每个应用都是独一无二的。您应评估自己的具体使用情形,以确定当前的数据优化策略是否能在这些受限环境中提供可接受的用户体验。
  • 确定您的应用是否适合在受限网络中使用。有些应用在任何情况下都不适合数据受限的网络。例如,视频在线播放等高带宽应用应评估其数据压缩和内容传送机制,以确保用户获得良好的使用体验。如果因数据限制而不可避免地导致体验降级,应用应采取以下措施:
    1. 应用可以选择完全不使用卫星网络,但仍可以识别卫星网络的存在,并告知用户应用在当前有限的网络上无法正常运行。
    2. 确定要限制或修改的具体使用情形。您的应用的某些功能可能比其他功能更适合在数据有限的情况下使用。例如,发送短信等低带宽操作的可靠性非常高。不过,上传未压缩的高清视频等高带宽操作可能会遇到严重的缓冲或失败问题。我们建议为这些要求较高的功能实现自适应比特率流式传输或强大的压缩功能。这与许多应用在漫游时更改行为的方式类似。
    3. 调整应用使用网络资源的方式。当应用以突发方式执行网络操作,并且大部分时间都不使用网络时,受限网络的效果最好。可变延迟可能会使实时同步通信变得困难。

如果您的应用使用复杂的网络逻辑Firebase 云消息传递,还需要进行一些特定的更改。

自行标识为针对受限网络进行了优化

如需将您的应用标识为针对受限网络进行了优化,并选择使用受限网络,请使用 <meta-data> 元素更新应用清单文件,如下所示:

<meta-data android:name="android.telephony.PROPERTY_SATELLITE_DATA_OPTIMIZED"
          android:value="PACKAGE_NAME" />

此元素允许您的应用在只有受限卫星网络可用时使用该网络。它还会通知系统您的应用已针对受限网络进行优化,从而通过在“设置”应用中将该应用列为支持卫星的应用来帮助用户发现该应用。

在数据受限的情况下更改行为

如果您需要在使用受限网络时更改应用的行为,或者您的应用具有使用 ConnectivityManager 管理网络使用的预先存在的逻辑,则需要对网络流程进行一些更改。

检测受限数据条件

用于网络请求的 NetworkCapabilities 对象包含一个 NET_CAPABILITY_NOT_BANDWIDTH_CONSTRAINED 位,该位默认在所有网络上设置,但在带宽受限的网络上移除。您可以通过检查网络是否具有 NET_CAPABILITY_NOT_BANDWIDTH_CONSTRAINED 功能来确定网络是否受带宽限制。

处理受限网络

NetworkRequest 对象默认还包含 NET_CAPABILITY_NOT_BANDWIDTH_CONSTRAINED 功能。移除此功能以表明接受受限网络。

当您检测到自己已连接到受限网络时,可以根据需要调整应用的功能:

Kotlin

val HandlerThread = HandlerThread("SatelliteNetworkMonitor"
handlerThread.start()
val handler = Handler(handlerThread.getLooper())

// Make the network request.
val request = NetworkRequest.Builder()
    .addCapability(NET_CAPABILITY_INTERNET
    .removeCapability(NET_CAPABILITY_NOT_BANDWIDTH_CONSTRAINED)
    .build()

// Register for the callback.
val callback = NetworkCallback() {
    override fun onCapabilitiesChanged(net: Network, nc: NetWorkCapabilities) {
        updateAppUseCases(net, nc)
    }

    fun updateAppUseCases(net: Network, nc: NetworkCapabilities) {
        if (!nc.hasCapability(NET_CAPABILITY_NOT_BANDWIDTH_CONSTRAINED) ||
             nc.hasTransport(NetworkCapabilities.TRANSPORT_SATELLITE)) {
            // Adapt to constrained network or disable heavy data usage features.
            ...
        } else {
            // Revert to unconstrained behavior.
            ...
        }
    }
}
// Where cm is your ConnectivityManager object:
cm.registerBestMatchingNetworkCallback(request, callback, handler)

Java

HandlerThread handlerThread = new HandlerThread("SatelliteNetworkMonitor");
handlerThread.start();
Handler handler = new Handler(handlerThread.getLooper());

// Make the network request.
NetworkRequest request = new NetworkRequest.Builder()
    .addCapability(NET_CAPABILITY_INTERNET)
    .removeCapability(NET_CAPABILITY_NOT_BANDWIDTH_CONSTRAINED)
    .build();

// Register for the callback.
NetworkCallback callback = new NetworkCallback() {
    @Override
    public void onCapabilitiesChanged(Network net, NetworkCapabilities nc) {
        updateAppUsecases(net, nc);
    }
    private void updateAppUsecases(Network net, NetworkCapabilities nc) {
        if (!nc.hasCapability(NET_CAPABILITY_NOT_BANDWIDTH_CONSTRAINED) || nc.hasTransport(NetworkCapabilities.TRANSPORT_SATELLITE)) {
            // Adapt to constrained network or disable heavy data usage features.
            ...
        } else {
            // Revert to unconstrained behavior.
            ...
        }
    }
};
// Where cm is your ConnectivityManager object:
cm.registerBestMatchingNetworkCallback(request, callback, handler);

在受限网络上接收 FCM 消息

如果您的应用使用 Firebase Cloud Messaging (FCM) 从应用服务器接收消息,您可以在将消息传递给 FCM 服务器时添加 bandwidth_constrained_ok 标志,以表明即使在受限的网络上,也应传送特定消息:

{
  "message":{
    "token":"bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1...",
    "notification":{
      "title":"Portugal vs. Denmark",
      "body":"great match!"
    }
    "android": {
       "bandwidth_constrained_ok": true
    }
  }
}

如果消息不包含此标志,则 FCM 服务器仅在设备通过不受限的网络连接时传送该消息。