I want my application to work in specific region e.g US.
We can limit distribution of application from play market but i found there are some hacks to install those apps.
I have to somehow limit the use within application.
For that I can retrieve user's GPS location and use Google's Geocode API for first run. But what if user travels to some other region?
I will have to use Location change listener to cater this scenario, but this will drain battery.
If I go for device's timezone, User can change it.
Is there any other thing i can possibly do to restrict application to specific region?
You can also check for the network the user is registered on with TelephonyManager
You have 2 methods that can be helpful.
GetNetworkCountryIso
http://developer.android.com/reference/android/telephony/TelephonyManager.html#getNetworkCountryIso()
and
GetSimCountryIso
http://developer.android.com/reference/android/telephony/TelephonyManager.html#getSimCountryIso()
Explanation
getNetworkCountryIso() will give you the iso for the country which the user is currenty registered for.
ie: If you're from Albania (al) and went to travel to USA (us) this will return "us"
getSimCountryIso() will give you the iso for the country where the SIM provider's country code.. ie: If you're from Albania (al) and went to travel to USA (us) this will return "al"
UPDATE
You can integrate (if server side available) http://www.whois.net/ip-address-lookup/ to look for the device IP address. You can get the IP like this.
How to get IP address of the device from code?
With a combination of all this functions (Wifi, network provider, IP, GPS, Google Play regions) you can reduce a lot the use limitations of your app. In the other hand if the user it´s advance enough to fake the IP using a proxy, doesn't turn on the Wifi / GPS and doesn't have SIM card, there´s not much more to do.
Hope it helps :)
As a continuation to my comment, you could go by those lines of filtering users by country code.
The problem - only some carriers store the phone number on the actual SIM card. If so, you will be able to obtain it using
TelephonyManager tMgr = (TelephonyManager)mAppContext.getSystemService(Context.TELEPHONY_SERVICE);
String mPhoneNumber = tMgr.getLine1Number();
To avoid the instances of those carriers who don't store the actual number on the SIM - there is no way to retrieve the number seeing it is not stored on the phone.
So, what I would do, is simply on the first run of application, request the user to input his full phone number (including country code) - and store that in SharedPrefs. Then, you will know if to run the app or not.
Good luck, hope this has helped!
Related
I have an app that tries to determine the quality of the mobile network in various locations, and then associate it with which network is in use on the phone.
To get the mobile carrier, I am using
TelephonyManager manager = (TelephonyManager)mContext.getSystemService(
Context.TELEPHONY_SERVICE);
String carrierName = manager.getNetworkOperatorName();
This generally works, but in some cases, I get the result, "Fi Network". Since Google Fi switches between T-Mobile, Sprint and US Celluar in the United States, I'd like to know which of the actual carriers is used, so I can use it to determine the quality of the network.
Is there any API that can tell me which of these carriers the phone is actually using?
TelephonyManager.getSimOperator() will return MCC & MNC codes which should uniquely identify a carrier, you can easily find lists online that maps MCC+MNC to operators names.
I need to determine the country (iso3) the device is in even if the user's device has GPS turned off and does not allow apps to access it's location.
I also need to account for tablets that have no sim card and thus cannot use telephonyManager.
For this reason I don't believe I can use the location manager (also because of these reasons: LocationManager requestLocationUpdates doesn't work)
The approach I am thinking I will need is to make a simple HTTP request to a third party ip location api:
e.g.
http://www.ipinfodb.com/ip_location_api.php
or
https://freegeoip.net
Is this the best way to do it? What is the best open api to use?
Your approach of third party ip location api seems right to currently. May be This would help you
http://ip-api.com/docs/api:json
http://ip-api.com/json
You can use the TelephonyManager
TelephonyManager tm = (TelephonyManager)this.getSystemService(this.TELEPHONY_SERVICE);
String countryCode = tm.getNetworkCountryIso();
Update:
Since you cannot use telephony I would suggest trying this, as it get's the users input from when they setup the device.
String locale = context.getResources().getConfiguration().locale.getCountry();
Could I get MCC & MNC of the other party, either on an incoming or an outgoing call?
I am aware that you can get your own information from the SIM card but I am interested for the information of my contacts.
I guess I must be able to retrieve such information during a phone call.
So two main questions:
Is it allowed from the protocol?
Are there any classes inside Android API that provide such information? (looked up inside TelephonyManager but did not find any)
Like payeli has answered: No, you cannot.
Firstly, because there is no API for accessing the other party's cellular information. Secondly, because Android doesn't actually know. You can delve into the source code of the TelephonyManager, and you'll see that it only contains information about the local telephony provider.
Furthermore, the internal Android class Connection also shows no hint of any such information. (Regardless of the information it contains, it isn't accessible from the API, not even via reflection.)
That being said, there are currently services that provide some insight into phone numbers. Here in the Netherlands, KPN provides an API for looking up caller information, including the current coverage state of the phone, whether it's roaming or not, and other details. I'm not sure if the API is public yet or not, but perhaps there's a similar service available in your region.
No, you can only retrieve the MCC and MNC of your phone, not for third party numbers to which you make or recieve calls.
Reason: Calls target a phone number, not the MCC/MNC of the sending/receiving devices. The MCC / MNC tuple is used to uniquely identify a mobile phone operator/carrier, so if user is using carrierX at present, he will have one value of MCC/MNC, and if user changes mobile carrier/operator but retains same phone number, the the value of MCC/MNC will change but phone-number will still be constant.
So the mapping between phone number of a contact and MCC/MNC of their carrier are not fixed. So:
Could I get MCC & MNC of the other party, either on an incoming or an outgoing call? NO
I need a way to determine which cellular network band my phone is currently on, and which tower it is connected to.
How would I go about doing this? I know there is a "Service Mode" you can enter with the command *#0011# --> however this does not work on my phone.
If there is a way to create an application where I can get this information, that would be ideal. I believe I would need to access the internal telephony classes of the android OS - which can be accessed via reflection.
Thanks
Take a look at these:
http://developer.android.com/reference/android/telephony/gsm/GsmCellLocation.html
http://developer.android.com/reference/android/telephony/TelephonyManager.html
You can get the CellID with appropriate methods within these classes. The CellID is a unique number for each cell (or each sector) so that identifies the tower. But relating that number with a specific tower (that is, its location) is harder, as that usually is not public information.
I'm not sure if you can get the frequency band, but if the "cell info" methods mentioned in the above links include channel numbers (ARFCN), you can deduce the band from those numbers.
im building an application that requires the country the user is in. I have no problem getting the country if the user is using a smart phone with
telephonyManager.getNetworkCountryIso()
but how can I achieve this if they are not using a sim, i.e. a nexus 7???
Any help would be greatly appreciated
Thanks
Try this in order to check whether the user is on a tablet or on a phone:
TelephonyManager telephonyManager1 = (TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE);
if(telephonyManager1.getPhoneType() == TelephonyManager.PHONE_TYPE_NONE) {
// TABLET
}
else {
// YOUR PREVIOUS CODE
}
Maybe you can try with the Locale, if the user is in a tablet? I know this doesn't give you the location, but maybe you can try to find out according to the Locale the user has:
String locale = context.getResources().getConfiguration().locale.getCountry();
Hope it helps!
Personally, I would extend the logic to something like this:
Use TelephonyManager
If no modem/SIM is present, use WiFi
If no modem/SIM is present, and WiFi is disabled, use GPS
If no modem/SIM is present and both WiFi and GPS are disabled, use Locale
This way you would cover as much scenarios as possible.
NB Locale will not provide you with your current country, but is dependent on what language is selected in your Android device. I.e., if your phone is in Russian, you will always get Russia.
You could obtain the users location (rough approximation should suffice) and then lookup the approximate address with a Geocoder to determine the country.
In fact, your question is similar to this one.
But in Android, you now get the Geocoder built-in, so no need to specially call a webservice and decode json. See the Location Guide on how to get the users location and the Geocoder API for how to retrieve the location.