You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter中如何获取当前提供移动数据的SIM卡网络信息?

识别当前提供移动数据的SIM卡(基于carrier_info插件扩展)

Android 端实现

carrier_info插件本身不直接返回当前数据SIM的标识,需要结合Android原生TelephonyManager API补充实现,步骤如下:

  1. 添加权限:在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代码中动态申请权限,避免权限不足导致崩溃。

  1. 通过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();
        }
    });
  1. 匹配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标识,步骤如下:

  1. 添加权限描述:在ios/Runner/Info.plist中添加:
<key>NSCellularNetworkUsageDescription</key>
<string>需要获取蜂窝网络信息以识别当前数据SIM卡</string>
  1. 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)
    }
}
  1. 匹配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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 07:52:36