valHandlerThread=HandlerThread("SatelliteNetworkMonitor"handlerThread.start()valhandler=Handler(handlerThread.getLooper())// Make the network request.valrequest=NetworkRequest.Builder().addCapability(NET_CAPABILITY_INTERNET.removeCapability(NET_CAPABILITY_NOT_BANDWIDTH_CONSTRAINED).build()// Register for the callback.valcallback=NetworkCallback(){overridefunonCapabilitiesChanged(net:Network,nc:NetWorkCapabilities){updateAppUseCases(net,nc)}funupdateAppUseCases(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
HandlerThreadhandlerThread=newHandlerThread("SatelliteNetworkMonitor");handlerThread.start();Handlerhandler=newHandler(handlerThread.getLooper());// Make the network request.NetworkRequestrequest=newNetworkRequest.Builder().addCapability(NET_CAPABILITY_INTERNET).removeCapability(NET_CAPABILITY_NOT_BANDWIDTH_CONSTRAINED).build();// Register for the callback.NetworkCallbackcallback=newNetworkCallback(){@OverridepublicvoidonCapabilitiesChanged(Networknet,NetworkCapabilitiesnc){updateAppUsecases(net,nc);}privatevoidupdateAppUsecases(Networknet,NetworkCapabilitiesnc){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);
[null,null,["最后更新时间 (UTC):2025-08-20。"],[],[],null,["# Develop for constrained satellite networks\n\nSatellite networks will someday be robust enough to function as normal networks\nand work seamlessly with all app use cases; but for now, data on these networks\nis a scarce resource. A satellite-based network with constraints on data use is\ncalled a *constrained satellite network*.\n\nDue to these constraints, Android apps don't use these networks by default. If\nyou want your app to operate on constrained satellite networks, you must\n[identify your app as optimized for satellite data usage](#self-identify) and [adapt your\napp's use cases](#adapt-use-cases) to conserve resources when connected to a constrained\nsatellite network.\n\nAdapt your app's use cases\n--------------------------\n\nAll you have to do to allow your app to access constrained satellite networks is\nopt in, but you might need to make further changes to optimize your app's\nbehavior to use limited network resources responsibly. Here are some things to\nconsider when you optimize for constrained data usage:\n\n- **Decide whether your app is suitable for use on constrained networks.** Some apps aren't a good fit for data-constrained networks under any circumstances. For example, video streaming apps might choose not to use satellite networks at all, though they could still identify the presence of a satellite network and inform the user that they won't function on the existing limited network.\n- **Identify specific use cases to limit or modify.** Some of your app's features might be better suited to limited data conditions than others. For example, sending text messages would work well, but attempting to upload HD video would likely result in a poor user experience. This is similar to the way many apps change behavior when roaming.\n- **Adapt the way your app uses network resources.** Constrained networks work best when apps perform network operations in bursts and spend most of the time not using the network. Avoid creating constant or chatty network traffic. For example, push-to-talk audio is much better suited to constrained network conditions than real-time audio calls.\n\nThere are also specific changes you need to make if your app uses [complex\nnetworking logic](#change-behavior) or [Firebase Cloud Messaging](#firebase-cloud-messaging).\n\nSelf-identify as optimized for constrained networks\n---------------------------------------------------\n\nTo identify your app as optimized for constrained networks and opt into using\nthem, update your [app manifest file](/guide/topics/manifest/manifest-intro) with a\n[`\u003cmeta-data\u003e`](/guide/topics/manifest/meta-data-element) element as follows: \n\n \u003cmeta-data android:name=\"android.telephony.PROPERTY_SATELLITE_DATA_OPTIMIZED\"\n android:value=\"\u003cvar translate=\"no\"\u003ePACKAGE_NAME\u003c/var\u003e\" /\u003e\n\nThis element allows your app to use a constrained satellite network when it's\nthe only network available. It also notifies the system that your app is\noptimized for constrained networks, aiding in user discovery by listing it among\nthe satellite-enabled apps in the settings app.\n| **Note:** Don't add this tag to your manifest when developing a library. Let the apps that use your library self-identify as appropriate.\n\nChange behavior under constrained data conditions\n-------------------------------------------------\n\nIf you need to change your app's behavior when using a constrained network, or\nif your app has pre-existing logic that uses\n[`ConnectivityManager`](/reference/android/net/ConnectivityManager) to manage network use, you'll need\nto make some changes to your network flow.\n\n### Detect constrained data conditions\n\nThe [`NetworkCapabilities`](/reference/android/net/NetworkCapabilities) object used for network\nrequests includes a\n[`NET_CAPABILITY_NOT_BANDWIDTH_CONSTRAINED`](/reference/android/net/NetworkCapabilities#NET_CAPABILITY_NOT_BANDWIDTH_CONSTRAINED) bit that is\nset by default on all networks and removed on networks that are\nbandwidth-constrained. You can determine whether a network is\nbandwidth-constrained by checking whether or not it has the\n`NET_CAPABILITY_NOT_BANDWIDTH_CONSTRAINED` capability.\n\n### Work with constrained networks\n\n[`NetworkRequest`](/reference/android/net/NetworkRequest) objects also include the\n`NET_CAPABILITY_NOT_BANDWIDTH_CONSTRAINED` capability by default. Remove this\ncapability to indicate that constrained networks are acceptable.\n\nWhen you detect that you've connected to a constrained network, you can adapt\nyour app's features as necessary: \n\n### Kotlin\n\n```kotlin\nval HandlerThread = HandlerThread(\"SatelliteNetworkMonitor\"\nhandlerThread.start()\nval handler = Handler(handlerThread.getLooper())\n\n// Make the network request.\nval request = NetworkRequest.Builder()\n .addCapability(NET_CAPABILITY_INTERNET\n .removeCapability(NET_CAPABILITY_NOT_BANDWIDTH_CONSTRAINED)\n .build()\n\n// Register for the callback.\nval callback = NetworkCallback() {\n override fun onCapabilitiesChanged(net: Network, nc: NetWorkCapabilities) {\n updateAppUseCases(net, nc)\n }\n\n fun updateAppUseCases(net: Network, nc: NetworkCapabilities) {\n if (!nc.hasCapability(NET_CAPABILITY_NOT_BANDWIDTH_CONSTRAINED) ||\n nc.hasTransport(NetworkCapabilities.TRANSPORT_SATELLITE)) {\n // Adapt to constrained network or disable heavy data usage features.\n ...\n } else {\n // Revert to unconstrained behavior.\n ...\n }\n }\n}\n// Where cm is your ConnectivityManager object:\ncm.registerBestMatchingNetworkCallback(request, callback, handler)\n```\n\n### Java\n\n```java\nHandlerThread handlerThread = new HandlerThread(\"SatelliteNetworkMonitor\");\nhandlerThread.start();\nHandler handler = new Handler(handlerThread.getLooper());\n\n// Make the network request.\nNetworkRequest request = new NetworkRequest.Builder()\n .addCapability(NET_CAPABILITY_INTERNET)\n .removeCapability(NET_CAPABILITY_NOT_BANDWIDTH_CONSTRAINED)\n .build();\n\n// Register for the callback.\nNetworkCallback callback = new NetworkCallback() {\n @Override\n public void onCapabilitiesChanged(Network net, NetworkCapabilities nc) {\n updateAppUsecases(net, nc);\n }\n private void updateAppUsecases(Network net, NetworkCapabilities nc) {\n if (!nc.hasCapability(NET_CAPABILITY_NOT_BANDWIDTH_CONSTRAINED) || nc.hasTransport(NetworkCapabilities.TRANSPORT_SATELLITE)) {\n // Adapt to constrained network or disable heavy data usage features.\n ...\n } else {\n // Revert to unconstrained behavior.\n ...\n }\n }\n};\n// Where cm is your ConnectivityManager object:\ncm.registerBestMatchingNetworkCallback(request, callback, handler);\n```\n| **Note:** There are no specific SDK dependencies for accessing constrained satellite networks. You can hardcode the integer values for `NET_CAPABILITY_NOT_BANDWIDTH_CONSTRAINED` and `TRANSPORT_SATELLITE` on lower versions of Android, but on Android 16 and above apps need to use the net network capabilities as demonstrated, handling any exceptions thrown by `ConnectivityManager`.\n\nReceive FCM messages on constrained networks\n--------------------------------------------\n\nIf your app uses [Firebase Cloud Messaging (FCM)](https://firebase.google.com/docs/cloud-messaging/android/client) to receive messages\nfrom an app server, you can indicate that a specific message should be delivered\neven on constrained networks by including the `bandwidth_constrained_ok` flag\nwhen passing the message to the FCM server: \n\n {\n \"message\":{\n \"token\":\"bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1...\",\n \"notification\":{\n \"title\":\"Portugal vs. Denmark\",\n \"body\":\"great match!\"\n }\n \"android\": {\n \"bandwidth_constrained_ok\": true\n }\n }\n }\n\nIf a message doesn't include this flag, then the FCM server only delivers it\nwhen the device is connected through an unconstrained network.\n| **Note:** Only use the `bandwidth_constrained_ok` flag if you've updated the corresponding app to work on constrained satellite networks."]]