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