Differentiate between international roaming and roaming with the country. - android

Do we have any flag or value on the phone which can help decide this ?

I think it's not possible, you can just differenciate whether you're using roaming or not, but at least officially I can't find any info about this.
getRoaming() from ServiceState class.
isRoaming() from NetworkInfo class.
Roaming detection in StackOverflow.
---- EDIT ----
As probably there's not a built-int method for this, you could simply define and keep an internal list of national telephony companies and see whether the SIM's operator match one of them, in which case you'll be having a national roaming, an international roaming if the current operator is not the same as the SIM's and it's not in your list, or no-roaming if the current operator matches the SIM's operator. The negative thing is that you'd need to keep track of all national operators and add it to the list if there's some new, but that's something that doesn't happen too often (or at least here).
So basically it would be something like this:
TelephonyManager telephMan = ((TelephonyManager) Context.getSystemService(Context.TELEPHONY_SERVICE));
// This will be the current registered operator
String currentOperatorName = telephMan.getNetworkOperatorName();
// This will return the SIM operator
String simOperatorName = telephonyManager.getSimOperatorName();
// Additionally you'll have to keep a list of national operators
ArrayList<String> myCountryOperators = new ArrayList<String();
myCountryOperators.add("...");
myCountryOperators.add("...");
...
if (currentOperatorName.equals(simOperatorName)) {
// No roaming
}
else if (myCountryOperators.contains(currentOperatorName)) {
// National roaming
}
else {
// International roaming
}

if it's a GSM phone, in my opinion is easier to compare the country code set in the SIM card with the country code of network carrier with TelephonyManager.getNetworkCountryIso() and TelephonyManager.getSimCountryIso()
If they match you're in same country, otherwise don't. And you don't need to keep a list of names...

Related

SubscriptionInfo.getMnc() drops leading zeros, cannot link MCC+MNC to SIM operator

I'm updating some code to use the Multi SIM support that was added to Android in 5.1. We examine the SIM operator (or the MCC+MNC combo) a lot in our app, so the code I'm writing involves migrating from reliance on TelephonyManager.getSimOperator() to getting SubscriptionInfos from the SubscriptionManager, each of which gives access to the MCC and MNC for a SIM.
//old way – can only access one SIM
TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
String simOperator = telephonyManager.getSimOperator();
//new way - gives access to all SIMs
SubscriptionManager subscriptionManager = (SubscriptionManager) context.getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE);
List<SubscriptionInfo> subInfoList = subscriptionManager.getActiveSubscriptionInfoList();
for(SubscriptionInfo info : subInfoList) {
int mcc = info.getMcc();
int mnc = info.getMnc();
//do some stuff...
}
I'm finding that because it's returning ints for MCC and MNC, you lose leading zeros that are in some of the MNCs. To see some examples, check out the table here. When you concat MCC+MNC you get the SIM operator, so it is important to keep the zeros that are often present. For example, NEXTEL in Mexico has a SIM operator value of "334090," but because the SubscriptionInfo returns ints for MCC and MNC, you get the values 334 and 90, respectively.
Given this issue, how can you reliably link a SubscriptionInfo's MCC+MNC pair to a particular SIM operator in a list of known SIM operators? Is this an oversight in the design of this API? Is there any other way to get the SIM operator for every SIM card that's in the multi-SIM phone?
MCC are always 3 digits, the rest is MNC, which as you correctly said, may have 2 or 3 digits.
If you parse the int to String, you can just get sub string of it and process the info as required.
Also it's a hidden method, but you can access it by reflection, to get the info you want in String format, this exists at least from Android 6 and Android 7
public String getSimOperator(int subId)
But I think SubscriptionManager way is safer since it's open API and for the moment you don't need to bother with Android versions handling it differently.
The best way to achieve this is to read IMSI from the SIM card. If you are reading the MNC+MNC directly and your user is on roaming or connected to another network then the values returned won't be reliable.
E.g. If your user is NEXTEL customer but is travelling or due to network connection issues connects to another network, lets say Telcel, then the value returned from MCC+MNC will be from Telcel.
In order to reliably match the operator of current SIM to predefined list, read IMSI value from SIM card using getSubscriptionId() from Telephony manager.
IMSI starts with MCC+MNC of the operator. You can easily check if MCC+MNC matches as follows
final String mccMncToCompare = "334090"; //You can also use Integer instead of string. You just have to perform type conversion
final TelephonyManager tm = (TelephonyManager) context
.getSystemService(Context.TELEPHONY_SERVICE);
final String imsi= tm.getSubscriberId();
final boolean mccMncMatched = imsi.startsWith(mccMncToCompare);

