Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/188.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 在通讯录提供商中搜索多种格式的电话号码?_Android - Fatal编程技术网

Android 在通讯录提供商中搜索多种格式的电话号码?

Android 在通讯录提供商中搜索多种格式的电话号码?,android,Android,我一直在编写一段代码,让用户按姓名、电子邮件或电话号码搜索联系人(使用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.Common

我一直在编写一段代码,让用户按姓名、电子邮件或电话号码搜索联系人(使用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();
                    }
但是,电话号码搜索有问题。在contacts中,电话号码的格式多种多样:

  • +101234567890
  • (123)456-7890
  • 1234567890
  • 123-456-7890
等等

我如何调整我的联系人查询过滤器,以便用户的输入可以找到任何格式的电话号码——最好不要使整个查询速度非常慢

我发现有些解决方案依赖于编辑表格数据来标准化电话号码,而联系人则不能这样做。也许那个标准化的数字字段会起作用。。。如果我能找到一种方法,轻松地将其构建到Contacts数据表的查询中。我知道我可以对每一条记录进行额外的电话号码搜索,或者使用Java进行检查,但我认为这会使它变得非常缓慢。可能是查询中的一个regexp SQL操作符,但我不知道如何让它在用户可能只输入了部分电话号码的逐字符搜索中工作


有什么想法吗?

你可以使用Android内置的SQLite函数
PHONE_NUMBERS_EQUAL
来实现这一点,该函数比较两个数字,如果它们完全相同,就可以返回
1

您只需更改
过滤器
,如下所示:

String filter = "(" + ContactsContract.Data.MIMETYPE + "=? OR "
    + ContactsContract.Data.MIMETYPE + "=?) AND "
    + "(PHONE_NUMBERS_EQUAL(" + ContactsContract.Data.DATA1 + ", ?, 0) OR "
    + ContactsContract.Data.DATA1 + " LIKE ? OR "
    + ContactsContract.Data.DISPLAY_NAME + " LIKE ?)";
并将另一个
通配符约束
添加到您的
过滤器参数

String[] filterParams = new String[] { ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE,
                                       ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE,
                                       wildcardedConstraint,
                                       wildcardedConstraint,
                                       wildcardedConstraint };
PHONE_NUMBERS_EQUAL
函数中的最后一个
INTEGER
参数指示是否使用严格的数字比较<代码>1表示严格,而
0
表示不严格。显然,这是一个系统范围的设置,可以从系统
资源
中检索,但我不确定是什么因素决定了如何为特定环境确定这一设置。上面的示例仅使用非严格比较。然而,如果是一个问题,实际资源价值可以如下获得:

private static final String STRICT_COMPARE = "config_use_strict_phone_number_comparation";

...

int strictResId = Resources.getSystem().getIdentifier(STRICT_COMPARE, "bool", "android");
boolean useStrict = Resources.getSystem().getBoolean(strictResId);

不是复制品。另一个问题是关于如何对电话号码进行基本搜索。上面的代码已经成功地按姓名、电子邮件地址或电话号码进行了更高级的搜索。问题是当联系人中的电话号码有多种格式时,如何搜索,而这不是其他问题所考虑的;匹配不同格式的数字。请注意其中提到的呼叫者ID。如果您不想使用它,请使用
PhoneNumberUtils.compare()
,手动筛选当前数据集。请稍候。我刚刚想到了另一种方法,您可以使用现有的查询执行此操作。让我做一些测试。等等我刚意识到我的问题不正确。给我一分钟来修复它。好的,我认为这与您对原始版本所做的一致。哇,多么酷的功能!我不知道那件事。我也很欣赏详细的代码示例!但有两个问题:第一,它实际上似乎不起作用?第二,我猜它只会比较准确的电话号码——所以在逐字输入时,它会失败,至少在输入完整的号码之前是如此(在这种情况下,不需要自动完成)?不用担心。是的,不久前我在浏览MMS/SMS提供商源代码时遇到了这个功能。在提到
PhoneNumberUtils.compare()
方法之前,我已经忘记了这一点。希望对你有用。干杯现在,我有一个查询正在部分使用
AutoCompleteTextView
。不得不采用更为野蛮的方法。如你所知,
电话号码\u EQUAL
不能用于此,如果我仔细阅读了你的问题并注意到你使用的是
自动完成文本视图
,我甚至可能不会提到它。不管怎样,我仍然要找出为什么我会得到一些错误的匹配,但我最终应该有一些可行的方法。