1

我正在尝试构建一个 Android 拨号器应用程序(MinSDK 23)。

我想实现一个联系人搜索(通常在默认拨号器应用程序和其他第三方拨号器应用程序中可用),如下所示:

当我在拨号盘上键入数字时,例如 245

我应该能够搜索电话号码包含“245”的联系人以及他们的姓名包含与数字 245 的字母组合匹配的联系人,根据我的计算,这应该是 27 个唯一组合。

虽然我确实知道这是一个排列问题,并且我可以通过对联系人姓名应用 OR 'LIKE' 过滤器来进行搜索,但这似乎不够有效,并且在我不断输入例如 245658 时会导致更多性能问题。

我们如何有效地做到这一点?是否有任何内置搜索机制可以通过这种方式搜索 android 联系人,或者是否存在更好的自定义解决方案?

4

1 回答 1

0

这是我们公司的一个经典面试问题。

首先,不要为输入的每个数字都点击 ContactsContract API,您需要在启动期间运行单个查询以从 Contacts DB 中获取所有名称,以便您能够在内存中快速搜索它们。

就像是:

Map<String, Long> namesMap = new HashMap<>();
String[] projection = new String[]{Contacts._ID, Contacts.DISPLAY_NAME};
Cursor c = getContentResolver().query(Contacts.CONTENT_URI, projection, null, null, null);
while (c != null && c.moveToNext()) {
    namesMap.put(c.getString(1), c.getLong(0));
}
c.close();

接下来,过滤上述内容NamesMap以仅获取适合搜索数字的名称的最佳方法是生成正则表达式模式。

因此,搜索查询245将生成正则表达式:.*[2abc][4ghi][5jkl].*,这不应该太难构建,每个数字都映射到固定字符串:2-> [2abc]

准备好正则表达式模式后,您将遍历namesMap并仅返回键与模式匹配的条目。确保您进行不区分大小写的匹配,或者在构建时将所有名称小写namesMap

于 2019-09-15T07:06:13.117 回答