mirror of
https://github.com/pppscn/SmsForwarder
synced 2025-08-03 01:17:41 +08:00
优化:手机号匹配通讯录联系人算法改进 #580
This commit is contained in:
parent
8b37862121
commit
992cabe323
@ -31,6 +31,7 @@ import com.xuexiang.xutil.data.DateUtils
|
|||||||
import com.xuexiang.xutil.resource.ResUtils.getString
|
import com.xuexiang.xutil.resource.ResUtils.getString
|
||||||
import java.text.SimpleDateFormat
|
import java.text.SimpleDateFormat
|
||||||
import java.util.Locale
|
import java.util.Locale
|
||||||
|
import kotlin.math.min
|
||||||
|
|
||||||
@Suppress("DEPRECATION")
|
@Suppress("DEPRECATION")
|
||||||
class PhoneUtils private constructor() {
|
class PhoneUtils private constructor() {
|
||||||
@ -339,7 +340,7 @@ class PhoneUtils private constructor() {
|
|||||||
|
|
||||||
//获取联系人列表
|
//获取联系人列表
|
||||||
fun getContactInfoList(
|
fun getContactInfoList(
|
||||||
limit: Int, offset: Int, phoneNumber: String?, name: String?
|
limit: Int, offset: Int, phoneNumber: String?, name: String?, isFuzzy: Boolean = true
|
||||||
): MutableList<ContactInfo> {
|
): MutableList<ContactInfo> {
|
||||||
val contactInfoList: MutableList<ContactInfo> = mutableListOf()
|
val contactInfoList: MutableList<ContactInfo> = mutableListOf()
|
||||||
|
|
||||||
@ -348,7 +349,11 @@ class PhoneUtils private constructor() {
|
|||||||
val selectionArgs = ArrayList<String>()
|
val selectionArgs = ArrayList<String>()
|
||||||
if (!TextUtils.isEmpty(phoneNumber)) {
|
if (!TextUtils.isEmpty(phoneNumber)) {
|
||||||
selection += " and replace(replace(" + ContactsContract.CommonDataKinds.Phone.NUMBER + ",' ',''),'-','') like ?"
|
selection += " and replace(replace(" + ContactsContract.CommonDataKinds.Phone.NUMBER + ",' ',''),'-','') like ?"
|
||||||
selectionArgs.add("%$phoneNumber%")
|
if (isFuzzy) {
|
||||||
|
selectionArgs.add("%$phoneNumber%")
|
||||||
|
} else {
|
||||||
|
selectionArgs.add("%$phoneNumber")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (!TextUtils.isEmpty(name)) {
|
if (!TextUtils.isEmpty(name)) {
|
||||||
selection += " and " + ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME + " like ?"
|
selection += " and " + ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME + " like ?"
|
||||||
@ -396,7 +401,61 @@ class PhoneUtils private constructor() {
|
|||||||
fun getContactByNumber(phoneNumber: String?): MutableList<ContactInfo> {
|
fun getContactByNumber(phoneNumber: String?): MutableList<ContactInfo> {
|
||||||
val contactInfoList = mutableListOf<ContactInfo>()
|
val contactInfoList = mutableListOf<ContactInfo>()
|
||||||
if (TextUtils.isEmpty(phoneNumber)) return contactInfoList
|
if (TextUtils.isEmpty(phoneNumber)) return contactInfoList
|
||||||
return getContactInfoList(1, 0, phoneNumber, null)
|
|
||||||
|
// 去除国际区号、空格、括号、横线等字符
|
||||||
|
val normalizedInputNumber = if (phoneNumber!!.startsWith("+") && phoneNumber.length > 4) {
|
||||||
|
phoneNumber.substring(4).replace("[^0-9]".toRegex(), "")
|
||||||
|
} else {
|
||||||
|
phoneNumber.replace("[^0-9]".toRegex(), "")
|
||||||
|
}
|
||||||
|
|
||||||
|
contactInfoList.addAll(getContactInfoList(99, 0, normalizedInputNumber, null, false))
|
||||||
|
if (contactInfoList.isEmpty() || contactInfoList.size == 1) {
|
||||||
|
return contactInfoList
|
||||||
|
}
|
||||||
|
|
||||||
|
// 计算每个联系人的匹配长度和优先级
|
||||||
|
val scoredContacts = contactInfoList.map { contact ->
|
||||||
|
//去除空格、括号、横线等字符
|
||||||
|
val normalizedContactNumber = contact.phoneNumber.replace("[^0-9]".toRegex(), "")
|
||||||
|
val matchLength = calculateMatchLength(normalizedInputNumber, normalizedContactNumber)
|
||||||
|
// 优先级规则:
|
||||||
|
// 1. 完全匹配(输入手机号与联系人手机号完全一致):优先级 2
|
||||||
|
// 2. 匹配长度等于输入手机号长度:优先级 1
|
||||||
|
// 3. 其他情况:优先级 0
|
||||||
|
val priority = when {
|
||||||
|
normalizedInputNumber == normalizedContactNumber -> 2
|
||||||
|
matchLength == normalizedInputNumber.length -> 1
|
||||||
|
else -> 0
|
||||||
|
}
|
||||||
|
contact to Pair(matchLength, priority)
|
||||||
|
}.sortedWith(compareByDescending<Pair<ContactInfo, Pair<Int, Int>>> { it.second.first } // 按匹配长度降序
|
||||||
|
.thenByDescending { it.second.second }) // 按优先级降序
|
||||||
|
|
||||||
|
// 返回匹配长度最长且优先级最高的联系人列表
|
||||||
|
val maxMatchLength = scoredContacts.first().second.first
|
||||||
|
val maxPriority = scoredContacts.first().second.second
|
||||||
|
return scoredContacts
|
||||||
|
.filter { it.second.first == maxMatchLength && it.second.second == maxPriority }
|
||||||
|
.map { it.first }
|
||||||
|
.toMutableList()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 计算从右向左的匹配长度
|
||||||
|
private fun calculateMatchLength(number1: String, number2: String): Int {
|
||||||
|
var matchLength = 0
|
||||||
|
val minLength = min(number1.length, number2.length)
|
||||||
|
|
||||||
|
// 从右向左逐位比较
|
||||||
|
for (i in 1..minLength) {
|
||||||
|
if (number1[number1.length - i] == number2[number2.length - i]) {
|
||||||
|
matchLength++
|
||||||
|
} else {
|
||||||
|
break // 遇到不匹配的字符,停止比较
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return matchLength
|
||||||
}
|
}
|
||||||
|
|
||||||
//获取通话记录转发内容
|
//获取通话记录转发内容
|
||||||
@ -590,4 +649,4 @@ class PhoneUtils private constructor() {
|
|||||||
init {
|
init {
|
||||||
throw UnsupportedOperationException("u can't instantiate me...")
|
throw UnsupportedOperationException("u can't instantiate me...")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user