I am developing an app and I need to compare the phone numbers of the device contact list to a phone number list in a database, but the phone numbers can be written in different forms like it’s described in Wikipedia:
Number structure for networks
Country Code - cc = 1 to 3 digits
Identification Code = x = 1 to 4 digits
Subscriber Number = maximum = 15 − (cc + x) = 8 to 11 digits
International public telecommunication number for networks (maximum 15 digits)
So in Brazil the phone number can be written like:
Subscriber Number 99999-9999
Identification Code + Subscriber Number 67 99999-9999
Country Code + Identification Code + Subscriber Number 55 67
99999-9999 or
+55 67 99999-9999
And in other countries the phone number can be written in different forms and can have different number patterns.
How can I compare the numbers from the device to the ones in the database like Telegram and Whatsapp do? Do I have to create a code to handle each country individually?
I am using libphonenumber for Android and libPhoneNumber-iOS for Swift and they work really well.
For getting the area code of the number a use getLengthOfGeographicalAreaCode like this:
String nationalSignificantNumber = phoneUtil.getNationalSignificantNumber(number);
int nationalDestinationCodeLength = phoneUtil.getLengthOfNationalDestinationCode(number);
if (nationalDestinationCodeLength > 0) {
nationalDestinationCode = nationalSignificantNumber.substring(0, nationalDestinationCodeLength);
}
For comparing two number I use isNumberMatch method. It works fine.
Related
I was working on a project where we needed to generate a unique number for the Firebase Realtime Database. Now I want to generate a random 8- to 12-digit number that will be unique. Can anyone provide a suitable method/algorithm for obtaining the number, or can it be combined with string?
If you truly need a random number with NN digits you should use Kotlin's Random:
val random = abs((0..999999999999).random())
Of course, in this, 0 is a valid number in this sequence. So what do you do in in the 111 billion chances you get 0? well, that's up to you. You could change the range (but less numbers = less randomness)
You could "pad" 0s to your number so 123 becomes 000000000123 (as a String, that is). Ultimately what you do with the random number is up 2 you.
Keep in mind Random also takes a Seed.
So you could become more fancy by using the time at UTC as the seed (which is constantly changing every instant):
val random = abs(Random(LocalDateTime.now().toEpochSecond(ZoneOffset.UTC)).nextLong())
This will likely give you HUGE numbers so you should convert to string and take the last NN digits
If you get for eg.:
2272054910131780911
You can take: 910131780911
I have created a simple playground where you can see this in action. Please understand I made this in 10 minutes, so there may be optimizations all over the place, I don't have the Kotlin standard library in my head and the Playground's autocomplete is not the same as Android Studio.
Possibly look into SecureRandom -- Cryptographically strong random number generator (RNG): https://docs.oracle.com/javase/8/docs/api/java/security/SecureRandom.html
Also, see this post regarding how long of a random number to generate by using SecureRandom: How to generate a SecureRandom string of length n in Java?
You can use Current Milli Second as Unique Number as follows
/**
* #param digit is to define how many Unique digit you wnat
* Such as 8, 10, 12 etc
* But digit must be Min 8 Max 12
*/
fun getUID(digit:Int):Long{
var currentMilliSeconds:String = ""+Calendar.getInstance().timeInMillis
var genDigit:Int = digit
if(genDigit<8)
genDigit = 8
if(genDigit>12)
genDigit = 12
var cut = currentMilliSeconds.length - genDigit
currentMilliSeconds = currentMilliSeconds.substring(cut);
return currentMilliSeconds.toLong()
}
Call it like
var UID = getUID(12)//parameter value can be 8-12
I am building an android app for blocking calls. Now when i am asking the user for contact that he/she wants to block then that number may or may not contain that country's code, while when i will receive a call from that person it will surely have the country code. For example,
in India one can store its number in three different ways:
1) 90331xxxxx
2) 090331xxxxx
3) +9190331xxxxx
Now if user added a contact number which was stored in first way then how could i compare it with the incoming number because the incoming number will be surely having country code.
Also the length of all mobiles number across the world is different. So, how should i compare this numbers.
You should use https://code.google.com/p/libphonenumber/. This has lot of features that you need.
https://code.google.com/p/libphonenumber/#Quick_Examples states how you can use this library to parse numbers and get country specific number, so basically you need to just get the local number using this library and then use that for your comparison.
String swissNumberStr = "044 668 18 00"
PhoneNumberUtil phoneUtil = PhoneNumberUtil.getInstance();
try {
PhoneNumber swissNumberProto = phoneUtil.parse(swissNumberStr, "CH");
} catch (NumberParseException e) {
System.err.println("NumberParseException was thrown: " + e.toString());
}
boolean isValid = phoneUtil.isValidNumber(swissNumberProto); // returns true
// Produces "+41 44 668 18 00"
System.out.println(phoneUtil.format(swissNumberProto, PhoneNumberFormat.INTERNATIONAL));
// Produces "044 668 18 00"
System.out.println(phoneUtil.format(swissNumberProto, PhoneNumberFormat.NATIONAL));
// Produces "+41446681800"
System.out.println(phoneUtil.format(swissNumberProto, PhoneNumberFormat.E164));
I have an Android application which uses an .so file, The .so changes his behavior according the network the phone connected to, i.e. if you are connected to AT&T you need to do XYZ. if you work on Verizon you do ABC otherwise you do XY.
Is there any good way to differentiate between mobile networks?
I thought to use PLMN somehow, Is there any robust way of doing
that? (I want it to work while roaming too etc.).
I had seen this, but I need to do it only in the C code with no wrappers or Java engagement, meaning the following can't be used:
TelephonyManager telephonyManager =((TelephonyManager) Context.getSystemService(Context.TELEPHONY_SERVICE));
String operatorName = telephonyManager.getNetworkOperatorName();
You can get the currently used PLMN with the AT+COPS? command. From 27.007:
+COPS? +COPS: <mode>[,<format>,<oper>[,<AcT>]]
...
Read command returns the current mode, the currently selected operator and the
current Access Technology. If no operator is selected, <format>, <oper> and <AcT>
are omitted.
....
<oper>: string type; <format> indicates if the format is alphanumeric or numeric;
long alphanumeric format can be upto 16 characters long and short format up to 8
characters (refer GSM MoU SE.13 [9]); numeric format is the GSM Location Area
Identification number (refer 3GPP TS 24.008 [8] subclause 10.5.1.3) which
consists of a three BCD digit country code coded as in ITU-T E.212 Annex A
[10], plus a two BCD digit network code, which is administration specific;
returned <oper> shall not be in BCD format, but in IRA characters converted from
BCD; hence the number has structure: (country code digit 3)(country code digit 2)
(country code digit 1) (network code digit 3)(network code digit 2)(network code
digit 1)
Using the following two at commands (see also)
AT+COPN 7.21 - Read operator names
AT+COPS 7.3 - PLMN selection
My requirement is to find out the message recipient number is an International number or National number.
Is there any android API or any third party library available to implement the same.
I want to use libphonenumber google API[android/externals/libphonenumber] but don't know how to check International and Non-international number.
I don't think telephonyManager.getSimCountryIso() would help you determine 'to which country the call is being made' as it will return your country's ISO.
Moreover, length of ISD codes vary across countries. For some countries it is 1, for some it's 2, for some it's 3 and for others it's 4. So you will need to extract/make 4 different keys of these lengths from the outgoing number as I have shown below:
Say the out going number is +91-XXX-XXX-XXXX. then you'll create 4 keys as:
9 (1 digit key)
91 (2 digit key)
91X (3 digit key)
91XX (4 digit key)
Now check if any of these 4 keys is present in this list: ISO List .
[EDIT: Alternative Solution]
Again, if you only need to determine if the call being made is international or not then you can simply check for below condition:
if(outgoing-number `startswith` "00" || outgoing-number does not `startswith` your "country's- ISD-code") {
//it's an international call;
} else {
//it's a domestic call;
}
Rather use the google library which is used internally in Android as well.
http://code.google.com/p/libphonenumber/
I'd like to check if a call being made is international or not. I have the SIM number which I obtain by using TelephonyManager.getLine1Number() and also the Country code ISO of the SIM Card which I obtain using TelephonyManager.getSimCountryIso().
Is there anyway I can find the country code of the number to which the call is being made?
I don't think telephonyManager.getSimCountryIso() would help you determine 'to which country the call is being made' as it will return your country's ISO.
Moreover, length of ISD codes vary across countries. For some countries it is 1, for some it's 2, for some it's 3 and for others it's 4. So you will need to extract/make 4 different keys of these lengths from the outgoing number as I have shown below:
Say the out going number is +91-XXX-XXX-XXXX.
then you'll create 4 keys as:
9 (1 digit key)
91 (2 digit key)
91X (3 digit key)
91XX (4 digit key)
Now check if any of these 4 keys is present in this list: ISO List.
[EDIT: Alternative Solution]
Again, if you only need to determine if the call being made is international or not then you can simply check for below condition:
if(outgoing-number `startswith` "00" || outgoing-number does not `startswith` your "country's-ISD-code") {
//it's an international call;
} else {
//it's a domestic call;
}