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

Flutter获取Android设备手机号的可行方案及实现指导

Android设备SIM卡手机号获取方案(Flutter)

这个需求可以实现,但需注意:手机号的获取依赖运营商是否将号码写入SIM卡的MSISDN字段,部分场景下无法获取到(比如运营商未写入)。以下是通过Flutter MethodChannel调用原生Android代码的实现方案,覆盖单/多SIM卡场景:

一、权限配置

在android/app/src/main/AndroidManifest.xml中添加必要权限:

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

二、动态申请权限

Android 6.0及以上需要动态申请危险权限,使用permission_handler插件处理:

  1. 添加依赖到pubspec.yaml:
dependencies:
  flutter:
    sdk: flutter
  permission_handler: ^10.2.0
  1. Flutter端权限申请代码:
import 'package:permission_handler/permission_handler.dart';

Future<bool> requestPermissions() async {
  final phonePerm = await Permission.phone.request();
  final smsPerm = await Permission.sms.request();
  
  return phonePerm.isGranted && smsPerm.isGranted;
}

三、通过MethodChannel调用原生代码

Flutter端代码

创建工具类封装MethodChannel调用:

import 'package:flutter/services.dart';

class SimPhoneNumberHelper {
  static const _channel = MethodChannel('sim_phone_number');

  static Future<List<String>> getPhoneNumbers() async {
    try {
      final List<dynamic> numbers = await _channel.invokeMethod('getPhoneNumbers');
      return numbers.cast<String>();
    } on PlatformException catch (e) {
      print('获取手机号失败: ${e.message}');
      return [];
    }
  }
}

Android原生端代码

在MainActivity.kt中实现MethodChannel逻辑,处理单/多SIM卡:

import android.content.Context
import android.telephony.SubscriptionManager
import android.telephony.TelephonyManager
import androidx.annotation.NonNull
import io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugin.common.MethodChannel

class MainActivity : FlutterActivity() {
    private val CHANNEL = "sim_phone_number"

    override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) {
        super.configureFlutterEngine(flutterEngine)
        MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL).setMethodCallHandler { call, result ->
            if (call.method == "getPhoneNumbers") {
                val numbers = getSimPhoneNumbers()
                result.success(numbers)
            } else {
                result.notImplemented()
            }
        }
    }

    private fun getSimPhoneNumbers(): List<String> {
        val numbers = mutableListOf<String>()
        val telephonyManager = getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager

        // Android 8.0+ 多SIM卡处理
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
            val subscriptionManager = getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE) as SubscriptionManager
            val activeSubs = subscriptionManager.activeSubscriptionInfoList
            
            activeSubs?.forEach { info ->
                info.number?.takeIf { it.isNotEmpty() }?.let { numbers.add(it) }
            }
        } else {
            // 兼容低版本单SIM卡,部分设备支持多SIM卡反射调用
            telephonyManager.line1Number?.takeIf { it.isNotEmpty() }?.let { numbers.add(it) }
            
            try {
                val method = telephonyManager.javaClass.getMethod("getLine1Number", Int::class.javaPrimitiveType)
                val secondNumber = method.invoke(telephonyManager, 1) as String?
                secondNumber?.takeIf { it.isNotEmpty() }?.let { numbers.add(it) }
            } catch (e: Exception) {
                // 不支持则忽略
            }
        }

        return numbers
    }
}

四、应用启动时调用

在main.dart的初始化阶段执行获取逻辑:

import 'package:flutter/material.dart';

void main() => runApp(const MyApp());

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

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

class _MyAppState extends State<MyApp> {
  @override
  void initState() {
    super.initState();
    _fetchAndPrintPhoneNumbers();
  }

  Future<void> _fetchAndPrintPhoneNumbers() async {
    final hasPerm = await requestPermissions();
    if (!hasPerm) {
      print("权限被拒绝,无法获取手机号");
      return;
    }

    final numbers = await SimPhoneNumberHelper.getPhoneNumbers();
    if (numbers.isEmpty) {
      print("未获取到手机号(可能运营商未将号码写入SIM卡)");
      return;
    }

    print("设备SIM卡手机号列表:");
    for (int i = 0; i < numbers.length; i++) {
      print("SIM ${i+1}: ${numbers[i]}");
    }
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: const Text("手机号获取示例")),
        body: const Center(child: Text("查看控制台输出")),
      ),
    );
  }
}

关键注意点

  • 手机号获取成功率依赖运营商是否将MSISDN写入SIM卡,无法保证100%获取。
  • Android 10及以上版本,READ_PHONE_STATE权限不足以获取手机号,需配合READ_SMS权限。
  • 低版本Android的多SIM卡支持依赖厂商实现,部分设备无法获取第二张卡的号码。

内容的提问来源于stack exchange,提问作者S. M. Asif

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 13:22:12