Как получить корректный телефонный номер?

Ответить
grem17
Сообщения: 85
Зарегистрирован: 16 сен 2014, 11:54

Как получить корректный телефонный номер?

Сообщение grem17 » 26 янв 2015, 12:53

добрый день, вопрос довольно таки не простой (для меня по крайней мере), буду рад любой помощи

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

Для звонка, номер телефона внутри нашей страны (код страны 7), можно набрать как
"8922..." - при звонке внутри страны
"8904..."
"+7922..." - международный код
"+7904..."
- все варианты будут работать правильно

возьмем другую страну, например Украина (код страны 380)
"+38092..." - международный код
"092..." - при звонке внутри страны

как корректно обрабатывать номера всех стан внутри программы и делать по ним выборку через Cursor? ведь я могу записать свой номер как 8922..., а могу как +7922..., украинец может записать как "+38092...", так и "092..."

знаю что есть такие методы как
- PhoneNumberUtils.stripSeparators(contactNumber) преобразует номер вида 8-922-...к виду 8922
- так же могу получить разнообразные данные о телефоне (только метод telephonyManager.getLine1Number(); не срабатывает почему то)

Код: Выделить всё

				String srvcName = Context.TELEPHONY_SERVICE;
				TelephonyManager telephonyManager = (TelephonyManager)
				getSystemService(srvcName);
				int simState = telephonyManager.getSimState();
				switch (simState) {
				    case (TelephonyManager.SIM_STATE_ABSENT): break;
				    case (TelephonyManager.SIM_STATE_NETWORK_LOCKED): break;
				    case (TelephonyManager.SIM_STATE_PIN_REQUIRED): break;
				    case (TelephonyManager.SIM_STATE_PUK_REQUIRED): break;
				    case (TelephonyManager.SIM_STATE_UNKNOWN): break;
				    case (TelephonyManager.SIM_STATE_READY): {
				        // Извлеките из SIM-карты код страны в формате ISO
				        String simCountry = telephonyManager.getSimCountryIso();
				        // Получите код оператора активной SIM-карты (MCC + MNC)
				        String simOperatorCode = telephonyManager.getSimOperator();
				        // Извлеките из SIM-карты название оператора
				        String simOperatorName = telephonyManager.getSimOperatorName();
				        // -- Требуется наличие полномочия READ_PHONE_STATE --
				        // Получите серийный номер SIM-карты
				        String simSerial = telephonyManager.getSimSerialNumber();
				        String CountryIso = telephonyManager.getNetworkCountryIso(); 
				        String number = telephonyManager.getLine1Number();
				        break;
				    }
				    default: break;
- есть полный список стран и их кодов, пример:
<item>351,PT</item>
<item>1,PR</item>
<item>974,QA</item>
<item>40,RO</item>
<item>7,RU</item>

вот такая проблема, буду рад любой помощи или идеям по реализации

Аватара пользователя
doter.ua
Сообщения: 1106
Зарегистрирован: 23 ноя 2013, 16:08
Откуда: Ukraine

Re: Как получить корректный телефонный номер?

Сообщение doter.ua » 26 янв 2015, 16:27

Недавно тоже сталкивался с такой штукой.
Так я находил конкретное начало номера:

Код: Выделить всё

     public static final String  PATTERN_CODE_CITY            =  "^\\+?996.*"; 
     String number = "+9960701123456";  
     number .matches( PATTERN_CODE_CITY )
Где используется regex, \\+? знак вопроса означает, что символ необязательный. \\+ собственно сам символ, просто "+" зарезервированный и его нужно экранировать слешом, но слеш зарезервирован самим regex потому его экранируют еще одним слешем :) Кароч подробнее гугли "java regex" и его метасимволы.

Все номера начинаются с нуля "0". До нуля может быть плюс, код страны и т.д обычно 3-4 символа.
То есть нужно проверять код оператора уже после нуля. для этого ищем первое вхождение:

Код: Выделить всё

private static int findPositionOfZero(String num) {
        if ( num.contains("0") ) {
            return num.indexOf('0');
        }
        else{
            return -1;
        }
    }
Получаем инт - позиция нуля либо -1. Можно проверить длину номера минус позицию нуля. По идее должны быть не менее 8-9 символов: 0 nnn xxx xxx, если их совсем мало, то номер скорее всего кривой. Обычно nnn - код оператора. например 0 66n xxx xxx это МТС в Украине.

Так вот есть у нас позиция НУЛЯ, теперь можно проверять операторов:
Сначала обрезаем номер до нуля включительно: num.substring( pos + 1 ) где pos - позиция нуля из функции выше. было +38066хххххх стало 66ххххххх.

Код: Выделить всё

String CODE_MTS1 = "66"
String CODE_MTS1 = "77"
String CODE_MTS1 = "88"

switch ( str.substring(0,2) ){
    case CODE_MTS1:
         //todo
         break;
    case CODE_MTS2:
         //todo
         break;
    case CODE_MTS3:
         //todo
         break;
}
У нас обычно важны только первые 2 цифры 66n xxx xxx. Если нужно больше, то меняй шаблоны на "nnn" и откусывай substring(0, шаблон.length() )

