I wish to detect Eddystone Ul and uid without using Proximity Beacon API or Nearby Messages API. I wish to use native android libraries like BluetoothAdapter or BluetoothGatt or BluetoothGap to parse the eddystone frames. Is this feasible? if so how and If its not feasible then what could be the alternative?
The following is the simplest way to get information about Eddystone AFAIK.
// onLeScan() method of BluetoothAdapter.LeScanCallback interface.
public void onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord)
{
// Parse the payload of the advertisement packet
// as a list of AD structures.
List<ADStructure> structures =
ADPayloadParser.getInstance().parse(scanRecord);
// For each AD structure contained in the advertisement packet.
for (ADStructure structure : structures)
{
// If the AD structure represents Eddystone UID.
if (structure instanceof EddystoneUID)
{
// Eddystone UID
EddystoneUID es = (EddystoneUID)structure;
Log.d(TAG, "Tx Power = " + es.getTxPower());
Log.d(TAG, "Namespace ID = " + es.getNamespaceIdAsString());
Log.d(TAG, "Instance ID = " + es.getInstanceIdAsString());
Log.d(TAG, "Beacon ID = " + es.getBeaconIdAsString());
// As byte arrays if you want.
byte[] namespaceId = es.getNamespaceId();
byte[] instanceId = es.getInstanceId();
byte[] beaconId = es.getBeaconId();
}
// If the AD structure represents Eddystone URL.
else if (structure instanceof EddystoneURL)
{
// Eddystone URL
EddystoneURL es = (EddystoneURL)structure;
Log.d(TAG, "Tx Power = " + es.getTxPower());
Log.d(TAG, "URL = " + es.getURL());
}
// If the AD structure represents Eddystone TLM.
else if (structure instanceof EddystoneTLM)
{
// Eddystone TLM
EddystoneTLM es = (EddystoneTLM)structure;
Log.d(TAG, "TLM Version = " + es.getTLMVersion());
Log.d(TAG, "Battery Voltage = " + es.getBatteryVoltage());
Log.d(TAG, "Beacon Temperature = " + es.getBeaconTemperature());
Log.d(TAG, "Advertisement Count = " + es.getAdvertisementCount());
Log.d(TAG, "Elapsed Time = " + es.getElapsedTime());
}
}
}
You don't have to know details about the Eddystone specification if you use nv-bluetooth.
dependencies {
compile 'com.neovisionaries:nv-bluetooth:1.7'
}
Beacon Temperature in Eddystone TLM is expressed in a signed fixed-point notation. The code examples in How to detect Eddystone-Compatible Beacons (Android Beacon Library) don't show how to extract the data as a floating point number as of this writing. On the other hand, EddystoneTLM
class in nv-bluetooth has a method as shown below, so you don't have to decode the fixed-point notation.
public float getBeaconTemperature();
Likewise, EddystoneURL
class has a method to get the URL as URL
.
public URL getURL();
So, you don't have to do a step like below which is required when you use Android Beacon Library.
String url = UrlBeaconUrlCompressor.uncompress(beacon.getId1().toByteArray());
nv-bluetooth implements data structures related to Eddystone as an inheritance tree as shown below. This kind of proper inheritance tree is difficult to find in other libraries.
ADStructure
|
+-- ServiceData
|
+-- Eddystone
|
+-- EddystoneUID
|
+-- EddystoneURL
|
+-- EddystoneTLM
One of the benefits of the proper inheritance tree is that methods are placed at the right positions. Like this:
ADStructure
| // AD Structure Length - 1
| int getLength();
|
| // AD Type
| int getType();
|
| // AD Data
| byte[] getData();
|
+-- ServiceData
| | // Service UUID
| | UUID getServiceUUID();
| |
| +-- Eddystone
| | // Eddystone Frame Type
| | FrameType getFrameType();
| |
| +-- EddystoneUID
| | // Tx Power
| | int getTxPower();
| |
| | // Namespace ID (byte[])
| | byte[] getNamespaceId();
| |
| | // Instance ID (byte[])
| | byte[] getInstanceId();
| |
| | // Beacon ID (byte[])
| | byte[] getBeaconId();
| |
| | // Namespace ID (String)
| | String getNamespaceIdAsString();
| |
| | // Instance ID (String)
| | String getInstanceIdAsString();
| |
| | // Beacon ID (String)
| | String getBeaconIdAsString();
| |
| +-- EddystoneURL
| | // Tx Power
| | int getTxPower();
| |
| | // URL
| | URL getURL();
| |
| +-- EddystoneTLM
| // TLM Version
| int getTLMVersion();
|
| // Battery Voltage
| int getBatteryVoltage();
|
| // Beacon Temperature
| float getBeaconTemperature();
|
| // Advertisement Count
| long getAdvertisementCount();
|
| // Elapsed Time
| long getElapsedTime();
|
+-- ADManufacturerSpecific
| | // Company ID
| | int getCompanyId();
| |
| +-- IBeacon
| | // Major Number
| | int getMajor();
| |
| | (abbrev)
| |
| +-- Ucode
| | // Ucode
| | String getUcode();
| |
| | (abbrev)