Android - контакт с номером с кодом страны

При получении мобильного номера от входящего смс к нему добавлен код страны.
Теперь, когда соответствующий контакт в базе данных может не включать код страны для получения имени контакта, которое я использую:

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;
}

Это отлично работает, если я передаю точное совпадение или частичное совпадение. Однако, если я хочу получить идентификатор контакта, я использую этот код:

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;
}

Это работает отлично, если число является точным совпадением, но если оно не возвращает ничего. Мне нужен этот метод, чтобы найти идентификатор контакта, где его номер сохраняется как "01111111111", а входящий номер "+441111111111". Хотя они смотрят на другой URI, код выбора практически такой же, поэтому я не уверен, почему он не работает для второго.

Любые идеи?

Ответ 1

Я использую этот код для одного и того же повтора и возвращает имя возвращая 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;
}

Ответ 2

У меня была такая же проблема в прошлом месяце, и мне удалось ее решить, используя библиотеку google libphonenumber.

Проблема возникает только с локальными/национальными телефонными номерами, поскольку они могут быть сохранены без кода страны или с помощью "0".

Например:

Типичный номер телефона в Индии можно сохранить в следующих форматах

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

и каждый из вышеперечисленных файлов является абсолютно допустимым форматом для набора только в Индии

Но если телефонные номера, принадлежащие не родной стране, должны быть сохранены в обязательном порядке с кодом страны или вы не сможете позвонить.

ex. 

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

Таким образом, проблема согласования контактов действительно возникает, если связанный контакт local/national.

И что там, где libphonenumber входит в картину. Используя библиотеку, мы можем извлечь номер телефона в фактическом национальном формате, принадлежащем этой конкретной стране.

Вот трюк. Сначала передайте полученный номер из sms, как и для 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;
}

Надеюсь, что он решает вашу проблему.

Ответ 3

Для такого типа проблем Google сам предоставил нам библиотеки, специально предназначенные для телефонов Android. Не используйте какой-либо проводной код, посмотрите официальную библиотеку Google, протестированную опытными разработчиками.

Используйте libphonenumber библиотеку google, предназначенную для синтаксического анализа, форматирования, хранения и проверки международных телефонных номеров.

На этой целевой странице появилось много фрагментов кода, поэтому мне не нужно писать какой-либо код здесь, вы можете понять их только там.

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

Они предоставили ресурс Как разобрать и как совместить.

Особенности этой библиотеки, относящиеся к вам.

  • Анализ/форматирование/проверка номеров телефонов для всех стран/регионов мира.

  • isNumberMatch - получает уровень уверенности в том, могут ли два числа быть тем же.

  • findNumbers - находит числа в текстовом вводе.

Ответ 5

Я не уйду, если я отвечу на ваш вопрос правильно, но, как я понял, у вас есть проблема, что phonenumer может отображаться двумя разными способами. С или без кода страны.

Я предполагаю, что будет два простых решения. Проще всего было бы изменить ввод данных из вашего почтового ящика. Входящие всегда будут иметь код страны, который можно было бы обрезать. например

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))
...

Другим решением может быть то, что вы проверяете первый символ своей базы данных и конвертируете его например.

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

Ответ 6

Может быть, вы можете использовать статическую переменную (массив или что-то еще) со всеми кодами стран и использовать двухпроходный подход для правильного соответствия кода. Если код страны добавлен или что-то еще, этот массив может быть обновлен либо обновлением, либо если вам нужно быть действительно хорошим, вытащите из стандартного источника в Интернете и запускайте периодическое обновление из своего приложения.

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
    }
}

Ответ 7

Хотя мое решение может выглядеть грязным, но это может сделать трюк.

    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);
                }
            }
        }
    }

Надеюсь, что это поможет...

Ответ 8

Этот метод работает для меня, чтобы разобрать частичное число, используя:

//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 цифр числа, надеюсь, что это поможет!!!