Android - 使用国家/地区代码与号码联系

时间:2013-04-24 11:25:15

标签: java android sql android-contacts

从传入的短信中检索手机号码时,会附加国家/地区代码 现在,由于数据库中的匹配联系人可能不包含用于获取我正在使用的联系人姓名的国家/地区代码:

public static String getContactName(String number, Context context) {

    try {

        Uri personUri = Uri.withAppendedPath(
            ContactsContract.PhoneLookup.CONTENT_FILTER_URI, Uri.encode(number.trim()));
        String selection = PhoneLookup.NUMBER + " LIKE %" + number.trim() + "%";
        Cursor cur = context.getContentResolver().query(personUri,
            new String[] {
            PhoneLookup.DISPLAY_NAME
        },
            selection, null, null);
        if (cur.moveToFirst()) {
            String str = cur.getString(cur.getColumnIndex(PhoneLookup.DISPLAY_NAME));
            cur.close();
            return str;
        }
    } catch (Exception e) {
        //e.printStackTrace();
        return number;
    }
    return number;
}

如果我传入完全匹配或部分匹配,这将非常有效。但是,如果我想获取联系人ID,我正在使用此代码:

public static Contact getContact(String number, ContentResolver contentResolver) {

    Contact contact = new Contact(-1, number);
    try {
        Uri personUri = Uri.withAppendedPath(ContactsContract.CommonDataKinds.Phone.CONTENT_FILTER_URI, Uri.encode(number));
        String selection = ContactsContract.CommonDataKinds.Phone.NUMBER + " LIKE '%" + number + "%'";
        Cursor cur = contentResolver.query(personUri,
            new String[] {
            ContactsContract.CommonDataKinds.Phone.CONTACT_ID, PhoneLookup.DISPLAY_NAME
        },
            selection, null, null);
        if (cur.moveToFirst()) {
            contact = new Contact(Integer.parseInt(cur.getString(cur.getColumnIndex(ContactsContract.CommonDataKinds.Phone.CONTACT_ID))),
                cur.getString(cur.getColumnIndex(PhoneLookup.DISPLAY_NAME)));
        }
        cur.close();
    } catch (Exception e) {}
    return contact;
}

如果数字完全匹配,这种方法很完美,但如果不是,则不返回任何内容。我需要这种方法来查找联系人的ID,其号码保存为“01111111111”,传入号码为“+441111111111”。虽然他们正在查看不同的URI,但选择代码几乎相同,所以我不确定为什么它不适用于第二种。

有什么想法吗?

8 个答案:

答案 0 :(得分:9)

我使用此代码进行相同的处理,并返回名称 通过从相同的代码返回contactId,您的问题将得到解决

public static String getContactDisplayNameByNumber(String number) {
    Uri uri = Uri.withAppendedPath(
            ContactsContract.PhoneLookup.CONTENT_FILTER_URI,
            Uri.encode(number));
    String name = "?";

    ContentResolver contentResolver = context.getContentResolver();
    Cursor contactLookup = contentResolver.query(uri, new String[] {
            BaseColumns._ID, ContactsContract.PhoneLookup.DISPLAY_NAME },
            null, null, null);

    try {
        if (contactLookup != null && contactLookup.getCount() > 0) {
            contactLookup.moveToNext();
            name = contactLookup.getString(contactLookup
                    .getColumnIndex(ContactsContract.Data.DISPLAY_NAME));
            // String contactId =
            // contactLookup.getString(contactLookup.getColumnIndex(BaseColumns._ID));
        }
    } finally {
        if (contactLookup != null) {
            contactLookup.close();
        }
    }

    return name;
}

答案 1 :(得分:7)

上个月我遇到了同样的问题,我设法使用谷歌的libphonenumber库解决了这个问题。

问题只发生在本地/国家电话号码上,因为它们可以在没有国家代码或使用“0”的情况下保存。

例如:

印度的典型电话号码可以采用以下格式保存

  a. +919665123456
  b. 919665123456
  c. 09665123456
  d. 9665123456

以上每种都是完全有效的格式,只能在印度拨打

但是,如果属于您所在国家/地区以外的电话号码必须通过国家/地区代码保存,或者您将无法拨打电话。

ex. 

 a. +1732-757-2923    (US)
 b. +97433-456-789    (Qatar)

因此,如果相关联系人是local/national,那么匹配联系人的问题确实会发生。

这就是libphonenumber进入画面的地方。使用该库,我们可以提取属于该特定国家/地区的实际国家格式的电话号码。

这就是诀窍。首先将收到的数字从短信传递给uri,以便在数据库中进行匹配。如果不匹配则提取国内电话号码      使用libphonenumber,然后再次将其作为uri进行匹配。 (Uri.encode(number)

它适用于我的情况。

我以下列方式使用它。

public String getContactDisplayNameByNumber(String number) {

    if (number != null && number.length() != 0) {

        String name = lookupNumber(number);

        if (!name.contains(number))
            return name;
        else {

            TelephonyManager manager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);

            String usersCountryISOCode = manager.getNetworkCountryIso();

            PhoneNumberUtil phoneUtil = PhoneNumberUtil.getInstance();
            try {
                PhoneNumber phonenUmber = phoneUtil.parse(name,
                        usersCountryISOCode);
                if (phoneUtil.isValidNumber(phonenUmber)) {
                    temp = phoneUtil
                            .getNationalSignificantNumber(phonenUmber);


                    name = lookupNumber(temp);
                    return name;
                }

            } catch (Exception e) {

                e.printStackTrace();

            }
            return number;
        }
    } else {
        return "Invalid Number";
    }
}

