能否通过Telephony获取短信发送方的联系人姓名?
如何通过Android Telephony获取短信发送方的联系人姓名
完全可以实现,核心思路是通过Telephony获取短信发送方的电话号码(message.address),再结合Android的Contacts Provider查询匹配对应的联系人姓名,不需要额外依赖。
步骤说明
- 权限准备:需要申请
READ_SMS和READ_CONTACTS权限,Android 6.0及以上版本需动态申请。 - 获取短信发送方号码:在短信监听逻辑中,通过
SmsMessage的getOriginatingAddress()或直接读取message.address拿到发送方号码。 - 匹配联系人姓名:通过Contacts Provider的
ContactsContract.CommonDataKinds.Phone表,以拿到的号码为查询条件,获取对应的联系人显示名称。
代码示例
- 动态申请权限(Activity中实现)
private fun requestRequiredPermissions() { val permissions = arrayOf(Manifest.permission.READ_SMS, Manifest.permission.READ_CONTACTS) if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_SMS) != PackageManager.PERMISSION_GRANTED || ContextCompat.checkSelfPermission(this, Manifest.permission.READ_CONTACTS) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(this, permissions, 1001) } }
- 短信监听BroadcastReceiver(简化实现)
class SmsReceiver : BroadcastReceiver() { override fun onReceive(context: Context?, intent: Intent?) { if (Telephony.Sms.Intents.SMS_RECEIVED_ACTION == intent?.action) { val smsMessages = Telephony.Sms.Intents.getMessagesFromIntent(intent) for (message in smsMessages) { val senderNumber = message.originatingAddress val senderName = getContactNameByNumber(context, senderNumber) // 此处可直接使用senderName,未匹配到联系人则返回原号码 Log.d("SmsReceiver", "发送方:$senderName | 号码:$senderNumber") } } } private fun getContactNameByNumber(context: Context?, phoneNumber: String?): String? { if (context == null || phoneNumber.isNullOrEmpty()) return phoneNumber // 统一号码格式,去除空格、括号、加号等特殊字符,提升匹配率 val normalizedNumber = phoneNumber.replace("[^0-9]".toRegex(), "") val contentResolver = context.contentResolver val projection = arrayOf(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME) val selection = "${ContactsContract.CommonDataKinds.Phone.NORMALIZED_NUMBER} LIKE ?" val selectionArgs = arrayOf("%$normalizedNumber%") contentResolver.query( ContactsContract.CommonDataKinds.Phone.CONTENT_URI, projection, selection, selectionArgs, null )?.use { cursor -> if (cursor.moveToFirst()) { return cursor.getString(cursor.getColumnIndexOrThrow(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME)) } } // 未匹配到联系人时返回原号码 return phoneNumber } }
注意事项
- 号码格式处理:短信中的号码可能带区号、空格等格式,统一格式能有效提升匹配成功率。
- 权限校验:必须确保用户授予了对应权限,否则会导致查询失败。
- 性能优化:若频繁接收短信,建议对查询结果做缓存,避免重复查询Contacts Provider消耗资源。
内容的提问来源于stack exchange,提问作者Blue M
相关产品推荐
相关产品推荐

