為受限的衛星網路開發應用程式

衛星網路的效能終將足以做為一般網路使用,並與所有應用程式用途無縫整合;但目前這些網路的資料仍相當有限。以衛星為基礎的網路,且資料使用受到限制,稱為「受限衛星網路」

因此,Android 應用程式預設不會使用這些網路。如要讓應用程式在受限的衛星網路上運作,您必須將應用程式識別為已針對衛星資料用量進行最佳化,並調整應用程式的使用情境,以便在連線至受限的衛星網路時節省資源。

調整應用程式的用途

如要允許應用程式存取受限的衛星網路,您只需要選擇加入即可,但可能需要進一步變更,才能最佳化應用程式的行為,以合理使用有限的網路資源。如要針對受限的資料用量進行最佳化,請考慮下列事項:

  • 判斷應用程式是否適合在受限的網路上使用。在任何情況下,部分應用程式都不適合在數據用量受限的網路上使用。舉例來說,影片串流應用程式可能會選擇完全不使用衛星網路,但仍可識別衛星網路的存在,並通知使用者應用程式無法在現有的受限網路上運作。
  • 找出要限制或修改的特定用途。您應用程式的部分功能可能比其他功能更適合在資料受限的情況下運作。舉例來說,傳送簡訊應該沒問題,但嘗試上傳 HD 影片可能會導致使用者體驗不佳。這與許多應用程式在漫遊時變更行為的方式類似。
  • 調整應用程式使用網路資源的方式。如果應用程式會以叢發方式執行網路作業,且大部分時間都不會使用網路,那麼受限網路最適合這類應用程式。避免產生持續或頻繁的網路流量。舉例來說,在網路受限的情況下,對講音訊比即時語音通話更適合。

如果應用程式使用複雜的網路邏輯Firebase Cloud Messaging,您也需要進行特定變更。

自行識別是否已針對受限網路進行最佳化

如要將應用程式識別為已針對受限網路最佳化,並選擇使用這些網路,請按照下列方式,使用 <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 雲端通訊 (FCM) 接收應用程式伺服器的訊息,您可以將訊息傳遞至 FCM 伺服器時加入 bandwidth_constrained_ok 標記,指出即使在受限的網路上,也應傳送特定訊息:

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

如果訊息未包含這個標記,FCM 伺服器只會在裝置透過不受限制的網路連線時傳送訊息。