sim_phone_plus

A Flutter plugin to retrieve SIM phone numbers and SIM card details in a safe, interactive, and user-friendly way.

Features

  • Fetch SIM phone numbers and metadata (carrier name, country ISO, SIM slot index).
  • Handles Android 10+ restrictions gracefully.
  • Provides structured fallback responses when phone numbers are unavailable.
  • iOS returns a clear “not supported” response with a helpful message.
  • Helper APIs to check for device support and permission status.

Screenshots

Before Permission After Permission
Before Permission After Permission

Note: Please replace screenshot_1.png and screenshot_2.png in the assets/images directory with your own screenshots.

Platform Limitations

Android

Due to Android's privacy changes, getting phone numbers is not always possible. This plugin gracefully handles these limitations and will return null for the phone number if it cannot be retrieved. It will, however, still provide other SIM card details.

iOS

iOS does not allow programmatic access to SIM card information or phone numbers. This plugin will return a "not supported" message on iOS devices.

Permissions

Android

This plugin requires the READ_PHONE_STATE permission. You must add the following to your AndroidManifest.xml file:

<uses-permission android:name="android.permission.READ_PHONE_STATE"/>

API

  • Future<List<SimPhoneInfo>> getSimPhoneInfo()
  • Future<bool> isSupported()
  • Future<bool> hasPermission()
  • Future<void> requestPermission()

Example

import 'package:flutter/material.dart';
import 'dart:async';

import 'package:flutter/services.dart';
import 'package:sim_phone_plus/sim_phone_plus.dart';
import 'package:sim_phone_plus/sim_phone_info.dart';

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

class MyApp extends StatefulWidget {
  const MyApp({Key? key}) : super(key: key);

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

class _MyAppState extends State<MyApp> {
  List<SimPhoneInfo> _simPhoneInfo = [];
  bool _hasPermission = false;

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

  Future<void> initPlatformState() async {
    final simPhonePlus = SimPhonePlus();
    bool hasPermission = await simPhonePlus.hasPermission();

    if (hasPermission) {
      List<SimPhoneInfo> simPhoneInfo = await simPhonePlus.getSimPhoneInfo();
      setState(() {
        _simPhoneInfo = simPhoneInfo;
        _hasPermission = hasPermission;
      });
    } else {
      setState(() {
        _hasPermission = hasPermission;
      });
    }

    if (!mounted) return;
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: const Text('Sim Phone Plus Example'),
        ),
        body: Center(
          child: Column(
            children: [
              if (!_hasPermission)
                ElevatedButton(
                  onPressed: () async {
                    final simPhonePlus = SimPhonePlus();
                    await simPhonePlus.requestPermission();
                    initPlatformState();
                  },
                  child: const Text('Request Permission'),
                ),
              ListView.builder(
                shrinkWrap: true,
                itemCount: _simPhoneInfo.length,
                itemBuilder: (context, index) {
                  final sim = _simPhoneInfo[index];
                  return ListTile(
                    title: Text('SIM Card ${sim.slotIndex}'),
                    subtitle: Text(
                        'Carrier: ${sim.carrierName}\nNumber: ${sim.phoneNumber ?? 'N/A'}\nCountry ISO: ${sim.countryIso}\nMessage: ${sim.message}'),
                  );
                },
              ),
            ],
          ),
        ),
      ),
    );
  }
}