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 - находит числа в текстовом вводе.
Ответ 4
Попробуйте следующее: библиотека Google для работы с номерами телефонов
Ответ 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 цифр числа, надеюсь, что это поможет!!!