diff --git a/library/src/uk/co/alt236/bluetoothlelib/device/BluetoothLeDevice.java b/library/src/uk/co/alt236/bluetoothlelib/device/BluetoothLeDevice.java index 0130a17..5d25316 100644 --- a/library/src/uk/co/alt236/bluetoothlelib/device/BluetoothLeDevice.java +++ b/library/src/uk/co/alt236/bluetoothlelib/device/BluetoothLeDevice.java @@ -53,7 +53,7 @@ public class BluetoothLeDevice implements Parcelable{ mTimestamp = timestamp; } - private BluetoothLeDevice(Parcel in) { + protected BluetoothLeDevice(Parcel in) { final Bundle b = in.readBundle(getClass().getClassLoader()); mDevice = b.getParcelable(PARCEL_EXTRA_BLUETOOTH_DEVICE); diff --git a/library/src/uk/co/alt236/bluetoothlelib/device/mfdata/IBeaconManufacturerData.java b/library/src/uk/co/alt236/bluetoothlelib/device/mfdata/IBeaconManufacturerData.java index 5fcd915..8d689a8 100644 --- a/library/src/uk/co/alt236/bluetoothlelib/device/mfdata/IBeaconManufacturerData.java +++ b/library/src/uk/co/alt236/bluetoothlelib/device/mfdata/IBeaconManufacturerData.java @@ -56,11 +56,9 @@ public final class IBeaconManufacturerData { public IBeaconManufacturerData(byte[] data){ mData = data; - //Log.d("TAG", "~ Reading iBeacon Data: " + ByteUtils.byteArrayToHexString(data)); mCompanyIdentidier = ByteUtils.getIntFrom2ByteArray( - ByteUtils.invertArray( - Arrays.copyOfRange(mData, 0, 2))); + ByteUtils.invertArray(Arrays.copyOfRange(mData, 0, 2))); mIBeaconAdvertisment = ByteUtils.getIntFrom2ByteArray(Arrays.copyOfRange(mData, 2, 4)); mUUID = calculateUUIDString(Arrays.copyOfRange(mData, 4, 20)); @@ -69,28 +67,6 @@ public final class IBeaconManufacturerData { mCalibratedTxPower = data[24]; } - - private String calculateUUIDString(final byte[] uuid){ - final StringBuffer sb = new StringBuffer(); - - for(int i = 0 ; i< uuid.length; i++){ - if(i == 4){sb.append('-');} - if(i == 6){sb.append('-');} - if(i == 8){sb.append('-');} - if(i == 10){sb.append('-');} - - sb.append( - Integer.toHexString(ByteUtils.getIntFromByte(uuid[i]))); - } - - - return sb.toString(); - } - - public double getAccuracy(double rssi){ - return calculateAccuracy(mCalibratedTxPower, rssi); - } - public int getCalibratedTxPower(){ return mCalibratedTxPower; } @@ -99,22 +75,6 @@ public final class IBeaconManufacturerData { return mCompanyIdentidier; } - public String getDistanceDescriptor(double accuracy){ - if(accuracy < 0){ - return "WTF"; - } - - if(accuracy < 0.5){ - return "IMMEDIATE"; - } - - if(accuracy < 3.0){ - return "NEAR"; - } - - return "FAR"; - } - public int getIBeaconAdvertisement(){ return mIBeaconAdvertisment; } @@ -131,19 +91,20 @@ public final class IBeaconManufacturerData { return mUUID; } - // Code taken from: http://stackoverflow.com/questions/20416218/understanding-ibeacon-distancing - private static double calculateAccuracy(int txPower, double rssi) { - if (rssi == 0) { - return -1.0; // if we cannot determine accuracy, return -1. + private static String calculateUUIDString(final byte[] uuid){ + final StringBuffer sb = new StringBuffer(); + + for(int i = 0 ; i< uuid.length; i++){ + if(i == 4){sb.append('-');} + if(i == 6){sb.append('-');} + if(i == 8){sb.append('-');} + if(i == 10){sb.append('-');} + + sb.append( + Integer.toHexString(ByteUtils.getIntFromByte(uuid[i]))); } - double ratio = rssi*1.0/txPower; - if (ratio < 1.0) { - return Math.pow(ratio,10); - } - else { - final double accuracy = (0.89976)*Math.pow(ratio,7.7095) + 0.111; - return accuracy; - } + + return sb.toString(); } } diff --git a/library/src/uk/co/alt236/bluetoothlelib/util/IBeaconUtils.java b/library/src/uk/co/alt236/bluetoothlelib/util/IBeaconUtils.java index 1161172..d5c61d5 100644 --- a/library/src/uk/co/alt236/bluetoothlelib/util/IBeaconUtils.java +++ b/library/src/uk/co/alt236/bluetoothlelib/util/IBeaconUtils.java @@ -3,9 +3,58 @@ package uk.co.alt236.bluetoothlelib.util; import uk.co.alt236.bluetoothlelib.device.BluetoothLeDevice; public class IBeaconUtils { + private static final double DISTANCE_THRESHOLD_WTF = 0.0; + private static final double DISTANCE_THRESHOLD_IMMEDIATE = 0.5; + private static final double DISTANCE_THRESHOLD_NEAR = 0.5; + private static final byte[] SCAN_RECORD_PREFIX_IBEACON_1 = new byte[]{0x02, 0x01, 0x1A, 0x1A, (byte) 0xFF, 0x4C, 0x00, 0x02, 0x15}; private static final byte[] SCAN_RECORD_PREFIX_IBEACON_2 = new byte[]{0x02, 0x01, 0x06, 0x1A, (byte) 0xFF, 0x4C, 0x00, 0x02, 0x15}; + public static IBeaconDistanceDescriptor getDistanceDescriptor(double accuracy){ + if(accuracy < DISTANCE_THRESHOLD_WTF){ + return IBeaconDistanceDescriptor.UNKNOWN; + } + + if(accuracy < DISTANCE_THRESHOLD_IMMEDIATE){ + return IBeaconDistanceDescriptor.IMMEDIATE; + } + + if(accuracy < DISTANCE_THRESHOLD_NEAR){ + return IBeaconDistanceDescriptor.NEAR; + } + + return IBeaconDistanceDescriptor.FAR; + } + + // Code taken from: http://stackoverflow.com/questions/20416218/understanding-ibeacon-distancing + public static double calculateAccuracy(int txPower, double rssi) { + if (rssi == 0) { + return -1.0; // if we cannot determine accuracy, return -1. + } + + double ratio = rssi*1.0/txPower; + if (ratio < 1.0) { + return Math.pow(ratio,10); + } + else { + final double accuracy = (0.89976)*Math.pow(ratio,7.7095) + 0.111; + return accuracy; + } + } + + + private static boolean doesArrayBeginWith(byte[] array, byte[] prefix){ + if(array.length < prefix.length){return false;} + + for(int i = 0; i < prefix.length; i++){ + if(array[i] != prefix[i]){ + return false; + } + } + + return true; + } + public static boolean isThisAnIBeacon(BluetoothLeDevice device){ return isThisAnIBeacon(device.getScanRecord()); } @@ -22,15 +71,10 @@ public class IBeaconUtils { return false; } - private static boolean doesArrayBeginWith(byte[] array, byte[] prefix){ - if(array.length < prefix.length){return false;} - - for(int i = 0; i < prefix.length; i++){ - if(array[i] != prefix[i]){ - return false; - } - } - - return true; + public enum IBeaconDistanceDescriptor{ + IMMEDIATE, + NEAR, + FAR, + UNKNOWN, } }