When app is default dialer I need a way of getting sim id (1 or 2) for incoming call (dual sim).
App is implementing InCallService.
It looks like you can run call.getDetails().getAccountHandle().getId(), which will return a string that is the identifier of that PhoneAccountHandle.
Note that PhoneAccountHandle is also returned from getSimCallManager
Here's the note from the PhoneAccountHandle doc's:
A string that uniquely distinguishes this particular
PhoneAccountHandle from all the others supported by the connection
service that created it.
A connection service must select identifiers that are stable for the
lifetime of their users' relationship with their service, across many
Android devices. For example, a good set of identifiers might be the
email addresses with which with users registered for their accounts
with a particular service. Depending on how a service chooses to
operate, a bad set of identifiers might be an increasing series of
integers (0, 1, 2, ...) that are generated locally on each phone and
could collide with values generated on other phones or after a data
wipe of a given phone. Important: A non-unique identifier could cause
non-deterministic call-log backup/restore behavior.
You can also run getPhoneAccount(phoneAccountHandlerFromAbove) to get the address() i.e. phone number of the account.
If you want to compare it to the order of things in the system, you can retrieve the list of all PhoneAccountHandle's with getCallCapablePhoneAccounts
Related
I want to exchange (or only read) the NFC tag ID from one Android device to another but I don't know if I should use peer-to-peer mode or emulate an NFC tag with HCE.
If I use HCE, is the emulated tag ID unique?
What is the better option or is there a simpler one?
Neither P2P nor HCE will provide you a unique ID, least not on any phone I'm aware of. With P2P it's required that the ID exchanged in ATR is random. With HCE the emulated tag ID is usually set to 08h plus a random number. There may be API call to set but I'm not aware of such. But it makes a lot of sense that a phone can not be uniquely identified by just anyone reading.
How can I read the NFC ID of another Android device?
I assume you are talking about the anti-collision identifier/UID here. On the reading Android device, you can use the reader-mode API to access devices in HCE mode:
nfcAdapter.enableReaderMode(this, new NfcAdapter.ReaderCallback() {
public void onTagDiscovered (Tag tag) {
byte[] uid = tag.getId();
// TODO: do something with the UID ...
}
}, NfcAdapter.FLAG_READER_NFC_A | NfcAdapter.FLAG_READER_SKIP_NDEF_CHECK, null);
Is the emulated tag ID unique?
See Stephen's answer. Typically, neither P2P mode nor HCE should provide a unique and stable ID. However, there are some exceptions to this and the point of time when a non-stable ID changes may vary (also see this answer). It could be that:
The device has a secure element and uses the static UID of that secure element.
The device generates a new random UID whenever it is turned on, but continues to use the same UID until it is powered off.
The device generates a new random UID on every activation by an external reader device. I.e. whenever an external HF field is applied to the NFC antenna of the Android device.
Also note that some NFC devices will use randomly generated UIDs that do not start with the random-prefix 0x08.
Can I force a device to use a fixed/stable UID?
Android does not provide an API to influence the UID/anti-collision identifier, so the short answer is no. However, if rooting or creating a custom ROM is an option, there are some possibilities to change the UID and other protocol parameters:
Editing Functionality of Host Card Emulation in Android
Host-based Card Emulation with Fixed Card ID
Should you use the UID to identify (or even authenticate) a device?
No, you should definitely not do this. While you sometimes do not have much choice when you try to integrate a HCE device into some legacy system, you should definitely think about a different design.
First of all, as Stephen already wrote, if an NFC device exposes a fixed/stable identifier, this could possibly introduce a privacy issue as anyone could read and track the ID.
Second, while many systems still use these IDs to authenticate(!) cards, UIDs are not necessarily unique (particularly there are less 4-byte UIDs than cards out there) and UIDs can easily be cloned. See this answer for further details.
I was wondering :
When we enter a shop, using the app shop, we receive for example a notification.
But what if the beacon is down, and it's replaced with another beacon, with a different UUID etc .. ? Are the UUID/Major/Minor value of a beacon not harcoded but in a database on the server ? How it's fetched ?
Thanks you
The UUID of an iBeacon is not related in any way to its MAC address. It is a value that is assigned to the beacon by the beacon owner. Some beacon vendors have a specific UUID or range of UUIDs while others allow any UUID to be used.
If a particular beacon failed then the replacement would likely be configured with the same UUID.
When the app detects a particular beacon it needs to refer to some database, either in the app or on a server, that gives "meaning" to the particular UUID/major/minor combination so it is possible that the database could be updated to reflect the new hardware but this is less likely than simply configuring the replacement hardware with the same values
It is a good practice to not hard code your beacon identifiers in your app. You can build your app so on launch, it contacts a web service to download a list of identifiers to search for. You can build your own or use an off the shelf service like my company's ProximityKit that does exactly this.
Of course, if you are relying on beacon detections to launch your app, your app won't get auto launched to download the new beacon identifiers if the beacon ids change in advance. The user will have to manually do the launch to get the new list.
There are a few ways around this:
Set the identifiers on replaced beacons so they are the same as the old ones.
If you know you cannot set the identifiers, broaden the beacon region filter for auto launch so it matches a wide variety of beacon identifiers. On iOS you can search for all beacons with a shared UUID. On Android, you can search for all beacons regardless of identifiers.
When you initialise Beacon Region then you need to identify at least UUID and it is either hardcoded with in the app or can be placed on the server and should be retrieved from server before calling initialising Beacon Region.
NOTE:You should have a copy of all beacons UUIDs,majors and minors for future purposes
But suppose your Beacon goes out of order then there's a backup plan.
Follow below said steps:
1.Install Estimote-iOS or android app
2.Place the new beacon near to your device and start ranging beacons in estimote app.
3.Then you need to login with your cloud account in your app and configure new beacon(i.e edit your beacon's UUID.)You can even edit major,minor etc
4.Save those settings and your new beacon is configured and ready to use.
Happy Coding :)
Objective:
I am looking for a way to find out a unique_id for android device.
Background:
I will use the Id in login request payload and as my app is license based service app the Id should not change under normal circumstances.
Existing Approaches:
In iOS there are some unique id solutions for iOS such as CFUUID or identifierForVendor coupled with Keychain,Advertising Identifier etc.. that can do this job upto the expectation.
But in Android all the options that I know seems to have hole in it.
IMEI:
TelephonyManager TelephonyMgr = (TelephonyManager)getSystemService(TELEPHONY_SERVICE);
String m_deviceId = TelephonyMgr.getDeviceId();
Drawbacks
It is sim card dependent so
If there is no sim card then we're doomed
If there is dual sim then we're dommed
Android_ID:
String m_androidId = Secure.getString(getContentResolver(), Secure.ANDROID_ID);
Drawbacks
If OS version is upgraded then it may change
If device is rooted it gets changed
No guarantee that the device_id is unique there are some reports some manufacturers are having duplicate device_id
The WLAN MAC Address
WifiManager m_wm = (WifiManager)getSystemService(Context.WIFI_SERVICE);
String m_wlanMacAdd = m_wm.getConnectionInfo().getMacAddress();
Drawbacks
If there is no wifi hardware then we're doomed
In some new devices If wifi is off then we're doomed.
Bluetooth Address:
BluetoothAdapter m_BluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
String m_bluetoothAdd = m_BluetoothAdapter.getAddress();
Drawbacks:
if there is no bluetooth hardware we're doomed.
In future in some new devices we mightn't able to read it if its off.
Possible solutions:
There are two approaches that I think to solve this problem
We generate a random id by hashing timestamp with unique ids that I have mentioned and store it so next time during login we’ll check if the the stored value of key is null if its so then we’ll generate and store it else we’ll use the value of the key.
If there is something equivalent to keychain of iOS then we’re good with this approach.
Find a global identifier something like advertisingIdentifier of iOS which is same for all the apps in the device.
Any help is appreciated !
I have chosen to use Android_ID since It's not dependent on any hardware.
Build.SERIAL also dependent on availability of telephony that is in wifi only devices this Build.SERIAL won't work.
I have explained how other approaches are dependent upon the hardware availability in the question itself.
There is no such ID available on Android. You can generate your own, for example a random UUID and connect it to the user's account. This is what Kindle, Audible and other applications do to identify devices in a non-privacy-intrusive way.
Consider Google Analytics Mobile if you want to "track your users", http://www.google.com/analytics/mobile/
If you want to get closer to tracking a device you can combine the IDs above together in a hash-function. Bluetooth + wifi + android serial, and if any of them are null, you put a 0 in the hash, e.g. if there is no wifi mac addr. As you point out, you aren't guaranteed the id won't change. Unless the user is running a custom ROM, I would expect this computed ID to stay constant, though.
I think, you could use device serial ID (hardware serial number, not android id). You could seen it in device settings. In your code, you could get it by Build.SERIAL.
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 know, that android.Build.SERIAL is generated at first device boot, but I can't locate where and when exactly. I'm building AOSP Jelly Bean, Android tablet, nosdcard.
2nd question: is this serial number really unique for all Android devices?
According to this thread, it clearly says that it's unique, but added since API 9 and may be not present on all devices.
If you're writing your app for a specific device's model, you could direclty check if it has an IMEI. Otherwise, as you said, I recommend you to write a custom ID generator module. You will be sure that your ID will be unique and available for all devices.
IMEI represents the serial number of the device. It's sure it's unique. Two different devices can't have the same serial number.
To get the serial number of the device you just have to call :
String serial = Build.SERIAL;
It exists another approach. You can get the id by calling Secure.ANDROID_ID.
A 64-bit number (as a hex string) that is randomly generated on the
device's first boot and should remain constant for the lifetime of the
device. (The value may change if a factory reset is performed on the
device.)
private final String ANDROID_ID = Secure.getString(getContext().getContentResolver(),
Secure.ANDROID_ID);
Take care because it says that the value MAY change if a factory reset is performed.