sim_reader 1.0.1
sim_reader: ^1.0.1 copied to clipboard
A powerful Flutter plugin for reading SIM card information including carrier name, country code, phone number, network details, and more. Supports both single and dual SIM devices across Android and i [...]
SIM Reader 📱 #
Publisher Name | Pub Score | Pub Version |
---|---|---|
A powerful Flutter plugin for reading SIM card information including carrier name, country code, phone number, network details, and more. Supports both single and dual SIM devices across Android and iOS platforms.
✨ Features #
- 📋 Comprehensive SIM Information: Carrier name, country code, MCC/MNC, phone number
- 📱 Dual SIM Support: Read information from multiple SIM cards
- 🌐 Network Details: Network operator, type (2G/3G/4G/5G), availability status
- 🔒 Permission Management: Built-in permission handling and requests
- 🚀 Cross Platform: Works on both Android and iOS
- ⚡ Easy Integration: Simple API with comprehensive error handling
- 🛡️ Privacy Focused: Respects platform limitations and user privacy
🚀 Quick Start #
Installation #
Add this to your package's pubspec.yaml
file:
dependencies:
sim_reader: ^1.0.0
permission_handler: ^10.4.3 # For runtime permissions
Then run:
flutter pub get
Basic Usage #
import 'package:sim_reader/sim_reader.dart';
import 'package:permission_handler/permission_handler.dart';
// Request permission first
await Permission.phone.request();
// Check if device has SIM card
bool hasSimCard = await SimReader.hasSimCard();
// Get primary SIM card information
SimInfo? simInfo = await SimReader.getSimInfo();
// Get all SIM cards (for dual SIM devices)
List<SimInfo> allSimCards = await SimReader.getAllSimInfo();
// Get network information
NetworkInfo? networkInfo = await SimReader.getNetworkInfo();
Complete Example #
import 'package:flutter/material.dart';
import 'package:sim_reader/sim_reader.dart';
import 'package:permission_handler/permission_handler.dart';
class SimReaderDemo extends StatefulWidget {
@override
_SimReaderDemoState createState() => _SimReaderDemoState();
}
class _SimReaderDemoState extends State<SimReaderDemo> {
List<SimInfo> simCards = [];
NetworkInfo? networkInfo;
bool isLoading = true;
String? error;
@override
void initState() {
super.initState();
loadSimInfo();
}
Future<void> loadSimInfo() async {
try {
// Request permission
PermissionStatus status = await Permission.phone.request();
if (!status.isGranted) {
setState(() {
error = 'Phone permission is required';
isLoading = false;
});
return;
}
// Get SIM information
final allSimInfo = await SimReader.getAllSimInfo();
final netInfo = await SimReader.getNetworkInfo();
setState(() {
simCards = allSimInfo;
networkInfo = netInfo;
isLoading = false;
});
} on SimReaderException catch (e) {
setState(() {
error = e.message;
isLoading = false;
});
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('SIM Reader Demo')),
body: isLoading
? Center(child: CircularProgressIndicator())
: error != null
? Center(child: Text('Error: $error'))
: ListView.builder(
itemCount: simCards.length,
itemBuilder: (context, index) {
final sim = simCards[index];
return Card(
child: ListTile(
leading: Icon(Icons.sim_card),
title: Text(sim.carrierName ?? 'Unknown'),
subtitle: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('Country: ${sim.countryCode?.toUpperCase()}'),
if (sim.phoneNumber != null)
Text('Phone: ${sim.phoneNumber}'),
Text('MCC/MNC: ${sim.mobileCountryCode}/${sim.mobileNetworkCode}'),
],
),
),
);
},
),
floatingActionButton: FloatingActionButton(
onPressed: loadSimInfo,
child: Icon(Icons.refresh),
),
);
}
}
🛠️ Platform Setup #
Android Configuration #
Add the following permissions to your android/app/src/main/AndroidManifest.xml
:
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<!-- Required permissions -->
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<!-- Optional: For phone number access on Android 10+ -->
<uses-permission android:name="android.permission.READ_PHONE_NUMBERS" />
<application>
<!-- Your app configuration -->
</application>
</manifest>
iOS Configuration #
No additional configuration required. The plugin uses the CoreTelephony framework which is automatically available.
📚 API Reference #
SimReader Class #
Static Methods
Method | Return Type | Description |
---|---|---|
getSimInfo() |
Future<SimInfo?> |
Get primary SIM card information |
getAllSimInfo() |
Future<List<SimInfo>> |
Get all available SIM cards |
hasSimCard() |
Future<bool> |
Check if device has SIM card |
getNetworkInfo() |
Future<NetworkInfo?> |
Get network operator information |
SimInfo Class #
Represents SIM card information:
class SimInfo {
final String? carrierName; // Carrier/operator name
final String? countryCode; // ISO country code (e.g., "US", "IN")
final String? mobileCountryCode; // Mobile Country Code (MCC)
final String? mobileNetworkCode; // Mobile Network Code (MNC)
final String? phoneNumber; // Phone number (limited availability)
final String? simSerialNumber; // SIM serial number/ICCID
final String? subscriberId; // Subscriber ID/IMSI (Android only)
final int? simSlotIndex; // SIM slot index (0, 1, etc.)
final bool isNetworkRoaming; // Whether device is roaming
}
Example Usage
SimInfo? simInfo = await SimReader.getSimInfo();
if (simInfo != null) {
print('Carrier: ${simInfo.carrierName}');
print('Country: ${simInfo.countryCode}');
print('Phone: ${simInfo.phoneNumber}');
print('MCC: ${simInfo.mobileCountryCode}');
print('MNC: ${simInfo.mobileNetworkCode}');
print('Roaming: ${simInfo.isNetworkRoaming}');
}
NetworkInfo Class #
Represents network information:
class NetworkInfo {
final String? networkOperatorName; // Network operator name
final String? networkOperator; // Network operator code
final String? networkType; // Network type (2G, 3G, 4G, 5G, LTE, etc.)
final bool isNetworkAvailable; // Network availability status
final int? signalStrength; // Signal strength (limited support)
}
Example Usage
NetworkInfo? networkInfo = await SimReader.getNetworkInfo();
if (networkInfo != null) {
print('Operator: ${networkInfo.networkOperatorName}');
print('Type: ${networkInfo.networkType}');
print('Available: ${networkInfo.isNetworkAvailable}');
}
SimReaderException #
Custom exception for SIM Reader specific errors:
try {
final simInfo = await SimReader.getSimInfo();
} on SimReaderException catch (e) {
print('SIM Reader Error: ${e.message}');
} catch (e) {
print('General Error: $e');
}
🔐 Permission Handling #
Automatic Permission Requests #
import 'package:permission_handler/permission_handler.dart';
Future<bool> requestSimPermissions() async {
PermissionStatus status = await Permission.phone.status;
if (status.isDenied) {
status = await Permission.phone.request();
}
if (status.isPermanentlyDenied) {
// Open app settings
await openAppSettings();
return false;
}
return status.isGranted;
}
// Usage
if (await requestSimPermissions()) {
final simInfo = await SimReader.getAllSimInfo();
// Handle SIM information
} else {
// Handle permission denied
}
Permission Status Checking #
Future<void> checkPermissionStatus() async {
PermissionStatus status = await Permission.phone.status;
switch (status) {
case PermissionStatus.granted:
print('Permission granted');
break;
case PermissionStatus.denied:
print('Permission denied');
break;
case PermissionStatus.permanentlyDenied:
print('Permission permanently denied');
break;
case PermissionStatus.restricted:
print('Permission restricted');
break;
default:
print('Permission status: $status');
}
}
🌍 Platform Differences #
Android Capabilities #
- ✅ Full SIM information access
- ✅ Phone number (when available and permitted)
- ✅ SIM serial number and subscriber ID
- ✅ Complete dual SIM support
- ✅ Detailed network type information
- ✅ Roaming status
iOS Capabilities #
- ✅ Carrier information (name, MCC, MNC)
- ✅ Country code
- ✅ Basic network information
- ✅ Multiple SIM detection (iOS 12+)
- ❌ Phone number (Apple privacy restriction)
- ❌ SIM serial number (not available via public APIs)
- ❌ Subscriber ID (not available via public APIs)
- ⚠️ Limited roaming information
🔧 Advanced Usage #
Dual SIM Handling #
Future<void> handleDualSim() async {
List<SimInfo> allSims = await SimReader.getAllSimInfo();
if (allSims.length > 1) {
print('Device has dual SIM');
for (int i = 0; i < allSims.length; i++) {
SimInfo sim = allSims[i];
print('SIM ${i + 1}:');
print(' Slot: ${sim.simSlotIndex}');
print(' Carrier: ${sim.carrierName}');
print(' Country: ${sim.countryCode}');
}
} else if (allSims.length == 1) {
print('Device has single SIM');
} else {
print('No SIM cards found');
}
}
Network Type Detection #
Future<void> checkNetworkType() async {
NetworkInfo? networkInfo = await SimReader.getNetworkInfo();
if (networkInfo != null) {
String networkType = networkInfo.networkType ?? 'Unknown';
switch (networkType.toUpperCase()) {
case 'LTE':
case '4G':
print('4G/LTE network detected');
break;
case '5G':
case 'NR':
print('5G network detected');
break;
case '3G':
case 'UMTS':
case 'HSDPA':
case 'HSUPA':
case 'HSPA':
print('3G network detected');
break;
case '2G':
case 'GSM':
case 'GPRS':
case 'EDGE':
print('2G network detected');
break;
default:
print('Network type: $networkType');
}
}
}
Error Handling Best Practices #
class SimReaderHelper {
static Future<List<SimInfo>> getSafeSimInfo() async {
try {
// Check permission first
if (!await Permission.phone.isGranted) {
throw SimReaderException('Permission not granted');
}
// Check if SIM card exists
if (!await SimReader.hasSimCard()) {
throw SimReaderException('No SIM card found');
}
// Get SIM information
List<SimInfo> simCards = await SimReader.getAllSimInfo();
if (simCards.isEmpty) {
throw SimReaderException('SIM information not available');
}
return simCards;
} on SimReaderException catch (e) {
print('SIM Reader specific error: ${e.message}');
rethrow;
} catch (e) {
print('Unexpected error: $e');
throw SimReaderException('Failed to get SIM information: $e');
}
}
}
🐛 Troubleshooting #
Common Issues #
1. Permission Denied
- Cause: Required permissions not granted
- Solution: Request
READ_PHONE_STATE
permission at runtime
2. No SIM Information
- Cause: SIM card not present or information restricted
- Solution: Check
hasSimCard()
first, test on real device
3. Build Errors
- Android: Update compileSdkVersion to 33+
- iOS: Run
pod install
in ios directory
4. Emulator Issues
- Solution: Test on real device with active SIM card
Debug Helper #
Future<void> debugSimReader() async {
print('=== SIM Reader Debug ===');
try {
// Permission check
bool hasPermission = await Permission.phone.isGranted;
print('Permission granted: $hasPermission');
if (!hasPermission) {
print('Requesting permission...');
PermissionStatus status = await Permission.phone.request();
print('Permission status: $status');
}
// SIM card check
bool hasSim = await SimReader.hasSimCard();
print('Has SIM card: $hasSim');
if (hasSim) {
// Get all SIM info
List<SimInfo> sims = await SimReader.getAllSimInfo();
print('SIM count: ${sims.length}');
for (int i = 0; i < sims.length; i++) {
SimInfo sim = sims[i];
print('SIM $i: ${sim.carrierName} (${sim.countryCode})');
}
// Network info
NetworkInfo? network = await SimReader.getNetworkInfo();
if (network != null) {
print('Network: ${network.networkOperatorName} (${network.networkType})');
}
}
} catch (e) {
print('Debug error: $e');
}
print('=== Debug Complete ===');
}
📋 Requirements #
- Flutter: 3.0.0 or higher
- Dart: 3.0.0 or higher
- Android: API level 16+ (Android 4.1+)
- iOS: iOS 9.0 or higher
🤝 Contributing #
Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.
Development Setup #
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature
) - Commit your changes (
git commit -m 'Add some amazing feature'
) - Push to the branch (
git push origin feature/amazing-feature
) - Open a Pull Request
📄 License #
This project is licensed under the MIT License - see the LICENSE file for details.
🙏 Acknowledgments #
- Flutter team for the excellent plugin architecture
- Contributors and users who provided feedback and suggestions
- Mobile platform teams for providing SIM card access APIs
📞 Support #
- Issues: GitHub Issues
- Documentation: API Documentation
- Examples: Check the
/example
directory for complete working examples
🔗 Related Packages #
permission_handler
- For handling runtime permissionsdevice_info_plus
- For additional device informationconnectivity_plus
- For network connectivity status
Made with ❤️ by the SIM Reader team