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

已获取默认SMS角色,TelecomManager.getLine1Number返回null求助

问题描述
  • 已将应用设置为设备默认SMS角色持有者,满足Google读取设备标识符的权限要求
  • 可正常读取两张SIM卡的IMEI,但调用TelecomManager.getLine1Number()始终返回null,默认SMS应用理应具备获取号码用于短信功能的权限,附上当前C#代码寻求修复方案,接受Android Java实现

当前C#代码:

try
{
    if (roleManager.IsRoleHeld(RoleManager.RoleSms))
    {
        var manager = (TelephonyManager)GetSystemService(Context.TelephonyService);
        new Android.App.AlertDialog.Builder(this).SetTitle("Device Identifiers")
                      .SetMessage("phone no " + manager.Line1Number + "\n" + "line 1 imei: " + manager.GetImei(0) + "\n" +
                      "line 2 imei: " + manager.GetImei(1) + "\n" +
                      "serial no: " + manager.SimSerialNumber

                      ).Show();
        //telephonyManager.GetLine1 fails so
        //try and use the telecom service to read the number
        var telcom = (TelecomManager)GetSystemService(Context.TelecomService);
        //get a list of all capable calling accounts
        IList<PhoneAccountHandle> handles = telcom.CallCapablePhoneAccounts;
        if (handles != null)
        {
            //Toast the phone capable calling accounts count
            Toast.MakeText(this, handles.Count.ToString(), ToastLength.Short).Show();
            //get the phone account handle in index 0
            PhoneAccountHandle handle1 = handles[0];
            //get the phone number associated with that acount
            string phone1 = telcom.GetLine1Number(handle1);
            if (phone1 != null)
            {
                new Android.App.AlertDialog.Builder(this).SetTitle("Phone Number")
                    .SetMessage(phone1).Show();
            }
        }
        string phone = telcom.GetLine1Number(handles[1]);
        if (phone != null)
        {
            Toast.MakeText(this,phone,ToastLength.Short).Show();
        }
        else
        {
            Toast.MakeText(this, "GetLine1 is returning null", ToastLength.Short).Show();
        }
    }
} catch (Java.Lang.SecurityException exc)
{
    Toast.MakeText(this, exc.Message, ToastLength.Short).Show();
}
修复方案

1. 先排查SIM卡硬件/运营商问题

部分运营商不会将手机号码写入SIM卡的EF_MSISDN存储字段,此时无论应用权限是否足够,系统都无法读取到号码。可以:

  • 将SIM卡插入其他安卓设备,检查系统是否能显示本机号码
  • 联系运营商确认是否已将号码写入SIM卡

2. 代码逻辑优化

核心优化点

  • 针对多SIM卡场景,必须对卡槽索引做合法性校验,避免空指针或越界
  • TelephonyManager需指定卡槽索引获取对应号码,而非使用默认的Line1Number
  • 补充TelecomManager的PhoneAccount.getAddress()作为备选获取方式

修复后的C#代码

