For Android developers / Android 16+

Build for
constrained networks.

Declare satellite support and design requests that survive low bandwidth, high latency, and interruptions.

01 / Manifest

Tell Android your app is ready.

Add the satellite data optimization property to the final app's <application> element. Use the exact package name as the value. This declaration belongs to the app manifest, not a library.

AndroidManifest.xml

<application
    android:label="@string/app_name">
    <meta-data
        android:name="android.telephony.PROPERTY_SATELLITE_DATA_OPTIMIZED"
        android:value="com.example.yourapp" />
</application>

Verify the declaration in the released APK before shipping.

02 / Network requests

Let constrained networks through.

Requests that require an unconstrained network will exclude satellite connectivity. Remove that requirement and branch from the capabilities Android reports.

Kotlin

val request = NetworkRequest.Builder()
    .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
    .removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_BANDWIDTH_CONSTRAINED)
    .build()

fun isConstrained(capabilities: NetworkCapabilities) =
    !capabilities.hasCapability(
        NetworkCapabilities.NET_CAPABILITY_NOT_BANDWIDTH_CONSTRAINED
    )

03 / Push messages

Opt in to constrained FCM delivery.

If your app uses Firebase Cloud Messaging, set the Android-specific flag on messages that should be delivered over a constrained network.

FCM message payload

{
  "message": {
    "token": "DEVICE_TOKEN",
    "data": { "sync": "requested" },
    "android": {
      "bandwidth_constrained_ok": true
    }
  }
}

Before release

Test behavior, not just metadata.

Use an Android 16 device or emulator configuration that exposes constrained-network behavior. Check payload size, timeouts, retries, queued work, and recovery after the connection disappears.

Canonical references