Working with the Cellular Radio in Mobile Apps
Detect carrier, network type and signal strength to adapt your app for spotty connections, expensive data plans and offline scenarios.
You usually shouldn't care which radio is delivering your packets — except when you should. Knowing whether the user is on 5G versus 3G, on Wi-Fi versus a metered cellular plan, or has full bars versus a sliver can help you load smaller assets, defer uploads, or warn before a 200 MB download. This guide covers what each platform tells you, what it doesn't, and the privacy tradeoffs.
Key Takeaways
- Both platforms let you read the *type* of network (Wi-Fi, cellular generation) and whether it's metered.
- Apple deprecated `CTCarrier` (carrier name/MCC/MNC) in iOS 16 — most fields now return generic placeholders.
- Android still exposes signal strength via `TelephonyManager`, gated behind READ_PHONE_STATE.
- For "is the connection good enough" questions, prefer measuring throughput over reading radio metadata.
Cellular APIs at a Glance
What It Is & How It Works
What it is. A combination of telephony APIs (carrier, SIM, network type) and connectivity APIs (current transport, metered status). Most "smart download" features rely on the latter.
How it works. Use NetInfo / NWPathMonitor on iOS and ConnectivityManager.NetworkCapabilities on Android to inspect the active network, including transport type and metered hint.
Units & signal. Transport type (cellular/Wi-Fi/ethernet), generation (CELLULAR_2G…5G_NR), signal strength (dBm), metered (boolean).
What You Can Build With It
Adaptive media quality
Send 720p video on cellular, 4K on Wi-Fi.
Example: A streaming app dropping bitrate when the active transport flips to cellular.
Defer large uploads
Wait for an unmetered network before backing up photos.
Example: A photo app that schedules uploads only on Wi-Fi.
Show "weak signal" warnings
Tell users why their action is slow when bars are low.
Example: A video-call app surfacing "poor signal" before the call drops.
Carrier-aware experiences
Show carrier-specific support links or offer eSIM provisioning.
Example: A travel app prompting "you're roaming on Vodafone" with data-saving tips.
Permissions & Setup
Reading transport/metered info is permission-free on both OSes. Detailed cellular metrics on Android require the runtime READ_PHONE_STATE permission.
iOS · Info.plist
No special key for transport typeCoreTelephony available without prompt (limited)
Android · AndroidManifest.xml
android.permission.READ_PHONE_STATE (for signal strength, IMEI etc.)android.permission.ACCESS_NETWORK_STATE
Code Examples
Setup
- Expo: `npx expo install @react-native-community/netinfo`
- iOS: import Network; no Info.plist key needed
- Android: add ACCESS_NETWORK_STATE; READ_PHONE_STATE for signal strength
import NetInfo from '@react-native-community/netinfo';
NetInfo.addEventListener(state => {
const isCellular = state.type === 'cellular';
const generation = state.type === 'cellular'
? state.details?.cellularGeneration
: null;
const isExpensive = !!state.details?.isConnectionExpensive;
console.log({ type: state.type, generation, isExpensive });
});Tip: With Newly, you describe the feature you want and the AI agent wires up the sensor, permissions, and UI for you. Try it free.
Best Practices
Treat metered as the source of truth, not transport
Some Wi-Fi hotspots are metered, some cellular plans are not. The metered flag captures user intent better than transport.
Avoid CTCarrier on iOS 16+
Most fields return placeholder values; rely on it only for legacy iOS support.
Use Data Saver / Low Data Mode signals
Both OSes expose user preferences; respecting them is friendlier than ad-hoc heuristics.
Prefer measured throughput
"Is this fast enough" is best answered by a real probe, not a label.
Common Pitfalls
Assuming cellular = slow
5G can be faster than home broadband; Wi-Fi can be a saturated cafe network.
Mitigation: Use signal strength + measured RTT to make adaptive decisions.
Reading carrier name on iOS 16+
You'll receive "—" placeholder strings.
Mitigation: Drop the dependency or surface "Carrier" generically.
Forgetting permissions for signal strength
Android requires runtime READ_PHONE_STATE.
Mitigation: Request permission before calling getSignalStrength().
When To Use It (And When Not To)
Good fit
- Adaptive bitrate / asset selection
- Deferring uploads until unmetered
- Warning users about poor connectivity
- Carrier-aware roaming hints
Look elsewhere if…
- Anything requiring guaranteed throughput
- Identifying users via SIM info
- Carrier-specific business logic on iOS 16+
- Replacing real network error handling
Frequently Asked Questions
Can I read the user's phone number?
Effectively no — both platforms restrict this heavily and return null in most situations.
How do I detect 5G vs LTE?
On iOS, `CTTelephonyNetworkInfo.serviceCurrentRadioAccessTechnology`. On Android, `TelephonyManager.getDataNetworkType()`.
What is the metered flag?
A hint from the OS that the current network costs money or has a quota. Both NetInfo and NWPathMonitor expose it.
Is signal strength accurate?
It's a snapshot from the radio; it varies second-to-second. Use averages for UX.
Build with the Cellular Radio on Newly
Ship a cellular radio-powered feature this week
Newly turns a description like “use the cellular radio to adaptive media quality” into a real React Native app — permissions, native modules and UI included. Full source code is yours, and you can publish to the App Store and Google Play directly from the dashboard.
Want a deeper dive on the underlying APIs? See Expo Sensors, Apple Core Motion and Android sensor framework.
