I've just built an application that detecting incoming calls. I see that in some phones(or in different version of android) incoming call number has country code, some incoming numbers has not. Is there a way to get incoming calls with country codes in any android phone and in any version of android?
I use broadcast receiver and PhoneStateListener, I get the parameter of incomingNumber at onCallStateChanged. So I didn't use telephonymanager.EXTRA_PHONE_NUMBER (In fact I don't what exactly EXTRA_PHONE_NUMBER does)
Here is a code-snippet that you can use in your BroadcastReceiver to extract the country-code using libphonenumber library.
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_NEW_OUTGOING_CALL)) {
// get phone number from bundle
String phoneNumber = intent.getExtras().getString(Intent.EXTRA_PHONE_NUMBER);
// get country-code from the phoneNumber
PhoneNumberUtil phoneUtil = PhoneNumberUtil.getInstance();
try {
PhoneNumber numberProto = phoneUtil.parse(phoneNumber, Locale.getDefault().getCountry());
if (phoneUtil.isValidNumber(numberProto)) {
log.d("TAG", "Country Code: " + numberProto.getCountryCode());
} else {
log.d("TAG", "Invalid number format: " + phoneNumber);
}
} catch (NumberParseException e) {
Log.d(TAG, "Unable to parse phoneNumber " + e.toString());
}
}
}
You can get this done with libphonenumber library https://code.google.com/p/libphonenumber/
EXTRA_PHONE_NUMBER holds number entered by user
A String holding the phone number originally entered in
ACTION_NEW_OUTGOING_CALL, or the actual number to call in a
ACTION_CALL.
via http://developer.android.com/reference/android/content/Intent.html#EXTRA_PHONE_NUMBER
Also, have you seen: How to get phone number from an incoming call? ?
Related
I have a question about how to match phone numbers from user's contact list with phone numbers I have on remote database. Flow goes like this:
User registers on my app with his phone number (so does any other user)
App ask for contact permission
App sends contacts (phone numbers) to server to match against other registered numbers
The problem I have is that users register their phone number in format: +1XXXYYY.
For example person A registers with number +1222333. It might happen that person B has person A in his contact list as 0222333, how should I match that number? I can't know if prefix is "+1" or some other number.
I would like to recommend the libphonenumber library: https://github.com/google/libphonenumber
It can parse numbers and then output then to a standardized format. The official library has support for Java, C++ and JavaScript but there are also ports to other languages (see the bottom of the Github page)
Here is a quick example on how to format a national number as an international one in java
public static String getInternationalNumber(String localNumber, String regionCode) {
PhoneNumberUtil phoneUtil = PhoneNumberUtil.getInstance();
Phonenumber.PhoneNumber phoneNumber;
try {
phoneNumber = phoneUtil.parse(localNumber, regionCode);
}
catch (NumberParseException e) {
return null;
}
return (phoneUtil.format(phoneNumber, PhoneNumberUtil.PhoneNumberFormat.INTERNATIONAL));
}
You can probably assume that the numbers in the user's contact list have the same country code as the user.
To find which country code your user's phone number has you can do something like this (assuming it is an international number)
public static String getRegionCode(String phone) {
PhoneNumberUtil phoneUtil = PhoneNumberUtil.getInstance();
Phonenumber.PhoneNumber phoneNumber;
try {
phoneNumber = phoneUtil.parse(phone, "");
}
catch (NumberParseException e) {
return null;
}
return phoneUtil.getRegionCodeForNumber(phoneNumber);
}
I am trying to read a user's SMS messages and get the sender's phone number of those messages. When I try getting the sender's phone number of the message through the "address" column, it returns the phone number of the text's conversation (for example, if I send a message to a user with phone number X, the address column returns X instead of my phone number), not the phone number of the person that sent the message. Below is my Kotlin code:
var cursor = contentResolver.query(
Uri.parse("content://sms/"),
null,
null,
null,
null
)
// Retrieve the IDs of the sender's name
var senderID = cursor!!.getColumnIndex("address")
// Iterate through every message
while (cursor!!.moveToNext()) {
var messageSender = cursor.getString(senderID) // Get the sender of the message
System.out.println("---------------------------------------------------------")
System.out.println(messageSender) // Returns phone number of the conversation, not the sender
}
For example: user with phone number 123456789 sends a message to you. I want to retrieve phone number 123456789.
I found a solution. You must use the type column to identify whether the message has been sent or received.
When the message has been sent, you can read the phone number from the Telephony Manager.
fun getMessageSender(cursor: Cursor): String {
val partnerAddressId = cursor.getColumnIndex("address")
val typeId = cursor.getColumnIndex("type")
val partnerAddress = cursor.getString(partnerAddressId)
val type = cursor.getString(typeId)
return if (type.equals("1", true)) {
partnerAddress
} else {
getPhoneNumber()
}
}
private fun getPhoneNumber(): String {
val telephonyManager = getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager
return telephonyManager.line1Number
}
But please note that I do not know how this affects devices with Multi Sim. I could imagine that the wrong number will be returned here.
I have worked out this solution in combination with the following posts:
Getting phone number of each sms via content://sms/
Programmatically obtain the phone number of the Android phone
Is there any way to find the country code from my mobile number. Basically, I am working for a chat application I need to find the country code by using the mobile number. Is it possible?
For example:
My Country - India,
Country Code - +91,
My number - 9787248566
Now I have only my number . I don't know the country code. I don't know which country it is. Is it possible to achieve this in Android programmatically?
If you already have complete mobile number in a specific format e.g. +91-99xxxxxxxx and want to fetch country code = IN, then here is a reference to a solution.
Use a lib in your gradle.
//Phone Utils lib.
implementation 'com.googlecode.libphonenumber:libphonenumber:7.0'
And the code which will help to find the country code and other information is as below.
PhoneNumberUtil utils = PhoneNumberUtil.getInstance();
try {
for (String region : utils.getSupportedRegions()) {
// Check whether it's a valid number.
boolean isValid = utils.isPossibleNumber(mobileNo, region);
if (isValid) {
Phonenumber.PhoneNumber number = util.parse(mobileNo, region);
// Check whether it's a valid number for the given region.
isValid = utils.isValidNumberForRegion(number, region);
if (isValid) {
Log.d("Region:" , region); // IN
Log.d("Phone Code", number.getCountryCode()); // 91
Log.d("Phone No.", number.getNationalNumber()); // 99xxxxxxxxxx
}
}
}
} catch (NumberParseException e) {
e.printStackTrace();
}
Use TelephonyManager.getSimCountryIso().
If you want to map that to the number, see how to get country phone prefix from iso
In Android We can save mobile number/landline number/etc..how To check that the number is mobile number?
while (phones.moveToNext())
{
int phoneType = phones.getInt(phones.getColumnIndex(Phone.TYPE));
if (phoneType == Phone.TYPE_MOBILE)
{
phoneNumber = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DATA));
break;
}
}
with this code it fetches the mobile number of TYPE_MOBILE ..but what if the user put land line number in TYPE_MOBILE?
This is best way given inbuilt.
private boolean isValidMobile(String phone)
{
return android.util.Patterns.PHONE.matcher(phone).matches();
}
In android you will not get mobile number, if user save our own number in contact as owner then you will get. If you want user mobile number then you can use OTP verification related libraries and then you will got number
I am able to get the carrier name using the following snippet :
TelephonyManager telephonyManager = ((TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE));
String operatorName = telephonyManager.getNetworkOperatorName();
It works really fine.
I am also able to get the incoming call number using the following snippet:
private final PhoneStateListener phoneStateListener = new PhoneStateListener() {
#Override
public void onCallStateChanged(int state, String incomingNumber) {
String callState = "UNKNOWN";
switch (state) {
case TelephonyManager.CALL_STATE_RINGING:
}
}
}
I want to find out the carrier name / service provider name of an incoming number.
How can I achieve that?
Is that possible to get the incoming number's location, say, for example the country?
It's not possible to get the carrier name of a whatever mobile number neither with the Android API. At least is not that easy (and you could fall into some privacy related issue i think).
Read this article for more information:
http://sms411.net/2006/07/finding-out-someones-carrier/
Of course you can try to find the original carrier (using the prefix), but that could be different from the actual one...
It is not possible to retrieve the details of the carrier of a calling party programatically. Also, because of number portability, it is not possible to retrieve the carrier's name from the caller's phone number. You can, however, get the country information from the first few digits of the number. Refer List of country calling codes for more information.
from API Level 22 (Andrid 5.1) This APIs are available.
SubscriptionManager subscriptionManager = (SubscriptionManager)getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE);
List<SubscriptionInfo> subscriptionInfoList = subscriptionManager.getActiveSubscriptionInfoList();
if (subscriptionInfoList != null && subscriptionInfoList.size() > 0) {
for (SubscriptionInfo info : subscriptionInfoList) {
String carrierName = info.getCarrierName().toString();
String mobileNo = info.getNumber();
String countyIso = info.getCountryIso();
int dataRoaming = info.getDataRoaming();
}
}