Flutter中如何获取当前提供移动数据的SIM卡网络信息?
识别当前提供移动数据的SIM卡(基于carrier_info插件扩展)
Android 端实现
carrier_info插件本身不直接返回当前数据SIM的标识,需要结合Android原生TelephonyManager API补充实现,步骤如下:
- 添加权限:在
android/app/src/main/AndroidManifest.xml中添加对应权限(根据系统版本选择):
<!-- Android 10 及以下 --> <uses-permission android:name="android.permission.READ_PHONE_STATE" /> <!-- Android 11+ --> <uses-permission android:name="android.permission.READ_PHONE_NUMBERS" />
注意要在Flutter代码中动态申请权限,避免权限不足导致崩溃。
- 通过MethodChannel调用原生方法获取数据SIM的Slot ID:
Flutter端代码:
static const MethodChannel _channel = MethodChannel('data_sim_channel'); Future<int?> getCurrentDataSimSlot() async { try { return await _channel.invokeMethod('getCurrentDataSimSlot'); } on PlatformException catch (e) { print('获取失败: ${e.message}'); return null; } }
Android原生端(在MainActivity中添加):
new MethodChannel(getFlutterEngine().getDartExecutor().getBinaryMessenger(), "data_sim_channel") .setMethodCallHandler((call, result) -> { if (call.method.equals("getCurrentDataSimSlot")) { TelephonyManager telephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE); if (checkSelfPermission(Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) { result.error("PERMISSION_DENIED", "需要读取电话状态权限", null); return; } int subscriptionId = telephonyManager.getDefaultDataSubscriptionId(); SubscriptionManager subscriptionManager = SubscriptionManager.from(this); SubscriptionInfo info = subscriptionManager.getActiveSubscriptionInfo(subscriptionId); if (info != null) { result.success(info.getSimSlotIndex() + 1); // 多数设备Slot从1开始计数,需根据测试调整 } else { result.success(null); } } else { result.notImplemented(); } });
- 匹配carrier_info的SIM信息:
拿到Slot ID后,遍历androidInfo.simInfos找到对应SIM:
int? dataSlot = await getCurrentDataSimSlot(); if (dataSlot != null && androidInfo != null) { var dataSim = androidInfo.simInfos.firstWhere( (sim) => sim.slotIndex == dataSlot, orElse: () => null, ); print('当前数据SIM卡信息: $dataSim'); }
iOS 端实现
iOS需借助CoreTelephony框架获取当前数据SIM标识,步骤如下:
- 添加权限描述:在
ios/Runner/Info.plist中添加:
<key>NSCellularNetworkUsageDescription</key> <string>需要获取蜂窝网络信息以识别当前数据SIM卡</string>
- MethodChannel调用原生方法:
Flutter端代码复用Android端的MethodChannel:
Future<String?> getCurrentDataSimIdentifier() async { try { return await _channel.invokeMethod('getCurrentDataSimIdentifier'); } on PlatformException catch (e) { print('获取失败: ${e.message}'); return null; } }
iOS原生端(在AppDelegate中添加):
let channel = FlutterMethodChannel(name: "data_sim_channel", binaryMessenger: window?.rootViewController as! FlutterBinaryMessenger) channel.setMethodCallHandler { [weak self] call, result in guard call.method == "getCurrentDataSimIdentifier" else { result.notImplemented() return } let networkInfo = CTTelephonyNetworkInfo() if #available(iOS 12.0, *) { if let dataServiceId = networkInfo.dataServiceIdentifier { result.success(dataServiceId) } else { result.success(nil) } } else { result.error("IOS_VERSION_LOW", "仅支持iOS 12及以上版本", nil) } }
- 匹配carrier_info的SIM信息:
拿到dataServiceIdentifier后,遍历iosInfo.simCards找到对应SIM:
String? dataId = await getCurrentDataSimIdentifier(); if (dataId != null && iosInfo != null) { var dataSim = iosInfo.simCards.firstWhere( (sim) => sim.serviceIdentifier == dataId, orElse: () => null, ); print('当前数据SIM卡信息: $dataSim'); }
注意事项
- 不同设备的Slot ID计数可能有差异(比如部分设备从0开始),需实际测试适配。
- Android 12+可能需要额外权限,需参考官方文档调整。
- iOS仅支持12及以上版本的双卡数据卡识别,低版本无法区分双卡。
内容的提问来源于stack exchange,提问作者Sealed
相关产品推荐
相关产品推荐

