I'm trying to access the UUID of low energy bluetooth devices in Android, ultimately to post the string to a web API.
Here's my code that works fine at toasting the local name and mac address:
private final BroadcastReceiver ActionFoundReceiver = new BroadcastReceiver(){
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if(BluetoothDevice.ACTION_FOUND.equals(action)) {
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
String sMac = device.getAddress();
String sName = device.getName();
String sUUID = ""; //HELP!
Toast toast = Toast.makeText(getApplicationContext(), "Mac: " + sMac + " - Name: " + sName + " - UUID: " + sUUID, Toast.LENGTH_SHORT);
toast.show();
}
}
};
Can anyone help with this?
There can be multiple UUIDs - which represent the BLE Characteristics of that device.
http://developer.android.com/reference/android/bluetooth/BluetoothDevice.html#getUuids()
You can iterate over the array of UUIDs and grab the one you want.
If you're looking for a unique identifier for a single device then you want the MAC address which you can get via BluetoothDevice.getAddress()
Bluetooth UUIDs (Universally Unique Identifier) are assigned to Bluetooth services, characteristics, descriptors etc. to identify each and every Bluetooth attribute. It's not like a MAC address i.e. per device you have one ID. So when you do discovery for services of other connected Bluetooth devices using API such as BluetoothGattObj.discoverServices(), it discovers a set of services, characteristics, descriptors etc. supported on other Bluetooth devices.
Using the above code snippet submitted by you won't give you any Bluetooth UUIDs.
There is a sample Bluetooth Low Energy application available in the Android-SDK that when you download through Google's Android website and the relative path for the same may be ..\adt-bundle-windows-x86-xxxx\sdk\samples\android-xx\connectivity\BluetoothLeGatt. Please refer the same.
Related
I have implemented a broadcast receiver in Android to listen to all available Bluetooth signals. The receiver works, but only shows four devices. When I manually scan for devices in the android menu, I suddenly see eight different devices in my app.
How can I see all available devices without using manual scan?
code:
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
// When discovery finds a device
if (BluetoothDevice.ACTION_FOUND.equals(action)) {
// Get the BluetoothDevice object from the Intent
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
// Add the name and address to an array adapter to show in a ListView
int rssi = intent.getShortExtra(BluetoothDevice.EXTRA_RSSI,Short.MIN_VALUE);
Log.d("bluetoothSignal", "name: "+ device.getName() + " adress: "+ device.getAddress() + "strength: "+ rssi + " Data: " + intent.getData());
mArrayAdapter.add(device.getName() + "\n" + device.getAddress());
}
}
};
Be aware that in the 'android menu' scanning results can show the paired devices, as well as scanned devices. So this could account for the duplicates. This case however is not very likely because any good Bluetooth scanning results should prevent duplicate results but there may be special cases where duplicates could be allowed.
What I suspect is actually occurring is that the system settings is returning tradition Bluetooth Devices (using rfcomm) and Bluetooth LE devices. The problem is, most Bluetooth device menus don't show a identifier that indicates whether a device is tradition or Bluetooth LE device, just the device name. Furthermore, when using BluetoothAdapter.startDiscovery() it tends to prefer traditional Bluetooth Devices and only occasionally returns Bluetooth LE devices. For example in my experience, 85 percent of the time it does not discover Bluetooth LE devices in the time it takes to to complete a discovery process, 13 seconds. I recommend using a use both the traditional scanning mechanism and the Bluetooth LE scanning mechanism. To perform a Bluetooth LE scan get a reference to the BluetoothLeScanner get calling BluetoothAdapter.getBluetoothLeScanner(). Once you have a reference, call BluetoothLeScanner.startScan(ScanCallback callback). The ScanCallback will get fired with discovered Bluetooth LE devices that you can add to your ListView's adapter. Try this and see if you get similar results with the 'android menu'.
I try to build a project that can get Bluetooth rssi from specific devices. However, I'm stuck on that. Is there any way to filter and specify the scanning results and then continuously get information from the chosen Bluetooth devices?
Many thanks.
Yes
You can filter using device MAC address in android
//lets say i have a device i got by searching BT devices
BluetoothDevice device;
String mac = "00:11:22:AA:BB:CC"
if(mac.equals(device.getAddress)){
// my device found
}
public String getAddress ()
Added in API level 5
Returns the hardware address of this BluetoothDevice.
Bluetooth hardware address as string
for more see Android BluetoothDevice doc
I am trying to connect to remote device which needs the Bluetooth hardware address of that device to connect:
bdDevice = mBluetoothAdapter.getRemoteDevice(<bluetooth_hardware_address>);
How does one discover the bluetooth address of the remote device ?
These are the parameters of the remote device I already know - Serial Number, Equipment Number, VIN Number.
In iOS this is done using the properties of the remote device to get the Bluetooth hardware address, how is it done on Android.
I am trying to connect to remote device which needs the Bluetooth hardware address of that device to connect:
bdDevice = mBluetoothAdapter.getRemoteDevice(<bluetooth_hardware_address>);
How does one discover the bluetooth address of the remote device ?
These are the parameters of the remote device I already know - Serial Number, Equipment Number, VIN Number.
In iOS this is done using the properties of the remote device to get the Bluetooth hardware address, how is it done on Android.
UPDATE:
I can get address with the following code but this doesn't give serial number to match with --
String ui_serial_number = "000055557F9FC"; //I want to use this SN to connect.
BluetoothAdapter bluetoothAdapter;
Set<BluetoothDevice> pairedDevices = bluetoothAdapter.getBondedDevices();
for (BluetoothDevice device : pairedDevices) {
// here you get the mac using device.getAddress()
//But there is nothing like device.getSerialNumber()
if(device.getSerialNumber().equals(ui_serial_number )) //What to do here?
{
//This is the <bluetooth_hardware_address> that I want to connect with.
bdDevice = mBluetoothAdapter.getRemoteDevice(device.getAddress());
break;
}
}
But there is nothing like device.getSerialNumber() to match with the serial number in the UI and connect.
When you scan for BLE devices by BluetoothAdapter.startLeScan() you will get all BluetoothDevices in callback. Then you can get each BluetoothDevice address BluetoothDevice.getAddress()
You can get a Set of all your bonded devices:
BluetoothAdapter bluetoothAdapter;
Set<BluetoothDevice> pairedDevices = bluetoothAdapter.getBondedDevices();
for (BluetoothDevice device : pairedDevices) {
// here you get the mac using device.getAddress()
}
I'm currently trying to connect two phones which know each other's MAC address via Wi-Fi Direct, and stumbled upon the following problem:
The MAC address, which I receive from
WifiManager wifiMan = (WifiManager) this
.getSystemService(Context.WIFI_SERVICE);
WifiInfo wifiInf = wifiMan.getConnectionInfo();
MAC_ADDRESS = wifiInf.getMacAddress();
is slightly different than the one I receive from the WifiP2pManager when discovering and requesting peers. Example: a0:xx:xx:... turns into a2:xx:xx....
Does anyone know why? I did not find any way to get the "Wi-Fi Direct MAC address", and as I thought the MAC address should be unique, and it's the same Wi-Fi module that handles both (normal Wi-Fi and P2P/Direct). This is very weird..
What should I do? For the two devices (Galaxy Nexus) I've got, it's always only the first two characters that differ in the MAC addresses - should I simply discard them? Is the probability to encounter problems (two devices which only differ in the first part of MAC address) too high?
Thanks.
Reading about the MAC address on wikipedia.
Addresses can either be universally administered addresses or locally administered addresses.
Universally administered and locally administered addresses are distinguished by setting the second-least-significant bit of the most significant byte of the address. This bit is also referred to as the U/L bit, short for Universal/Local, which identifies how the address is administered. If the bit is 0, the address is universally administered. If it is 1, the address is locally administered.
Since Wi-Fi Direct is just another stack on top of MAC, you should also check what that bit can mean for it. I've found some mail discussion shedding some light on this. Apparently quote below is from a WFA spec.
The P2P Device shall assign a P2P Interface Address, corresponding to
the format as described in §7.1.3.3.1 of IEEE Std 802.11‑2007 1, which
is used to communicate with the P2P Group Owner or Clients within a P2P
Group. A P2P Interface Address is not required to be globally unique and
may be locally administered. A P2P Interface Address may be the same as
the P2P Device Address provided the requirements for P2P Interface
Address in this clause are satisfied.
So I believe answer to this question is, you shouldn't take MAC address from WifiManager and use it with Wi-Fi P2P connections.
I had been searching for this during my project. My requirements were to uniquely identify devices in an adhoc P2p network formed with WiFi Direct. Each device should identify its friend device the next time when it comes into proximity. I needed my own WiFi (Direct) MAC and my friends' to create a Key for this friend zone creation.
My Research: The design is in such a way that there is an Unique Universal ID and a Local ID. Reason: Universal ID can only be used to connect to Infrastructure mode Networks. Local ID could be used for "ad-hoc" mode networks(device to device). In this ad-hoc mode, there are possibilities that a single device might simultaneosly belong to several ad-hoc groups.
Hence to support this concurrent operations, P2p devices support
Multiple MAC entities, possibly on different channels.
For each session, a persistent group MAY use a different channel and device
MAC for each session.
P2P devices use their global MAC address as Device ID during discovery and negotiation, and a temporary local MAC address for all frames within a group. Understood from here
However, there is NO straight forward way to obtain one's own WiFi P2p MAC address. Issue 53437: Android.
In this issue discussion, the project member from google has suggested this is possible and just that it hasn't been documented
Solution: Using intent filter WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION and the extra
from the intent WifiP2pManager.EXTRA_WIFI_P2P_DEVICE
This is how I have used it in my project:
#Override
public void onReceive(Context context, Intent intent) {
....
....
String action = intent.getAction();
if (WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION
.equals(action)) {
WifiP2pDevice device = (WifiP2pDevice) intent
.getParcelableExtra(WifiP2pManager.EXTRA_WIFI_P2P_DEVICE);
String myMac = device.deviceAddress;
Log.d(TAG, "Device WiFi P2p MAC Address: " + myMac);
/* Saving WiFi P2p MAC in SharedPref */
sharedPref = context.getSharedPreferences(context.getString(R.string.sp_file_name), Context.MODE_PRIVATE);
String MY_MAC_ADDRESS = sharedPref.getString(context.getString(R.string.sp_field_my_mac), null);
if (MY_MAC_ADDRESS == null || MY_MAC_ADDRESS != myMac) {
SharedPreferences.Editor editor = sharedPref.edit();
editor.putString(context.getString(R.string.sp_field_my_mac), myMac);
editor.commit();
}
Hope this helps someone!
iFixit says that the Galaxy Nexus uses the BCM4330 for its MAC, Baseband, and PHY, so if you have any friends at Broadcom you could ask them.
Sadly, the datasheet is not public; the best I can do is link you to a block diagram.
I was struggling all night to figure out a way to retrieve WiFi Direct mac address instead, since my requirements were drafted around the assumption that it's feasible.
It's kind of round about, you create a single device group and get the owner and the device address along with it.
Here's the code,
final WifiP2pManager p2pManager = (WifiP2pManager) getSystemService(WIFI_P2P_SERVICE);
final WifiP2pManager.Channel channel = p2pManager.initialize(this, getMainLooper(), null);
p2pManager.createGroup(channel, new WifiP2pManager.ActionListener() {
#Override
public void onSuccess() {
p2pManager.requestGroupInfo(channel, new WifiP2pManager.GroupInfoListener() {
#Override
public void onGroupInfoAvailable(WifiP2pGroup wifiP2pGroup) {
Log.i("", wifiP2pGroup.getOwner().deviceAddress);
// Following removal necessary to not have the manager busy for other stuff, subsequently
p2pManager.removeGroup(channel, new WifiP2pManager.ActionListener() {
#Override
public void onSuccess() {
Log.i("", "Removed");
}
#Override
public void onFailure(int i) {
Log.i("", "Failed " + i);
}
});
}
});
}
#Override
public void onFailure(int i) {
Log.i("", String.valueOf(i));
}
});
Forget Wifi manager. Wifi direct address does not equals to MAC address. Wifi direct address uses for wifi direct connection. You can not use to anything else.
To connect two device with wifi direct device, you have to create a WifiP2pGroup with one of your device. With your another device, you have to search the WifiP2pGroups, select yours, and connect.
You can get WiFi direct address using next code:
public String getWFDMacAddress(){
try {
List<NetworkInterface> interfaces = Collections.list(NetworkInterface.getNetworkInterfaces());
for (NetworkInterface ntwInterface : interfaces) {
if (ntwInterface.getName().equalsIgnoreCase("p2p0")) {
byte[] byteMac = ntwInterface.getHardwareAddress();
if (byteMac==null){
return null;
}
StringBuilder strBuilder = new StringBuilder();
for (int i=0; i<byteMac.length; i++) {
strBuilder.append(String.format("%02X:", byteMac[i]));
}
if (strBuilder.length()>0){
strBuilder.deleteCharAt(strBuilder.length()-1);
}
return strBuilder.toString();
}
}
} catch (Exception e) {
Log.d(TAG, e.getMessage());
}
return null;
}
I want some unique ID of the Android device. I've tried it with the following code
String ts = Context.TELEPHONY_SERVICE;
TelephonyManager telephonyManager = (TelephonyManager) this.getSystemService(ts);
However I know that this works only for phones.
What if my app is running on some notebook, netbook or other type of device? How do I get an unique ID in that case?
There are three types of identifier on android phone.
IMEI
IMSI
String ts = Context.TELEPHONY_SERVICE;
TelephonyManager mTelephonyMgr = (TelephonyManager) getSystemService(ts);
String imsi = mTelephonyMgr.getSubscriberId();
String imei = mTelephonyMgr.getDeviceId();
Android ID
It is a 64-bit hex string which is generated on the device's first boot.
Generally it won't be changed unless is factory reset.
Secure.getString(getContentResolver(), Secure.ANDROID_ID);
Sorry to bump an old thread but this problem gives me headache, I found a good article for someone to read, and this really helps me a lot.
Sometimes it is required during Android application development to get the unique id of the Android based smartphone device. This is necessary in cases when the user wants to track the unique device installations of the application.
This is also useful in cases where the Android developer wants to send Push messages to only few specific devices. So over here it becomes necessary to have a UDID for every device.
In Android there are many alternatives to UDID of the device. Some of the methods to get the UDID in android application are listed below with its advantages and disadvantages and any necessary permissions for getting the device ID.
The IMEI: (International Mobile Equipment Identity)
The Android ID
The WLAN MAC Address string
The Bluetooth Address string
1) IMEI: (International Mobile Equipment Identity)
The IMEI Number is a very good and primary source to get the device ID. It is unique for each and every device and is dependent on the device Hardware. So it is also unique for each and every device and it is permanent till the lifetime of the device.
The code snippet to get the Device IMEI is as below,
TelephonyManager TelephonyMgr = (TelephonyManager)getSystemService(TELEPHONY_SERVICE);
String m_deviceId = TelephonyMgr.getDeviceId();
For this your application will require the permission “android.permission.READ_PHONE_STATE” given in the manifest file.
Advantages of using IMEI as Device ID:
The IMEI is unique for each and every device.
It remains unique for the device even if the application is re-installed or if the device is rooted or factory reset.
Disadvantages of using IMEI as Device ID:
IMEI is dependent on the Simcard slot of the device, so it is not possible to get the IMEI for the devices that do not use Simcard.
In Dual sim devices, we get 2 different IMEIs for the same device as it has 2 slots for simcard.
2) The Android ID
The Android_ID is a unique 64 bit number that is generated and stored when the device is first booted. The Android_ID is wiped out when the device is Factory reset and new one gets generated.
The code to get the Android_ID is shown below,
String m_androidId = Secure.getString(getContentResolver(), Secure.ANDROID_ID);
Advantages of using Android_ID as Device ID:
It is unique identifier for all type of devices (smart phones and tablets).
No need of any permission.
It will remain unique in all the devices and it works on phones without Simcard slot.
Disadvantages of using Android_ID as Device ID:
If Android OS version is upgraded by the user then this may get changed.
The ID gets changed if device is rooted or factory reset is done on the device.
Also there is a known problem with a Chinese manufacturer of android device that some devices have same Android_ID.
3) The WLAN MAC Address string
We can get the Unique ID for android phones using the WLAN MAC address also. The MAC address is unique for all devices and it works for all kinds of devices.
The code snippet to get the WLAN MAC address for a device is as shown below,
WifiManager m_wm = (WifiManager)getSystemService(Context.WIFI_SERVICE);
String m_wlanMacAdd = m_wm.getConnectionInfo().getMacAddress();
Your application will require the permission “android.permission.ACCESS_WIFI_STATE” given in the manifest file.
Advantages of using WLAN MAC address as Device ID:
It is unique identifier for all type of devices (smart phones and tablets).
It remains unique if the application is reinstalled.
Disadvantages of using WLAN MAC address as Device ID:
If device doesn’t have wifi hardware then you get null MAC address, but generally it is seen that most of the Android devices have wifi hardware and there are hardly few devices in the market with no wifi hardware.
4) The Bluetooth Address string
We can get the Unique ID for android phones using the Bluetooth device also. The Bluetooth device address is unique for each device having Bluetooth hardware.
The code snippet to get the Bluetooth device address is as given below,
BluetoothAdapter m_BluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
String m_bluetoothAdd = m_BluetoothAdapter.getAddress();
To get the above code, your application needs the permission “android.permission.BLUETOOTH” given in the manifest file.
Advantages of using Bluetooth device address as Device ID:
It is unique identifier for all type of devices (smart phones and tablets).
There is generally a single Bluetooth hardware in all devices and it doesn’t gets changed.
Disadvantages of using Bluetooth device address as Device ID:
If device hasn’t bluetooth hardware then you get null.
As per me these are few of the best possible ways to get the Unique Device ID for Android smartphone device and their pros and cons of using it. Now it is upto you to decide which method to use based on the Android application development requirements.
If there are any other methods to get UDID and that covers up the disadvantages of above methods, then I would love to explore those in my Android application. Pl. share those in comment box and also if any suggestions or queries.
Here's the article
Secure.getString(getContentResolver(), Secure.ANDROID_ID);
This will not work for all the devices.
Some of the android devices has a problem Some devices returns null when we try to get the Device ID.The only way to solve this issue is to make a pseudodeviceID which should be generated by ourself.This function will generation a unique device ID for you.You can make changes to this function as you needed.Me too struggled a lot for solving this issue.
public String getDeviceID() {
/*String Return_DeviceID = USERNAME_and_PASSWORD.getString(DeviceID_key,"Guest");
return Return_DeviceID;*/
TelephonyManager TelephonyMgr = (TelephonyManager) getApplicationContext().getApplicationContext().getSystemService(Context.TELEPHONY_SERVICE);
String m_szImei = TelephonyMgr.getDeviceId(); // Requires
// READ_PHONE_STATE
// 2 compute DEVICE ID
String m_szDevIDShort = "35"
+ // we make this look like a valid IMEI
Build.BOARD.length() % 10 + Build.BRAND.length() % 10
+ Build.CPU_ABI.length() % 10 + Build.DEVICE.length() % 10
+ Build.DISPLAY.length() % 10 + Build.HOST.length() % 10
+ Build.ID.length() % 10 + Build.MANUFACTURER.length() % 10
+ Build.MODEL.length() % 10 + Build.PRODUCT.length() % 10
+ Build.TAGS.length() % 10 + Build.TYPE.length() % 10
+ Build.USER.length() % 10; // 13 digits
// 3 android ID - unreliable
String m_szAndroidID = Secure.getString(getContentResolver(),Secure.ANDROID_ID);
// 4 wifi manager, read MAC address - requires
// android.permission.ACCESS_WIFI_STATE or comes as null
WifiManager wm = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);
String m_szWLANMAC = wm.getConnectionInfo().getMacAddress();
// 5 Bluetooth MAC address android.permission.BLUETOOTH required
BluetoothAdapter m_BluetoothAdapter = null; // Local Bluetooth adapter
m_BluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
String m_szBTMAC = m_BluetoothAdapter.getAddress();
System.out.println("m_szBTMAC "+m_szBTMAC);
// 6 SUM THE IDs
String m_szLongID = m_szImei + m_szDevIDShort + m_szAndroidID+ m_szWLANMAC + m_szBTMAC;
System.out.println("m_szLongID "+m_szLongID);
MessageDigest m = null;
try {
m = MessageDigest.getInstance("MD5");
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
m.update(m_szLongID.getBytes(), 0, m_szLongID.length());
byte p_md5Data[] = m.digest();
String m_szUniqueID = new String();
for (int i = 0; i < p_md5Data.length; i++) {
int b = (0xFF & p_md5Data[i]);
// if it is a single digit, make sure it have 0 in front (proper
// padding)
if (b <= 0xF)
m_szUniqueID += "0";
// add number to string
m_szUniqueID += Integer.toHexString(b);
}
m_szUniqueID = m_szUniqueID.toUpperCase();
Log.i("-------------DeviceID------------", m_szUniqueID);
Log.d("DeviceIdCheck", "DeviceId that generated MPreferenceActivity:"+m_szUniqueID);
return m_szUniqueID;
}
Look at the constant
ANDROID_ID in android.provider.Secure.Settings to see if that helps.
I am adding a few useful links from official docs;
Best Practices for Unique Identifiers
Changes to Device Identifiers in Android O
For detailed instructions on how to get a Unique Identifier for each Android device your application is installed from, see this official Android Developers Blog posting:
http://android-developers.blogspot.com/2011/03/identifying-app-installations.html
It seems the best way is for you to generate one your self upon installation and subsequently read it when the application is re-launched.
I personally find this acceptable but not ideal. No one identifier provided by Android works in all instances as most are dependent on the phone's radio states (wifi on/off, cellular on/off, bluetooth on/off). The others like Settings.Secure.ANDROID_ID must be implemented by the manufacturer and are not guaranteed to be unique.
The following is an example of writing data to an INSTALLATION file that would be stored along with any other data the application saves locally.
public class Installation {
private static String sID = null;
private static final String INSTALLATION = "INSTALLATION";
public synchronized static String id(Context context) {
if (sID == null) {
File installation = new File(context.getFilesDir(), INSTALLATION);
try {
if (!installation.exists())
writeInstallationFile(installation);
sID = readInstallationFile(installation);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
return sID;
}
private static String readInstallationFile(File installation) throws IOException {
RandomAccessFile f = new RandomAccessFile(installation, "r");
byte[] bytes = new byte[(int) f.length()];
f.readFully(bytes);
f.close();
return new String(bytes);
}
private static void writeInstallationFile(File installation) throws IOException {
FileOutputStream out = new FileOutputStream(installation);
String id = UUID.randomUUID().toString();
out.write(id.getBytes());
out.close();
}
}
Use a MAC address:
A Media Access Control address (MAC
address) is a unique identifier
assigned to network interfaces
Any device connected to a network is guaranteed to have a MAC address, and you can find it on the Android by going to Settings > About Phone > Status.
You should be able to get the bluetooth Mac address using the Bluetooth API.
You can try this:
String deviceId = Secure.getString(this.getContentResolver(),
Secure.ANDROID_ID);
Settings.Secure#ANDROID_ID returns the Android ID as an unique 64-bit hex string.
import android.provider.Settings.Secure;
private String android_id = Secure.getString(getContext().getContentResolver(),
Secure.ANDROID_ID);
final TelephonyManager tm = (TelephonyManager) getBaseContext().getSystemService(Context.TELEPHONY_SERVICE);
final String tmDevice, tmSerial, tmPhone, androidId;
tmDevice = "" + tm.getDeviceId();
tmSerial = "" + tm.getSimSerialNumber();
androidId = "" + android.provider.Settings.Secure.getString(getContentResolver(), android.provider.Settings.Secure.ANDROID_ID);
UUID deviceUuid = new UUID(androidId.hashCode(), ((<span id="IL_AD3" class="IL_AD">long</span>)tmDevice.hashCode() << 32) | tmSerial.hashCode());
String deviceId = deviceUuid.toString();
You can get MAC address if network-device (Bluetooth etc.) is enabled in the system (turned on). But device may have Bluetooth, WiFi, etc. or nothing.
You may write your own unique ID generator (with 20 numbers or symbols randomly for example)
TextView textAndroidId = (TextView)findViewById(R.id.androidid);
String AndroidId = Settings.Secure.getString(getContentResolver(), Settings.Secure.ANDROID_ID);
textAndroidId.setText("My ID is: " + AndroidId);
Since new restrictions have been applied to the MAC address and other telephony-related API's and one can only access those hardware-related Unique identifiers if they are part of the system app and has the required privileges.
from docs:
When working with Android identifiers, follow these best practices:
Avoid using hardware identifiers. In most use cases, you can avoid using hardware identifiers, such as SSAID (Android ID), without limiting required functionality.
Android 10 (API level 29) adds restrictions for non-resettable identifiers, which include both IMEI and serial number. Your app must be a device or profile owner app, have special carrier permissions, or have the READ_PRIVILEGED_PHONE_STATE privileged permission in order to access these identifiers.
Only use an Advertising ID for user profiling or ads use cases. When using an Advertising ID, always respect users' selections regarding ad tracking. Also, ensure that the identifier cannot be connected to personally identifiable information (PII), and avoid bridging Advertising ID resets.
Use a Firebase installation ID (FID) or a privately stored GUID whenever possible for all other use cases, except for payment fraud prevention and telephony. For the vast majority of non-ads use cases, an FID or GUID should be sufficient.
Use APIs that are appropriate for your use case to minimize privacy risk. Use the DRM API for high-value content protection and the SafetyNet APIs for abuse protection. The SafetyNet APIs are the easiest way to determine whether a device is genuine without incurring privacy risk.
The remaining sections of this guide elaborate on these rules in the context of developing Android apps.
The best case is we use the FID or GUID to identify the uniqueness of the app per installation, here is how you can do it.
fun getDeviceId(): String {
return FirebaseInstallations.getInstance().id.result ?: UUID.randomUUID().toString()
}
You can check permission and can evaluate the value it will give you the device id:
private static final int REQUEST_READ_PHONE_STATE = 1;
int permissionCheck = ContextCompat.checkSelfPermission(getContext(),
Manifest.permission.READ_PHONE_STATE);
if (permissionCheck != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(getActivity(), new String[]{Manifest.permission.READ_PHONE_STATE}, REQUEST_READ_PHONE_STATE);
} else {
TelephonyManager tManager = (TelephonyManager) getContext().getSystemService(Context.TELEPHONY_SERVICE);
String uid = tManager.getDeviceId();
System.out.print(uid);
}
Output: 358240051111110