carrier_info 3.0.3 copy "carrier_info: ^3.0.3" to clipboard
carrier_info: ^3.0.3 copied to clipboard

Carrier Info gets networkType, networkGeneration, mobileCountryCode, mobileCountryCode, e.t.c from both android and ios devices

example/lib/main.dart

import 'dart:async';
import 'dart:io';

import 'package:carrier_info/carrier_info.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatefulWidget {
  const MyApp({super.key});

  @override
  State createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  IosCarrierData? _iosInfo;
  IosCarrierData? get iosInfo => _iosInfo;
  set iosInfo(IosCarrierData? iosInfo) {
    setState(() => _iosInfo = iosInfo);
  }

  AndroidCarrierData? _androidInfo;
  AndroidCarrierData? get androidInfo => _androidInfo;
  set androidInfo(AndroidCarrierData? carrierInfo) {
    setState(() => _androidInfo = carrierInfo);
  }

  @override
  void initState() {
    super.initState();
    initPlatformState();
  }

  // Platform messages are asynchronous, so we initialize in an async method.
  Future<void> initPlatformState() async {
    // Platform messages may fail, so we use a try/catch PlatformException.
    try {
      if (Platform.isAndroid) androidInfo = await CarrierInfo.getAndroidInfo();
      if (Platform.isIOS) iosInfo = await CarrierInfo.getIosInfo();
    } catch (e) {
      print('Error getting carrier info: $e');
    }

    // If the widget was removed from the tree while the asynchronous platform
    // message was in flight, we want to discard the reply rather than calling
    // setState to update our non-existent appearance.
  }

  @override
  Widget build(BuildContext context) {
    return Material(
      color: Colors.transparent,
      child: CupertinoApp(
        debugShowCheckedModeBanner: false,
        home: CupertinoPageScaffold(
          navigationBar: CupertinoNavigationBar(
            middle: const Text('Carrier Info example app'),
            border: Border.symmetric(
              horizontal: BorderSide(
                width: 0.5,
                color: CupertinoColors.systemGrey2.withOpacity(0.4),
              ),
            ),
          ),
          backgroundColor: CupertinoColors.lightBackgroundGray,
          child: Platform.isAndroid
              ? AndroidUI(androidInfo: androidInfo)
              : IosUI(iosInfo: iosInfo),
        ),
      ),
    );
  }
}

class IosUI extends StatelessWidget {
  const IosUI({
    super.key,
    this.iosInfo,
  });

  final IosCarrierData? iosInfo;

  String formatIOSVersion(Map<String, dynamic>? versionDict) {
    if (versionDict == null) return 'Unknown';

    final major = versionDict['majorVersion'] ?? 0;
    final minor = versionDict['minorVersion'] ?? 0;
    final patch = versionDict['patchVersion'] ?? 0;

    return '$major.$minor.$patch';
  }

