制約のある衛星ネットワーク向けに開発する

衛星ネットワークは、いつか通常のネットワークとして機能し、すべてのアプリのユースケースでシームレスに動作するほど堅牢になるでしょう。しかし、現時点では、これらのネットワーク上のデータは希少なリソースです。データ使用に制約がある衛星ベースのネットワークは、制約付き衛星ネットワークと呼ばれます。

このような制約があるため、Android アプリはデフォルトでこれらのネットワークを使用しません。アプリを制約のある衛星ネットワークで動作させる場合は、アプリを衛星データ使用向けに最適化されていると識別し、アプリのユースケースを適応させて、制約のある衛星ネットワークに接続されたときにリソースを節約する必要があります。

アプリのユースケースを適応させる

アプリが制約付き衛星ネットワークにアクセスできるようにするには、オプトインするだけで済みますが、限られたネットワーク リソースを責任を持って使用するようにアプリの動作を最適化するために、さらに変更が必要になる場合があります。データ使用量を制限するために最適化する際は、次の点を考慮してください。

  • 衛星ネットワークは、地上 LTE/5G ネットワークよりも大幅に制約の多い条件下で動作します。スループットが低く、レイテンシが高いのが特徴です。一般的に、信頼性の理由からデータ使用量を最小限に抑えることをおすすめしますが、アプリはそれぞれ異なります。特定のユースケースを評価して、現在のデータ最適化戦略がこのような制約のある環境で許容できるユーザー エクスペリエンスを提供しているかどうかを判断する必要があります。
  • アプリが制約のあるネットワークでの使用に適しているかどうかを判断します。一部のアプリは、どのような状況でもデータ制限のあるネットワークには適していません。たとえば、動画ストリーミングなどの高帯域幅アプリは、機能的なユーザー エクスペリエンスを確保するために、データ圧縮とコンテンツ配信のメカニズムを評価する必要があります。データの制約によりエクスペリエンスの低下が避けられない場合、アプリは次のアクションを実行する必要があります。
    1. アプリは衛星ネットワークをまったく使用しないことを選択する可能性があります。ただし、衛星ネットワークの存在を特定し、既存の制限されたネットワークでは機能しないことをユーザーに通知することはできます。
    2. 制限または変更する特定のユースケースを特定します。アプリの機能によっては、データ制限モードに適しているものもあれば、そうでないものもあります。たとえば、テキスト メッセージの送信などの低帯域幅オペレーションは信頼性が高くなります。ただし、非圧縮の HD 動画のアップロードなど、高帯域幅のオペレーションでは、バッファリングやエラーが頻繁に発生する可能性があります。このような負荷の高い機能には、アダプティブ ビットレート ストリーミングまたは堅牢な圧縮を実装することをおすすめします。これは、ローミング時に多くのアプリが動作を変更するのと同様です。
    3. アプリのネットワーク リソースの使用方法を調整します。制約付きネットワークは、アプリがネットワーク オペレーションをバーストで実行し、ほとんどの時間をネットワークを使用せずに費やす場合に最適です。遅延が変動すると、リアルタイムの同期通信が難しくなることがあります。

アプリで複雑なネットワーク ロジック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 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 サーバーは制約のないネットワーク経由でデバイスが接続されている場合にのみメッセージを配信します。