try
{
    if (roleManager.IsRoleHeld(RoleManager.RoleSms))
    {
        var telephonyManager = (TelephonyManager)GetSystemService(Context.TelephonyService);
        // 获取卡槽0和卡槽1的号码(指定索引)
        string slot0Number = telephonyManager.GetLine1Number(0);
        string slot1Number = telephonyManager.GetLine1Number(1);

        // 显示IMEI和号码信息
        new Android.App.AlertDialog.Builder(this)
            .SetTitle("设备标识符")
            .SetMessage($"卡槽1号码: {slot0Number ?? "未获取到"}\n" +
                        $"卡槽1IMEI: {telephonyManager.GetImei(0)}\n" +
                        $"卡槽2号码: {slot1Number ?? "未获取到"}\n" +
                        $"卡槽2IMEI: {telephonyManager.GetImei(1)}\n" +
                        $"SIM序列号: {telephonyManager.SimSerialNumber}")
            .Show();

        var telecomManager = (TelecomManager)GetSystemService(Context.TelecomService);
        IList<PhoneAccountHandle> callableAccounts = telecomManager.CallCapablePhoneAccounts;

        if (callableAccounts != null && callableAccounts.Count > 0)
        {
            // 遍历所有可通话账户,尝试获取号码
            foreach (var accountHandle in callableAccounts)
            {
                PhoneAccount account = telecomManager.GetPhoneAccount(accountHandle);
                // 优先用GetLine1Number,备选用PhoneAccount的Address
                string phoneNumber = telecomManager.GetLine1Number(accountHandle);
                if (phoneNumber == null && account != null)
                {
                    phoneNumber = account.Address?.ToString();
                }

                if (!string.IsNullOrEmpty(phoneNumber))
                {
                    Toast.MakeText(this, $"账户号码: {phoneNumber}", ToastLength.Short).Show();
                }
                else
                {
                    Toast.MakeText(this, $"账户{accountHandle.Id}未获取到号码", ToastLength.Short).Show();
                }
            }
        }
    }
}
catch (Java.Lang.SecurityException exc)
{
    Toast.MakeText(this, $"权限异常: {exc.Message}", ToastLength.Short).Show();
}
catch (Java.Lang.IndexOutOfBoundsException exc)
{
    Toast.MakeText(this, "卡槽索引越界", ToastLength.Short).Show();
}

对应的Android Java实现

try {
    if (roleManager.isRoleHeld(RoleManager.ROLE_SMS)) {
        TelephonyManager telephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
        // 获取指定卡槽的号码
        String slot0Number = telephonyManager.getLine1Number(0);
        String slot1Number = telephonyManager.getLine1Number(1);

        new AlertDialog.Builder(this)
                .setTitle("设备标识符")
                .setMessage(String.format("卡槽1号码: %s\n卡槽1IMEI: %s\n卡槽2号码: %s\n卡槽2IMEI: %s\nSIM序列号: %s",
                        slot0Number != null ? slot0Number : "未获取到",
                        telephonyManager.getImei(0),
                        slot1Number != null ? slot1Number : "未获取到",
                        telephonyManager.getImei(1),
                        telephonyManager.getSimSerialNumber()))
                .show();

        TelecomManager telecomManager = (TelecomManager) getSystemService(Context.TELECOM_SERVICE);
        List<PhoneAccountHandle> callableAccounts = telecomManager.getCallCapablePhoneAccounts();

        if (callableAccounts != null && !callableAccounts.isEmpty()) {
            for (PhoneAccountHandle accountHandle : callableAccounts) {
                PhoneAccount account = telecomManager.getPhoneAccount(accountHandle);
                String phoneNumber = telecomManager.getLine1Number(accountHandle);
                if (phoneNumber == null && account != null) {
                    phoneNumber = account.getAddress() != null ? account.getAddress().toString() : null;
                }

                if (phoneNumber != null && !phoneNumber.isEmpty()) {
                    Toast.makeText(this, "账户号码: " + phoneNumber, Toast.LENGTH_SHORT).show();
                } else {
                    Toast.makeText(this, "账户" + accountHandle.getId() + "未获取到号码", Toast.LENGTH_SHORT).show();
                }
            }
        }
    }
} catch (SecurityException e) {
    Toast.makeText(this, "权限异常: " + e.getMessage(), Toast.LENGTH_SHORT).show();
} catch (IndexOutOfBoundsException e) {
    Toast.makeText(this, "卡槽索引越界", Toast.LENGTH_SHORT).show();
}

额外说明

  • 即使是默认SMS应用,也无法保证100%获取到手机号码,这取决于SIM卡是否存储了号码、运营商是否提供该字段
  • 部分安卓定制系统可能对号码读取有额外限制,需测试不同品牌设备

内容的提问来源于stack exchange,提问作者TechGeek

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 21:15:34