  @override
  Widget build(BuildContext context) {
    // Check if we're on iOS 16.0+ and show deprecation notice
    final versionInfo =
        iosInfo?.toMap()['_ios_version_info'] as Map<String, dynamic>?;
    final isDeprecated = versionInfo?['ctcarrier_deprecated'] as bool? ?? false;

    return ListView(
      children: [
        const SizedBox(height: 20),

        // Show deprecation notice if on iOS 16.0+
        if (isDeprecated) ...[
          Container(
            margin: const EdgeInsets.all(15),
            padding: const EdgeInsets.all(15),
            decoration: BoxDecoration(
              color: CupertinoColors.systemYellow.withOpacity(0.1),
              borderRadius: BorderRadius.circular(8),
              border: Border.all(
                color: CupertinoColors.systemYellow.withOpacity(0.3),
              ),
            ),
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                const Row(
                  children: [
                    Icon(
                      CupertinoIcons.exclamationmark_triangle,
                      color: CupertinoColors.systemYellow,
                      size: 16,
                    ),
                    SizedBox(width: 8),
                    Text(
                      'iOS 16.0+ Limitation',
                      style: TextStyle(
                        fontWeight: FontWeight.bold,
                        color: CupertinoColors.systemYellow,
                      ),
                    ),
                  ],
                ),
                const SizedBox(height: 8),
                Text(
                  versionInfo?['deprecation_notice'] as String? ??
                      'CTCarrier is deprecated. Most carrier information is unavailable.',
                  style: const TextStyle(
                    fontSize: 13,
                    color: CupertinoColors.systemGrey,
                  ),
                ),
              ],
            ),
          ),
        ],

        // Device Status Section
        const Padding(
          padding: EdgeInsets.all(15),
          child: Text(
            'DEVICE STATUS',
            style: TextStyle(
              fontSize: 15,
              color: CupertinoColors.systemGrey,
            ),
          ),
        ),

        HomeItem(
          title: 'SIM Inserted',
          value: '${iosInfo?.isSIMInserted ?? false}',
          isFirst: true,
        ),

        // iOS Version Info
        if (versionInfo != null) ...[
          HomeItem(
            title: 'iOS Version',
            value: formatIOSVersion(
                versionInfo['ios_version'] as Map<String, dynamic>?),
          ),
          HomeItem(
            title: 'CTCarrier Deprecated',
            value: '${versionInfo['ctcarrier_deprecated'] ?? false}',
          ),
        ],

        // Network Status Section
        if (iosInfo?.networkStatus != null) ...[
          const SizedBox(height: 20),
          const Padding(
            padding: EdgeInsets.all(15),
            child: Text(
              'NETWORK STATUS',
              style: TextStyle(
                fontSize: 15,
                color: CupertinoColors.systemGrey,
              ),
            ),
          ),
          HomeItem(
            title: 'Has Cellular Data',
            value: '${iosInfo?.networkStatus?.hasCellularData ?? false}',
            isFirst: true,
          ),
          HomeItem(
            title: 'Active Services',
            value: '${iosInfo?.networkStatus?.activeServices ?? 0}',
          ),
          HomeItem(
            title: 'Technologies',
            value: (iosInfo?.networkStatus?.technologies?.isNotEmpty ?? false)
                ? iosInfo!.networkStatus!.technologies!.join(', ')
                : 'None',
          ),
        ],

        // Subscriber Information Section
        if (iosInfo?.subscriberInfo != null) ...[
          const SizedBox(height: 20),
          const Padding(
            padding: EdgeInsets.all(15),
            child: Text(
              'SUBSCRIBER INFORMATION',
              style: TextStyle(
                fontSize: 15,
                color: CupertinoColors.systemGrey,
              ),
            ),
          ),
          HomeItem(
            title: 'Subscriber Count',
            value: '${iosInfo?.subscriberInfo?.subscriberCount ?? 0}',
            isFirst: true,
          ),
          HomeItem(
            title: 'Subscriber IDs',
            value: (iosInfo?.subscriberInfo?.subscriberIdentifiers.isNotEmpty ??
                    false)
                ? iosInfo!.subscriberInfo!.subscriberIdentifiers.join(', ')
                : 'None',
          ),
          if (iosInfo?.subscriberInfo?.carrierTokens != null)
            HomeItem(
              title: 'Carrier Tokens',
              value:
                  '${iosInfo?.subscriberInfo?.carrierTokens?.length ?? 0} tokens available',
            ),
        ],

        // Cellular Plan Information Section
        if (iosInfo?.cellularPlanInfo != null) ...[
          const SizedBox(height: 20),
          const Padding(
            padding: EdgeInsets.all(15),
            child: Text(
              'CELLULAR PLAN INFORMATION',
              style: TextStyle(
                fontSize: 15,
                color: CupertinoColors.systemGrey,
              ),
            ),
          ),
          HomeItem(
            title: 'Supports Embedded SIM',
            value: '${iosInfo?.cellularPlanInfo?.supportsEmbeddedSIM ?? false}',
            isFirst: true,
          ),
        ],

        // Legacy supportsEmbeddedSIM (for backward compatibility)
        if (iosInfo?.cellularPlanInfo == null && iosInfo != null) ...[
          const SizedBox(height: 20),
          const Padding(
            padding: EdgeInsets.all(15),
            child: Text(
              'LEGACY CARRIER INFORMATION',
              style: TextStyle(
                fontSize: 15,
                color: CupertinoColors.systemGrey,
              ),
            ),
          ),
          HomeItem(
            title: 'supportsEmbeddedSIM (Legacy)',
            value: '${iosInfo?.supportsEmbeddedSIM ?? false}',
            isFirst: true,
          ),
        ],

        // Radio Access Technology (still works on iOS 16.0+)
        if ((iosInfo?.carrierRadioAccessTechnologyTypeList ?? [])
            .isNotEmpty) ...[
          const SizedBox(height: 20),
          const Padding(
            padding: EdgeInsets.all(15),
            child: Text(
              'RADIO ACCESS TECHNOLOGY (Available on all iOS versions)',
              style: TextStyle(
                fontSize: 15,
                color: CupertinoColors.systemGrey,
              ),
            ),
          ),
          ...(iosInfo?.carrierRadioAccessTechnologyTypeList ?? [])
              .asMap()
              .entries
              .map(
                (entry) => HomeItem(
                  title: 'Technology ${entry.key + 1}',
                  value: entry.value ?? 'Unknown',
                  isFirst: entry.key == 0,
                ),
              ),
        ],

        // Carrier Data (limited on iOS 16.0+)
        if ((iosInfo?.carrierData ?? []).isNotEmpty) ...[
          const SizedBox(height: 20),
          const Padding(
            padding: EdgeInsets.all(15),
            child: Text(
              'CARRIER DATA',
              style: TextStyle(
                fontSize: 15,
                color: CupertinoColors.systemGrey,
              ),
            ),
          ),
          ...(iosInfo?.carrierData ?? []).asMap().entries.map(
            (entry) {
              final index = entry.key;
              final carrierData = entry.value;
              final carrierMap = carrierData.toMap();

              return Column(
                children: [
                  if (index > 0) const SizedBox(height: 15),
                  Padding(
                    padding: const EdgeInsets.all(15),
                    child: Row(
                      children: [
                        Text(
                          'SIM ${index + 1}: ${carrierData.carrierName ?? 'Unknown'}',
                          style: const TextStyle(
                            fontSize: 15,
                            color: CupertinoColors.systemGrey,
                          ),
                        ),
                        if (isDeprecated) ...[
                          const SizedBox(width: 8),
                          const Icon(
                            CupertinoIcons.exclamationmark_triangle_fill,
                            color: CupertinoColors.systemYellow,
                            size: 14,
                          ),
                        ],
                      ],
                    ),
                  ),
                  ...carrierMap.entries.map(
                    (e) {
                      // Skip internal fields
                      if (e.key.startsWith('_')) return const SizedBox.shrink();

                      // Highlight deprecated fields
                      final isDeprecatedField = isDeprecated &&
                          [
                            'carrierName',
                            'mobileCountryCode',
                            'mobileNetworkCode',
                            'isoCountryCode',
                            'carrierAllowsVOIP'
                          ].contains(e.key);

                      return HomeItem(
                        title: e.key,
                        value: e.value?.toString() ?? 'null',
                        isDeprecated: isDeprecatedField,
                      );
                    },
                  ),
                ],
              );
            },
          ),
        ],

        // Show a message if no data is available
        if (iosInfo == null) ...[
          const SizedBox(height: 50),
          const Center(
            child: Column(
              children: [
                Icon(
                  CupertinoIcons.info_circle,
                  size: 50,
                  color: CupertinoColors.systemGrey,
                ),
                SizedBox(height: 16),
                Text(
                  'Loading carrier information...',
                  style: TextStyle(
                    fontSize: 16,
                    color: CupertinoColors.systemGrey,
                  ),
                ),
              ],
            ),
          ),
        ],

        const SizedBox(height: 20),
      ],
    );
  }
}

