Identify handset without user having to create account - android

I am developing an Android app (and soon iPhone app). I need a way to identify the handset from server side. I was thinking I could write a secret (a cryptographic string of some sort) in persistent storage on the device the first time the app is run, and use this to identify the handset next time it speaks to the back end server. Is this how to do it? Is there a better way?
Clarification: The question should have said, I want to identify the user of the app. I'm not interested in tracking the actual device.

As much I understood your question, you wish to identify from which device request is coming, not the build or firmware of the phone. In this case you could identify them from their IMEI number, with following code -
TelephonyManager telephonyManager = (TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE);
telephonyManager.getDeviceId();
Add the following permission into your Manifest file :
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>

Related

The phone return empty when I want to get the phone number

Some phones return null when I want to get the phone number. In other phones I get the phone number.
This happens when Settings -> About Phone -> Status -> My phone number is "Unkow". Not writed there the phone number.
Why is this happening?How can I get a phone number ?
The code:
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
And:
TelephonyManager tMgr = (TelephonyManager)getApplicationContext().getSystemService(Context.TELEPHONY_SERVICE);
String mPhoneNumber = tMgr.getLine1Number();
Your code is perfect to get phone number of Android device.It will return you number.But sometimes it gives you null because that devices Service provider has not given permission to do that.
Means It works like : Android devices Request SIM card/Service provider for card info with phone number. And In response, Some provider have returned phone number of user and some has refused to do so.
Can you clarify what specifically you're asking for? If you're saying that it happens when in your phone's settings, under About Phone->Status->My phone number, it says "Unknown", then unfortunately that's not a programming question and not a question for here. Is that the case?
You cannot get device phone number in any ways. It depends on the service provider, some may allow access and some may not since it is completely dependent on the network access privileges. But in rare case you would get the phone number once the user has configured their own mobile number with the SIM card provider. The other way to do this by fetching the number from Facebook that too the user should have registered their mobile number, whereas the earlier versions of whatsapp provides this feature, but it is not compatible with the newer ones.
Note: It works with few custom phones which provides the access.(i.e., phones synced with only particular network providers)

Restrict android application to specific region

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!

What kind of Android application will require android.permission.READ_PHONE_STATE permission?

I have seen some Android apps on my phone require this android.permission.READ_PHONE_STATE permission. I don't know if I could trust them. I know this permission will give the app access to many information. I'm particularly interested in what functionality in an Android app normally require the information like DeviceId , SimSerialNumber, SubscriberId?
Phone state provides access to a lot of information about the phone. Usual usages will be for reading the IMEI of your phone and your phone number. This can be useful to identify you in their systems.
It can also be needed if the application is made compatible for Android 1.5 or lower, because this permission didn't exist back then and is added automatically by the play store to those apps
See also: https://android.stackexchange.com/questions/605/why-do-so-many-applications-require-permission-to-read-the-phone-state-and-ident
Another possible reason is so they can mute audio events if you're in the middle of a call. This is why apps like Pandora, Spotify, etc need the permission - so they can mute themselves when you get a call.
Not long ago I discovered that for some devices you should add android.permission.READ_PHONE_STATE if your application sends SMS. Probably in some cases SmsManager tries to retrieve some information about phone state before sending sms.
For example getting exception for HUAWEI GRA-L09:
java.lang.SecurityException: Requires READ_PHONE_STATE: Neither user 10174 nor current process has android.permission.READ_PHONE_STATE.
at android.os.Parcel.readException(Parcel.java:1543)
at android.os.Parcel.readException(Parcel.java:1496)
at com.android.internal.telephony.ISms$Stub$Proxy.s! endMultipartTextForSubscriber(ISms.java:1224)
at android.telephony.SmsManager.sendMultipartTextMessage(SmsManager.java:404)

How to “lock down” the device, on removal of SIM card or SD card?

I am distributing android phones with vital business information to my agents. Incase user remove SIM card, SD card or try to modify the data stored on the device storage, system need to lock down and if possible send notification to the concern persons.
This would require changing the baseband software of the device. You CANNOT do this on a post-production phone.
Update
Potentionally you can do something with the DeviceAdmin Api
I think you could register a DeviceAdmin, and as soon as the phone boots up check the SIM and SDCARD. Then you could either continue to wipe data or set a new password for the device using resetPassword and call locknow. This way the phone is locked and the user will need password from you
Don't store critical information on the phone.
Failing that, don't store critical information in plain-text.
Use some kind of network-based authentication to control access at run-time.
At the end of the day, your data will never be 100% secure against a determined software hacker. Or a user with a camera. So work with trustworthy people.
You can simple do following things.
1) register receiver on SD card states, if it is unmounted take action accordingly, can do same with the sim , for SIM save the sim number which can be get from TelephonyManager class.
2) and if user switch off the phone and then pull sd card or sim, on reboot app can check if the sdcard is present or the Sim changed. in this case too you can take action accordingly,
but if user replaces the sdcard in switch off mode you can not do anything.
I think it's possible to:
Register BroadcastListener for the BOOT_COMPLETED broadcast
So after boot completing you will have BroadcastReceiver started - where you can check presense of SIM or SD card - which is easy like:
telephonyMgr =
(TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE);
String simSerial = telephonyMgr.getSimSerialNumber();
If check fails you can either BRICK device (which is cruel) or wipe data through DevicePolicyManager.wipeData

Android phone number

The following code does not give me the phone number of the device ,how can i get the phone number
TelephonyManager tm = (TelephonyManager)getSystemService(TELEPHONY_SERVICE);
String number = tm.getLine1Number();
Toast.makeText(getApplicationContext(),"Telephone number: "+ number,
Toast.LENGTH_SHORT).show();
ALso i have tried the following..but the number doest show up
Programmatically obtain the phone number of the Android phone
How to get the mobile number of current sim card in real device?
The only method available from Android API as all the comments suggest is getLine1Number(). However I have never been able to obtain it since your operator must provide you with a SIM that supports letting phone read internal phone number. That seems not very common, so I am afraid that you could be left without means of knowing it.
That's why some programs that use your phone number to identify you (i.e. Whatsapp) do ask user about his/her phone number, because there is no sure way to getting it programatically.
the code provided:
TelephonyManager tMgr =(TelephonyManager)mAppContext.getSystemService(Context.TELEPHONY_SERVICE);
mPhoneNumber = tMgr.getLine1Number();
should work fine, however, it will not if you forgot the permission "READ_PHONE_STATE".
Hope this works now :)
Try this:
private String getMyPhoneNumber(){
TelephonyManager mTelephonyMgr;
mTelephonyMgr = (TelephonyManager)
getSystemService(Context.TELEPHONY_SERVICE);
return mTelephonyMgr.getLine1Number();
}
Hope it help you
[In case if anyone still stumbles here looking for this still existing age-old problem]
AFAIK, TelephonyManager.getLine1Number() is not reliable due to various constraints from operators.
There are some java reflection based hacks but varies from device to device thus making those hacks sort of useless [at least in terms of supported models]
But there is a legitimate lawful logic to find the number, if you really need so. Query all the SMS by sms provider and get the "To" number.
Extra benefits of this trick: 1. you can get all the line numbers if there is multi sim in the device.
Cons: 1. you will need SMS_READ permission [sorry for that]
2. You will get all the sim numbers ever used in the device. this problem can be minimised with some constraint logic e.g. time frame (sms received or sent only today) etc. It would be interesting to hear from others about how to improve this case.

Categories

Resources