【发布时间】:2016-04-27 03:14:41
【问题描述】:
我一直在编写一段代码,让用户可以按姓名、电子邮件或电话号码搜索(使用 AutoCompleteTextView 逐个字符)联系人。我已经制定了以下代码:
// General contact data, so we have to get the DATA1 attribute and use MIMETYPE
// to figure out what it is. Usually we'd query, say, ContactsContract.CommonDataKinds.Email.CONTENT_URI
Uri uri = ContactsContract.Data.CONTENT_URI;
// Limit the query results to only the columns we need for faster operations.
// Using a projection also seems to make the query DISTINCT
String[] projection = new String[] {ContactsContract.Contacts.DISPLAY_NAME,
ContactsContract.Data.DATA1,
ContactsContract.Data.MIMETYPE};
// Find contact records with an email address or phone number
// Search the name and data1 field (which may contain an email or phone number)
// for user-entered search phrase
String filter = "(" + ContactsContract.Data.MIMETYPE + "=? OR " + ContactsContract.Data.MIMETYPE + "=?)"
+ " AND (" + ContactsContract.Data.DATA1 + " LIKE ? OR " + ContactsContract.Data.DISPLAY_NAME + " LIKE ?)";
String wildcardedConstraint = "%" + constraintString + "%";
String[] filterParams = new String[]{ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE, ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE, wildcardedConstraint, wildcardedConstraint};
// Sort contacts with the most recently contacted ones first. That's often 0 (unset)
// so do a sub-sort by last updated date, most recent contacts first
String orderBy = ContactsContract.Contacts.LAST_TIME_CONTACTED + " DESC, " + ContactsContract.Contacts.CONTACT_LAST_UPDATED_TIMESTAMP + " DESC";
Cursor cursor = getContext().getContentResolver().query(uri, projection, filter, filterParams, orderBy);
if (cursor != null) {
while (cursor.moveToNext()) {
String name = cursor.getString(cursor.getColumnIndex(ContactsContract.Data.DISPLAY_NAME));
String data1 = cursor.getString(cursor.getColumnIndex(ContactsContract.Data.DATA1));
String mimetype = cursor.getString(cursor.getColumnIndex(ContactsContract.Data.MIMETYPE));
String number = null;
String email = null;
if (mimetype.equals(ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE)) {
email = data1;
} else if (mimetype.equals(ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE)) {
number = data1;
}
items.add(new Person(name, number, email));
Log.e("temp", name + " " + data1 + " " + mimetype);
}
cursor.close();
}
但是,电话号码搜索存在问题。在通讯录中,电话号码有多种不同的格式:
- +101234567890
- (123) 456-7890
- 1234567890
- 123-456-7890
等等。
如何调整我的联系人查询过滤器,以便用户的输入可以找到任何格式的电话号码 - 最好不要让整个查询变得非常慢?
我发现的一些解决方案依赖于编辑表格数据来标准化电话号码,这不是联系人的选项。也许规范化的数字字段会起作用......如果我能找到一种方法来轻松地将它构建到联系人数据表上的这个查询中。我知道我可以对每条记录进行额外的电话号码搜索,或者使用 Java 进行检查,但我认为这会使其非常慢。可能是查询中的正则表达式 SQL 运算符——但我不知道如何使它适用于用户可能只输入部分电话号码的逐字符搜索。
有什么想法吗?
【问题讨论】:
-
不是重复的。另一个问题是关于如何对电话号码进行基本搜索。上面的代码已经成功地通过姓名、电子邮件地址或电话号码进行了更高级的搜索。问的问题是当联系人中的电话号码是多种格式时如何进行搜索,这是其他问题甚至没有考虑的问题。
-
这就是
PhoneLookup表的用途;匹配不同格式的数字。注意它提到来电显示的地方。如果您不想使用它,请使用PhoneNumberUtils.compare()手动过滤当前数据集。 -
等一下。我只是想到了另一种方法,你可以用现有的查询来做到这一点。让我做一些测试。
标签: android