class AndroidUI extends StatelessWidget {
  const AndroidUI({
    super.key,
    this.androidInfo,
  });

  final AndroidCarrierData? androidInfo;

  @override
  Widget build(BuildContext context) {
    return ListView(
      children: [
        const SizedBox(height: 20),
        Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            const Padding(
              padding: EdgeInsets.all(15),
              child: Text(
                'CARRIER INFORMATION',
                style: TextStyle(
                  fontSize: 15,
                  color: CupertinoColors.systemGrey,
                ),
              ),
            ),
            HomeItem(
              title: 'isVoiceCapable',
              value: '${androidInfo?.isVoiceCapable ?? false}',
              isFirst: true,
            ),
            HomeItem(
              title: 'isSmsCapable',
              value: '${androidInfo?.isSmsCapable ?? false}',
            ),
            HomeItem(
              title: 'isMultiSimSupported',
              value: '${androidInfo?.isMultiSimSupported ?? 'Unknown'}',
            ),
            HomeItem(
              title: 'isDataCapable',
              value: '${androidInfo?.isDataCapable ?? false}',
            ),
            HomeItem(
              title: 'isDataEnabled',
              value: '${androidInfo?.isDataEnabled ?? false}',
            ),
            ...(androidInfo?.telephonyInfo ?? []).map((it) {
              return Padding(
                padding: const EdgeInsets.symmetric(vertical: 15),
                child: Column(
                  children: [
                    Text(
                      'SIM: ${it.phoneNumber ?? 'Unknown'} (from telephonyInfo)',
                      style: const TextStyle(
                        fontSize: 15,
                        color: CupertinoColors.systemGrey,
                      ),
                    ),
                    const SizedBox(height: 15),
                    ...(it.toMap()).entries.map(
                          (val) => HomeItem(
                            title: '${val.key}',
                            value: '${val.value ?? 'N/A'}',
                          ),
                        )
                  ],
                ),
              );
            }),
            ...(androidInfo?.subscriptionsInfo ?? []).map((it) {
              return Column(
                children: [
                  Text(
                    'SIM: ${it.phoneNumber ?? 'Unknown'} (from subscriptionsInfo)',
                    style: const TextStyle(
                      fontSize: 15,
                      color: CupertinoColors.systemGrey,
                    ),
                  ),
                  const SizedBox(height: 15),
                  ...(it.toMap()).entries.map(
                        (val) => HomeItem(
                          title: '${val.key}',
                          value: '${val.value ?? 'N/A'}',
                        ),
                      )
                ],
              );
            }),

            // Show a message if no data is available
            if (androidInfo == null) ...[
              const SizedBox(height: 50),
              const Center(
                child: Column(
                  children: [
                    Icon(
                      CupertinoIcons.info_circle,
                      size: 50,
                      color: CupertinoColors.systemGrey,
                    ),
                    SizedBox(height: 16),
                    Text(
                      'Loading carrier information...',
                      style: TextStyle(
                        fontSize: 16,
                        color: CupertinoColors.systemGrey,
                      ),
                    ),
                  ],
                ),
              ),
            ],
          ],
        ),
      ],
    );
  }
}

