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

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

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

调整应用的用例

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

  • 确定您的应用是否适合在受限网络中使用。有些应用在任何情况下都不适合数据受限的网络。例如,视频流应用可能选择完全不使用卫星网络,但它们仍然可以识别卫星网络的存在,并告知用户它们无法在现有的有限网络上运行。
  • 确定要限制或修改的具体使用情形。您的应用的某些功能可能比其他功能更适合在数据有限的情况下使用。例如,发送短信会很顺畅,但尝试上传高清视频可能会导致用户体验不佳。这与许多应用在漫游时更改行为的方式类似。
  • 调整应用使用网络资源的方式。当应用以突发方式执行网络操作,并且大部分时间都不使用网络时,受限网络的效果最好。避免创建持续或频繁的网络流量。例如,与实时语音通话相比,对讲音频更适合受限的网络条件。

如果您的应用使用复杂的网络逻辑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 服务器仅在设备通过不受限的网络连接时传送该消息。