已获取默认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
相关产品推荐
相关产品推荐