class HomeItem extends StatelessWidget {
  final bool isFirst;
  final String title;
  final String? value;
  final bool isDeprecated;

  const HomeItem({
    super.key,
    required this.title,
    this.value,
    this.isFirst = false,
    this.isDeprecated = false,
  });

  @override
  Widget build(BuildContext context) {
    return Material(
      color: Colors.white,
      child: InkWell(
        onTap: () {},
        child: Column(
          children: [
            if (!isFirst)
              Container(height: 0.5, color: Colors.grey.withOpacity(0.3)),
            Padding(
              padding: const EdgeInsets.all(15),
              child: Row(
                mainAxisAlignment: MainAxisAlignment.spaceBetween,
                children: [
                  Row(
                    children: [
                      Text(
                        title,
                        style: TextStyle(
                          color:
                              isDeprecated ? CupertinoColors.systemGrey : null,
                        ),
                      ),
                      if (isDeprecated) ...[
                        const SizedBox(width: 4),
                        const Icon(
                          CupertinoIcons.exclamationmark_triangle_fill,
                          color: CupertinoColors.systemYellow,
                          size: 12,
                        ),
                      ],
                    ],
                  ),
                  const Spacer(),
                  Flexible(
                    child: Wrap(
                      alignment: WrapAlignment.start,
                      crossAxisAlignment: WrapCrossAlignment.start,
                      children: [
                        Text(
                          value ?? 'N/A',
                          style: TextStyle(
                            color: isDeprecated
                                ? CupertinoColors.systemGrey
                                : null,
                            fontStyle: isDeprecated ? FontStyle.italic : null,
                          ),
                        ),
                      ],
                    ),
                  ),
                ],
              ),
            ),
          ],
        ),
      ),
    );
  }
}
79
likes
140
points
5.92k
downloads

Publisher

verified publishercodenka.com

Weekly Downloads

Carrier Info gets networkType, networkGeneration, mobileCountryCode, mobileCountryCode, e.t.c from both android and ios devices

Repository (GitHub)

Documentation

API reference

License

MIT (license)

Dependencies

flutter, flutter_lints

More

Packages that depend on carrier_info

Packages that implement carrier_info