carrier_info 3.0.3
carrier_info: ^3.0.3 copied to clipboard
Carrier Info gets networkType, networkGeneration, mobileCountryCode, mobileCountryCode, e.t.c from both android and ios devices
📱 Carrier Info #
⚠️ IMPORTANT iOS 16.0+ NOTICE: Apple has deprecated
CTCarrier
starting with iOS 16.0. This means that most carrier-specific information (carrier name, country codes, network codes, etc.) will returnnil
or generic values on iOS 16.0 and later versions. This is an Apple platform limitation, not a plugin issue. See the iOS Limitations section for more details.
Carrier Info gets networkType, networkGeneration, mobileCountryCode, mobileCountryCode, e.t.c from both android and ios devices. It's a port from this js project and an improvement on the existing flt_telephony_info package.
📸 Screen Shots #
Fetching android carrier info #
Docs: https://developer.android.com/reference/android/telephony/TelephonyManager#getNetworkCountryIso(), https://developer.android.com/reference/android/telephony/SubscriptionManager
AndroidCarrierData? carrierInfo = await CarrierInfo.getAndroidInfo();
returns {
"isVoiceCapable": true,
"isDataEnabled": true,
"subscriptionsInfo": [
{
"mobileCountryCode": "310",
"isOpportunistic": false,
"mobileNetworkCode": "260",
"displayName": "T-Mobile",
"isNetworkRoaming": false,
"simSlotIndex": 0,
"phoneNumber": "+15551234567",
"countryIso": "us",
"subscriptionType": 0,
"cardId": 0,
"isEmbedded": false,
"carrierId": 1,
"subscriptionId": 1,
"simSerialNo": "",
"dataRoaming": 0
}
],
"isDataCapable": true,
"isMultiSimSupported": "MULTISIM_NOT_SUPPORTED_BY_HARDWARE",
"isSmsCapable": true,
"telephonyInfo": [
{
"networkCountryIso": "us",
"mobileCountryCode": "310",
"mobileNetworkCode": "260",
"displayName": "T-Mobile",
"simState": "SIM_STATE_READY",
"isoCountryCode": "us",
"cellId": {
"cid": 47108,
"lac": 8514
},
"phoneNumber": "+15551234567",
"carrierName": "T-Mobile",
"subscriptionId": 1,
"networkGeneration": "4G",
"radioType": "LTE",
"networkOperatorName": "T-Mobile"
}
]
};
Fetching iOS carrier info #
IosCarrierData? carrierInfo = await CarrierInfo.getIosInfo();
// iOS 15.x and earlier - Full carrier information available
returns {
"carrierData": [
{
"mobileNetworkCode": "20",
"carrierAllowsVOIP": true,
"mobileCountryCode": "621",
"carrierName": "Airtel",
"isoCountryCode": "ng"
}
],
"supportsEmbeddedSIM": false,
"carrierRadioAccessTechnologyTypeList": ["LTE"],
"isSIMInserted": true,
"subscriberInfo": {
"subscriberCount": 1,
"subscriberIdentifiers": ["subscriber_id_here"],
"carrierTokens": ["token_here"]
},
"cellularPlanInfo": {
"supportsEmbeddedSIM": false
},
"networkStatus": {
"hasCellularData": true,
"activeServices": 1,
"technologies": ["LTE"]
},
"_ios_version_info": {
"ios_version": {...},
"ctcarrier_deprecated": false,
"deprecation_notice": "CTCarrier functionality is available on this iOS version."
}
}
// iOS 16.0+ - Limited carrier information due to CTCarrier deprecation
returns {
"carrierData": [
{
"mobileNetworkCode": null,
"carrierAllowsVOIP": null,
"mobileCountryCode": null,
"carrierName": null,
"isoCountryCode": null,
"_deprecated_notice": "CTCarrier is deprecated in iOS 16.0+. Carrier information is no longer available."
}
],
"supportsEmbeddedSIM": false,
"carrierRadioAccessTechnologyTypeList": ["LTE"],
"isSIMInserted": true,
"subscriberInfo": {
"subscriberCount": 1,
"subscriberIdentifiers": ["subscriber_id_here"],
"carrierTokens": ["token_here"]
},
"cellularPlanInfo": {
"supportsEmbeddedSIM": true
},
"networkStatus": {
"hasCellularData": true,
"activeServices": 1,
"technologies": ["LTE"]
},
"_ios_version_info": {
"ios_version": {...},
"ctcarrier_deprecated": true,
"deprecation_notice": "CTCarrier and CTSubscriber are deprecated in iOS 16.0+. Most carrier-specific information is no longer available for privacy and security reasons."
}
}
iOS Features #
Available on All iOS Versions #
SIM Detection
- isSIMInserted: Boolean indicating if a SIM card is inserted and active
- networkStatus: Real-time network connectivity information
- carrierRadioAccessTechnologyTypeList: Current radio technology (2G, 3G, 4G, 5G)
Network Status
"networkStatus": {
"hasCellularData": true, // Cellular data available
"activeServices": 1, // Number of active cellular services
"technologies": ["LTE"] // Current radio access technologies
}
Subscriber Information (iOS 16.0+)
"subscriberInfo": {
"subscriberCount": 1, // Number of subscribers (dual SIM)
"subscriberIdentifiers": ["subscriber_id"], // Subscriber identifiers
"carrierTokens": ["token"] // Carrier authentication tokens
}
Cellular Plan Information
"cellularPlanInfo": {
"supportsEmbeddedSIM": true // eSIM support detection
}
iOS Version Detection #
Use the _ios_version_info
field to detect capabilities:
final iosInfo = await CarrierInfo.getIosInfo();
final versionInfo = iosInfo?.toMap()['_ios_version_info'] as Map<String, dynamic>?;
final isDeprecated = versionInfo?['ctcarrier_deprecated'] as bool? ?? false;
if (isDeprecated) {
// Handle iOS 16.0+ limitations
print('SIM Inserted: ${iosInfo?.isSIMInserted}');
print('Network Status: ${iosInfo?.networkStatus?.hasCellularData}');
print('Radio Tech: ${iosInfo?.carrierRadioAccessTechnologyTypeList}');
} else {
// Full carrier information available
print('Carrier: ${iosInfo?.carrierData?.first.carrierName}');
print('MCC: ${iosInfo?.carrierData?.first.mobileCountryCode}');
}
iOS Limitations #
CTCarrier Deprecation (iOS 16.0+) #
Starting with iOS 16.0, Apple has deprecated the CTCarrier
class and related APIs for privacy and security reasons. This affects the following information:
❌ No longer available on iOS 16.0+:
- Carrier name (
carrierName
) - Mobile country code (
mobileCountryCode
) - Mobile network code (
mobileNetworkCode
) - ISO country code (
isoCountryCode
) - VOIP allowance (
carrierAllowsVOIP
)
✅ Still available on iOS 16.0+:
- SIM insertion detection (
isSIMInserted
) - Radio access technology types (
carrierRadioAccessTechnologyTypeList
) - Network status (
networkStatus
) - Subscriber information (
subscriberInfo
) - Cellular plan information (
cellularPlanInfo
)
Recommendations #
-
Check iOS version: Use the
_ios_version_info
field to determine if you're running on iOS 16.0+ and handle the limitations accordingly. -
Use available features: Focus on features that work across all iOS versions:
// These work on all iOS versions final simInserted = iosInfo?.isSIMInserted ?? false; final hasData = iosInfo?.networkStatus?.hasCellularData ?? false; final radioTech = iosInfo?.carrierRadioAccessTechnologyTypeList ?? [];
-
Graceful degradation: Design your app to work without carrier-specific information on newer iOS versions.
-
Alternative approaches: Consider using network-based detection or user input for carrier information when needed.
-
Android alternative: For apps that require detailed carrier information, consider using the Android implementation which still provides full functionality.
New iOS Models #
The plugin now includes enhanced models for iOS data:
- IosCarrierData: Main container with all carrier information
- CarrierData: Individual carrier information (nullable fields for iOS 16.0+)
- SubscriberInfo: Subscriber and carrier token information
- CellularPlanInfo: Cellular plan provisioning information
- NetworkStatus: Real-time network connectivity status
Technical References #
- Apple Developer Documentation - CTCarrier
- Apple Developer Documentation - CTSubscriber
- Apple Developer Documentation - CTCellularPlanProvisioning
- Stack Overflow Discussion
- iOS 16.0 Release Notes
Permissions #
You should add permissions that are required to your android manifest:
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.READ_BASIC_PHONE_STATE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.READ_PHONE_NUMBERS" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.READ_PRIVILEGED_PHONE_STATE" />
✨ Contribution #
Lots of PR's would be needed to make this plugin standard, as for iOS there's a permanent limitation for getting the exact data usage, there's only one way around it and it's super complex.