P.S. telephonyManager.getLine1Number() по-моему, он работает когда номер записан на симку.
P.S. Для поиска конкретного номера можно проверять шаблоном:
public static final String PATTERN_CODE = ".*123456$"; знак доллара - конец строки. т.е. должно заканчиваться на 123456.
Семь раз отмерь - поставь студию.
Эклипс не студия, ошибка вылетит - не исправишь.
Скажи мне кто твой друг, и оба поставили студию.
Студия - свет, а эклипс - тьма.

grem17
Сообщения: 85
Зарегистрирован: 16 сен 2014, 11:54

Re: Как получить корректный телефонный номер?

Сообщение grem17 » 26 янв 2015, 18:25

doter.ua
спасибо! даже не рассчитывал что получу ответ!
завтра проверю

grem17
Сообщения: 85
Зарегистрирован: 16 сен 2014, 11:54

Re: Как получить корректный телефонный номер?

Сообщение grem17 » 27 янв 2015, 07:39

doter.ua писал(а): Все номера начинаются с нуля "0". До нуля может быть плюс, код страны и т.д обычно 3-4 символа.
вот тут не понятно, у меня например номер +79221599ххх, здесь нет нуля, как быть?

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

з.з.ы. а как вообще работает стандартная схема андроида, по распознаванию смс? ведь я могу отправить как на номер 8922...так и на номер +7922..., когда делаешь выборку в курсор то подставляешь в условие полный номер +7922...и номера начинающиеся с 8922...не попадут в выборку

Аватара пользователя
doter.ua
Сообщения: 1106
Зарегистрирован: 23 ноя 2013, 16:08
Откуда: Ukraine

Re: Как получить корректный телефонный номер?

Сообщение doter.ua » 27 янв 2015, 11:43

grem17 писал(а):
doter.ua писал(а): Все номера начинаются с нуля "0". До нуля может быть плюс, код страны и т.д обычно 3-4 символа.
вот тут не понятно, у меня например номер +79221599ххх, здесь нет нуля, как быть?

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

з.з.ы. а как вообще работает стандартная схема андроида, по распознаванию смс? ведь я могу отправить как на номер 8922...так и на номер +7922..., когда делаешь выборку в курсор то подставляешь в условие полный номер +7922...и номера начинающиеся с 8922...не попадут в выборку
Проверяй по последним 6-9 цифрам
Семь раз отмерь - поставь студию.
Эклипс не студия, ошибка вылетит - не исправишь.
Скажи мне кто твой друг, и оба поставили студию.
Студия - свет, а эклипс - тьма.

grem17
Сообщения: 85
Зарегистрирован: 16 сен 2014, 11:54

Re: Как получить корректный телефонный номер?

Сообщение grem17 » 27 янв 2015, 11:48

ха! "а ларчик просто открывался"
оказывается при поступлении смс, андроид сам идентифицирует номер и сопоставляет с уже сохраненным и присваивает контакту ID, по которому можно делать выборку

само смс сообщение имеет поле thread_id - это и есть тот уникальный ID контакта по которому делается выборка и не имеет значения как начинается номер, с +7922... или 8922...
теперь можно легко вывести историю смс текущего контакта

вот рабочий код, как допилить под себя - разберетесь

Код: Выделить всё

				Uri uriSMSURI = Uri.parse("content://sms/sent");
				//String [] projection = {"address","date","type","_id","thread_id"}; //возвращает лишь перечисленные столбцы
				String [] projection = null; //возвращает лишь перечисленные столбцы
				String selection = "thread_id = "+"1"; //фильтр по строке
				//getContentResolver().query(uriSMSURI, projection, selection, null, sort);
				//inbox type=1
				//sent type=2
				Cursor cur = getContentResolver().query(uriSMSURI, projection, selection, null, "date");
				
				if (cur.moveToFirst()) {
					do{
						String id = cur.getString(cur.getColumnIndex("_id"));
						String thread_id = cur.getString(cur.getColumnIndex("thread_id"));
						String address = cur.getString(cur.getColumnIndex("address"));
						String person = cur.getString(cur.getColumnIndex("person"));
						String date = cur.getString(cur.getColumnIndex("date"));
						String protocol = cur.getString(cur.getColumnIndex("protocol"));						
						String read = cur.getString(cur.getColumnIndex("read"));
						String status = cur.getString(cur.getColumnIndex("status"));
						String type = cur.getString(cur.getColumnIndex("type"));
						String reply_path_present = cur.getString(cur.getColumnIndex("reply_path_present"));
						String subject = cur.getString(cur.getColumnIndex("subject"));
						String body = cur.getString(cur.getColumnIndex("body"));
						String service_center = cur.getString(cur.getColumnIndex("service_center"));
						String locked = cur.getString(cur.getColumnIndex("locked"));
						Log.d("1", "---------------------------"+"_id="+id+" thread_id="+thread_id+" address="+address+" person="+person+" date="+date+" protocol="+protocol+" read="+read+" status="+status+" type="+type+" reply_path_present="+reply_path_present+" subject="+subject+" body="+body+" service_center="+service_center+" locked="+locked);
						
					}while (cur.moveToNext());
				}

Ответить