private String lookupNumber(String number) {

    uri = Uri.withAppendedPath(
            ContactsContract.PhoneLookup.CONTENT_FILTER_URI,
            Uri.encode(number));
    name = number;

    contentResolver = getContentResolver();
    contactLookup = contentResolver.query(uri, columns, null, null, null);

    try {
        if (contactLookup != null && contactLookup.getCount() > 0) {
            contactLookup.moveToNext();
            name = contactLookup.getString(contactLookup
                    .getColumnIndex(ContactsContract.Data.DISPLAY_NAME));

        }
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        if (contactLookup != null) {
            contactLookup.close();
        }
    }

    return name;
}

希望它能解决你的问题。

答案 2 :(得分:2)

针对此类问题,Google本身为我们提供了专为Android手机设计的库。不要使用任何类型的有线代码,请查看经验丰富的开发人员测试的Google官方库。

使用 libphonenumber 谷歌库,用于解析,格式化,存储和验证国际电话号码。

此目标网页上有很多代码段,所以我认为不需要在这里编写任何代码,只能在那里理解它们。

http://code.google.com/p/libphonenumber/

他们已经提供了资源如何解析和如何匹配。

此图书馆的相关功能。

  • 解析/格式化/验证所有国家/地区的电话号码 世界。

  • isNumberMatch - 获得两个数字是否可以的置信度 是一样的。

  • findNumbers - 在文本输入中查找数字。

答案 3 :(得分:0)

答案 4 :(得分:0)

如果我回答你的问题是正确的,我就不会放弃,但正如我所知道的那样,你有问题所在,说唱者可能会以两种不同的方式出现。有或没有国家代码。

我想有两个简单的解决方案。最简单的方法是更改​​收件箱中的读取输入。收件箱将始终具有可以修剪的国家/地区代码。 例如

String inboxNo; //the number you've read from the inbox
int length = inboxNo.length     
if ((inboxNo.equals(whatYouAreSearching) || (String withOutCountryCode = "0"+ inboxNo.substring(3,length-1))
...

其他解决方案可能是您检查数据库的第一个字符并进行转换 e.g。

if(!dataBaseNo.substring(0,1).contanins("+"){
dataBaseNo = "+44" + dataBaseNo.substring(1,length-1);
...

答案 5 :(得分:0)

也许您可以将静态变量(数组或其他内容)与所有国家/地区代码一起使用,并使用2遍方法来正确匹配代码。如果添加了国家/地区代码或其他内容,则可以通过更新刷新此阵列,或者如果您需要非常好,可以在线从标准源提取并从您的应用程序触发定期更新。

private static int countrycodes[]; // define the entire data here
...
{
...
for(int i=0;i<countrycodes.length;i++){
    //match using regexp or something and flag this for 2nd pass
    }
}

答案 6 :(得分:0)

虽然我的解决方案可能看起来很脏,但这可能会解决问题。

    String number = "your number";
    ContentResolver contentResolver; // content resolver
    Contact c;
    if (number != null) {
        if (number.charAt(0) == '+') {
            c = getContact(number.substring(1), contentResolver);
            if (c.firstField == -1) {
                c = getContact(number.substring(2), contentResolver);
                if (c.firstField == -1) {
                    c = getContact(number.substring(3), contentResolver);
                }
            }
        } else {
            c = getContact(number, contentResolver);
            if (c.firstField == -1) {
                c = getContact(number.substring(1), contentResolver);
                if (c.firstField == -1) {
                    c = getContact(number.substring(2), contentResolver);
                }
            }
        }
    }

希望它有所帮助...

答案 7 :(得分:0)

这项技术适用于我,通过使用:

来解析部分号码
//encode the phone number and build the filter URI
Uri contactUri = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, Uri.encode(number.substring(len-9)));

String selection = PhoneLookup.NUMBER + " LIKE %" + number.substring(len-9) + "%";

Cursor cursor = context.getContentResolver().query(contactUri, projection, selection, null, null);

完整示例:

private void getContactDetails(String number) {
    // define the columns you want the query to return
    String[] projection = new String[] {
        PhoneLookup.DISPLAY_NAME,
        PhoneLookup._ID,
        PhoneLookup.LOOKUP_KEY};
    int len = number.length();
    // encode the phone number and build the filter URI
    Uri contactUri = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, Uri.encode(number.substring(len-9)));

    String selection = PhoneLookup.NUMBER + " LIKE %" + number.substring(len-9) + "%";

    Cursor cursor = context.getContentResolver().query(contactUri, projection, selection, null, null);

    if(cursor != null) {
        if (cursor.moveToFirst()) {
            String name = cursor.getString(cursor.getColumnIndex(PhoneLookup.DISPLAY_NAME));
            String lookUpKey = cursor.getString(cursor.getColumnIndex(PhoneLookup.LOOKUP_KEY));
        }
        cursor.close();
    }
}

它解析并匹配最后10位数字,希望它会有所帮助!!!