Checking if call being made is international

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

check mobile number valid or not through country code

I have contact like "+919672525253".Now i extract the country code like "91" from that number.Now if number is like "9672525253" and if i extract the country code then it will give me "967".So after extracting the country code how can i check that remaining number is valid mobile number for that country code or not?
EDIT
If any body know the mobile number length country wise then also i can solve this problem.like in india 10 digits.
You pretty much can't. For example in the US mobile numbers and landline numbers are indistinguishable, they have normal area codes just like landline numbers. Even if it were possible every country does it differently and it is also constantly changing as numbers run out new prefixes are added and things change and their is no pattern you could match against or database you could do a lookup against.
Take a look at libPhoneNumber (bundled in ICS) which can help validating a phone number (see PhoneNumberUtils).
There's a MobileType you can get after validation but as stated in the source and by Ben, in some region this will not work.
EDIT:
Some validation code (here we need to check the phone is a valid one assuming it's a french one):
boolean isValid = false;
PhoneNumber number = null;
try {
number = this.phoneUtil.parse(phone, "FR"); // phone is number in internationnal format "+xxxxxx"
isValid = this.phoneUtil.isValidNumber(number);
} catch (final NumberParseException e) {
// ...
}
isValid // is the phone number valid according to the library?
this.phoneUtil.getRegionCodeForNumber(number); // this gets the country code of the phone as found by the library (for example "US", "CH", "GB", ...)
This works for us but you'll need to try it to see if it suit your need.

knowing the network operator name

I want to get my network operator name in my app.
I am using fallowing methods in the TelephonyManager to get this:
TelephonyManager mTeleManager = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);
mTeleManager.getSimOperatorName();
mTeleManager.getNetworkOperatorName();
mTeleManager.getSimOperator()
But I am getting empty values from the "getSimOperatorName()" and "getNetworkOperatorName()"..
I am getting numeric code from this "getSimOperator()" method, But I want know the alphabetic form of the operator name . Some thing like "T-Mobile" for Tmobile networks.
Pl. suggest me how to do this.
thanks.
Have you tried it on different phones/with different sim cards?
According to TelephonyManager.getLine1Number() returns Null
Hi All,
Here comes an explanation for this. It is not actually an issue, both information depends on some fields on the SIM card that are optional. So it might be empty if the SIM has no such optional fields or if the operator has set it empty.
Regards,
He is talking about
TelephonyManager.getLine1Number()
TelephonyManager.getSimOperatorName()

How to find Base Station Identifying Code (BSIC)

Is it possible to find Base Station Identifying Code in android. To clarify, Let 'A' calls to 'B'. Before 'B' receive the phone call, his installed app will find
'A's BSIC and match it with a given database of BSIC( this BSIC database may be located on phone locally or
in a web or from phone network provider's database ) then will find 'A' location( Say +88017... is calling from "Dinajpur of Bangladesh" ).Is it possible ? if so how ? please help me...
Rereading the question, you want the other person's tower, not your own. No, i don't think that info is available to you. At most, you can guess by the country and region codes.
Not relevant anymore:
I believe you can achieve what you want getting the cell id in use or all the neighboring cells
TelephonyManager mTelephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
GsmCellLocation loc = (GsmCellLocation) mTelephonyManager.getCellLocation();
Log.d ("CID", Integet.toString(loc.getCid()));
Log.d ("LAC", Integet.toString(loc.getLac()));
// or
List<NeighboringCellInfo> list = mTelephonyManager.getNeighboringCellInfo ();
for (NeighboringCellInfo cell : list) {
Log.d ("CID", Integet.toString(cell.getCid()));
Log.d ("LAC", Integet.toString(cell.getLac()));
}
You can refer then to cell location through several open databases (e.g., http://www.location-api.com/ or http://opencellid.org/ )
If this is not enought, I suggest you to check this thread: http://groups.google.com/group/android-platform/browse_thread/thread/b55c8d3275ed7042/78d9c30c49e94a3a , specially this link: http://www.google.com/url?sa=D&q=http://www.3gpp.org/ftp/Specs/archive/27_series/27.007/27007-860.zip

Categories

Resources