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 3f03cb2..5fcd915 100644
--- a/library/src/uk/co/alt236/bluetoothlelib/device/mfdata/IBeaconManufacturerData.java
+++ b/library/src/uk/co/alt236/bluetoothlelib/device/mfdata/IBeaconManufacturerData.java
@@ -66,7 +66,7 @@ public final class IBeaconManufacturerData {
mUUID = calculateUUIDString(Arrays.copyOfRange(mData, 4, 20));
mMajor = ByteUtils.getIntFrom2ByteArray(Arrays.copyOfRange(mData, 20, 22));
mMinor = ByteUtils.getIntFrom2ByteArray(Arrays.copyOfRange(mData, 22, 24));
- mCalibratedTxPower = ByteUtils.getIntFromByte(data[24]);
+ mCalibratedTxPower = data[24];
}
@@ -87,7 +87,7 @@ public final class IBeaconManufacturerData {
return sb.toString();
}
- public double getAccuracy(int rssi){
+ public double getAccuracy(double rssi){
return calculateAccuracy(mCalibratedTxPower, rssi);
}
@@ -99,6 +99,22 @@ 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;
}
@@ -116,7 +132,7 @@ public final class IBeaconManufacturerData {
}
// Code taken from: http://stackoverflow.com/questions/20416218/understanding-ibeacon-distancing
- protected static double calculateAccuracy(int txPower, double rssi) {
+ private static double calculateAccuracy(int txPower, double rssi) {
if (rssi == 0) {
return -1.0; // if we cannot determine accuracy, return -1.
}
diff --git a/sample_app/res/layout/list_item_device.xml b/sample_app/res/layout/list_item_device.xml
index acd990e..1f46b15 100644
--- a/sample_app/res/layout/list_item_device.xml
+++ b/sample_app/res/layout/list_item_device.xml
@@ -48,7 +48,8 @@
android:layout_height="wrap_content"
android:paddingRight="5dp"
android:text="@string/label_mac"
- android:textSize="12sp" />
+ android:textSize="12sp"
+ android:textStyle="bold" />
+ android:textSize="12sp"
+ android:textStyle="bold" />
+ android:textSize="12sp"
+ android:textStyle="bold" />
+ android:textSize="12sp"
+ android:textStyle="bold" />
+ android:textSize="12sp"
+ android:textStyle="bold" />
+ android:textSize="12sp"
+ android:textStyle="bold" />
+ android:textSize="12sp"
+ android:textStyle="bold" />
mLeDevices;
- private final LayoutInflater mInflator;
+// Adapter for holding devices found through scanning.
+public class LeDeviceListAdapter extends BaseAdapter {
+ private static final DecimalFormat DOUBLE_TWO_DIGIT_ACCURACY = new DecimalFormat("#.##");
- public LeDeviceListAdapter(Activity activity) {
- super();
- mLeDevices = new ArrayList();
- mInflator = activity.getLayoutInflater();
- }
+ private final List mLeDevices;
+ private final LayoutInflater mInflator;
- public void addDevice(BluetoothLeDevice device) {
- final int position = mLeDevices.indexOf(device);
- if(position == -1){
- mLeDevices.add(device);
- } else {
- mLeDevices.set(position, device);
- }
- }
+ public LeDeviceListAdapter(Activity activity) {
+ super();
+ mLeDevices = new ArrayList();
+ mInflator = activity.getLayoutInflater();
+ }
- public BluetoothLeDevice getDevice(int position) {
- return mLeDevices.get(position);
- }
+ public void addDevice(BluetoothLeDevice device) {
+ final int position = mLeDevices.indexOf(device);
+ if(position == -1){
+ mLeDevices.add(device);
+ } else {
+ mLeDevices.set(position, device);
+ }
+ }
- public void clear() {
- mLeDevices.clear();
- }
+ public BluetoothLeDevice getDevice(int position) {
+ return mLeDevices.get(position);
+ }
- @Override
- public int getCount() {
- return mLeDevices.size();
- }
+ public void clear() {
+ mLeDevices.clear();
+ }
- @Override
- public Object getItem(int i) {
- return mLeDevices.get(i);
- }
+ @Override
+ public int getCount() {
+ return mLeDevices.size();
+ }
- @Override
- public long getItemId(int i) {
- return i;
- }
+ @Override
+ public Object getItem(int i) {
+ return mLeDevices.get(i);
+ }
- @Override
- public View getView(int i, View view, ViewGroup viewGroup) {
- ViewHolder viewHolder;
- // General ListView optimization code.
- if (view == null) {
- view = mInflator.inflate(R.layout.list_item_device, null);
- viewHolder = new ViewHolder();
- viewHolder.deviceAddress = (TextView) view.findViewById(R.id.device_address);
- viewHolder.deviceName = (TextView) view.findViewById(R.id.device_name);
- viewHolder.deviceRssi = (TextView) view.findViewById(R.id.device_rssi);
- viewHolder.deviceIcon = (ImageView) view.findViewById(R.id.device_icon);
- viewHolder.ibeaconMajor = (TextView) view.findViewById(R.id.ibeacon_major);
- viewHolder.ibeaconMinor = (TextView) view.findViewById(R.id.ibeacon_minor);
- viewHolder.ibeaconDistance = (TextView) view.findViewById(R.id.ibeacon_distance);
- viewHolder.ibeaconUUID = (TextView) view.findViewById(R.id.ibeacon_uuid);
- viewHolder.ibeaconTxPower = (TextView) view.findViewById(R.id.ibeacon_tx_power);
- viewHolder.ibeaconSection = (View) view.findViewById(R.id.ibeacon_section);
- view.setTag(viewHolder);
- } else {
- viewHolder = (ViewHolder) view.getTag();
- }
+ @Override
+ public long getItemId(int i) {
+ return i;
+ }
- final BluetoothLeDevice device = mLeDevices.get(i);
- final String deviceName = device.getName();
+ @Override
+ public View getView(int i, View view, ViewGroup viewGroup) {
+ ViewHolder viewHolder;
+ // General ListView optimization code.
+ if (view == null) {
+ view = mInflator.inflate(R.layout.list_item_device, null);
+ viewHolder = new ViewHolder();
+ viewHolder.deviceAddress = (TextView) view.findViewById(R.id.device_address);
+ viewHolder.deviceName = (TextView) view.findViewById(R.id.device_name);
+ viewHolder.deviceRssi = (TextView) view.findViewById(R.id.device_rssi);
+ viewHolder.deviceIcon = (ImageView) view.findViewById(R.id.device_icon);
+ viewHolder.ibeaconMajor = (TextView) view.findViewById(R.id.ibeacon_major);
+ viewHolder.ibeaconMinor = (TextView) view.findViewById(R.id.ibeacon_minor);
+ viewHolder.ibeaconDistance = (TextView) view.findViewById(R.id.ibeacon_distance);
+ viewHolder.ibeaconUUID = (TextView) view.findViewById(R.id.ibeacon_uuid);
+ viewHolder.ibeaconTxPower = (TextView) view.findViewById(R.id.ibeacon_tx_power);
+ viewHolder.ibeaconSection = (View) view.findViewById(R.id.ibeacon_section);
+ view.setTag(viewHolder);
+ } else {
+ viewHolder = (ViewHolder) view.getTag();
+ }
- if (deviceName != null && deviceName.length() > 0){
- viewHolder.deviceName.setText(deviceName);
- } else{
- viewHolder.deviceName.setText(R.string.unknown_device);
- }
+ final BluetoothLeDevice device = mLeDevices.get(i);
+ final String deviceName = device.getName();
+ final double rssi = device.getRssi();
- if (IBeaconUtils.isThisAnIBeacon(device)){
- final IBeaconManufacturerData data = new IBeaconManufacturerData(device);
- viewHolder.deviceIcon.setImageResource(R.drawable.ic_device_ibeacon);
- viewHolder.ibeaconSection.setVisibility(View.VISIBLE);
- viewHolder.ibeaconMajor.setText(String.valueOf(data.getMajor()));
- viewHolder.ibeaconMinor.setText(String.valueOf(data.getMinor()));
- viewHolder.ibeaconTxPower.setText(String.valueOf(data.getCalibratedTxPower()));
- viewHolder.ibeaconUUID.setText(data.getUUID());
- viewHolder.ibeaconDistance.setText(String.valueOf(data.getAccuracy(device.getRssi())));
- } else {
- viewHolder.deviceIcon.setImageResource(R.drawable.ic_bluetooth);
- viewHolder.ibeaconSection.setVisibility(View.GONE);
- }
+ if (deviceName != null && deviceName.length() > 0){
+ viewHolder.deviceName.setText(deviceName);
+ } else{
+ viewHolder.deviceName.setText(R.string.unknown_device);
+ }
- viewHolder.deviceAddress.setText(device.getAddress());
- viewHolder.deviceRssi.setText(String.valueOf(device.getRssi()) + "db");
- return view;
- }
+ if (IBeaconUtils.isThisAnIBeacon(device)){
+ final IBeaconManufacturerData data = new IBeaconManufacturerData(device);
+ final double accuracy = data.getAccuracy(rssi);
- static class ViewHolder {
- TextView deviceName;
- TextView deviceAddress;
- TextView deviceRssi;
- TextView ibeaconUUID;
- TextView ibeaconMajor;
- TextView ibeaconMinor;
- TextView ibeaconTxPower;
- TextView ibeaconDistance;
- View ibeaconSection;
- ImageView deviceIcon;
- }
+ viewHolder.deviceIcon.setImageResource(R.drawable.ic_device_ibeacon);
+ viewHolder.ibeaconSection.setVisibility(View.VISIBLE);
+ viewHolder.ibeaconMajor.setText(String.valueOf(data.getMajor()));
+ viewHolder.ibeaconMinor.setText(String.valueOf(data.getMinor()));
+ viewHolder.ibeaconTxPower.setText(String.valueOf(data.getCalibratedTxPower()));
+ viewHolder.ibeaconUUID.setText(data.getUUID());
+ viewHolder.ibeaconDistance.setText(
+ DOUBLE_TWO_DIGIT_ACCURACY.format(accuracy) + "m " + data.getDistanceDescriptor(accuracy));
+ } else {
+ viewHolder.deviceIcon.setImageResource(R.drawable.ic_bluetooth);
+ viewHolder.ibeaconSection.setVisibility(View.GONE);
+ }
- }
\ No newline at end of file
+ viewHolder.deviceAddress.setText(device.getAddress());
+ viewHolder.deviceRssi.setText(String.valueOf(rssi) + "db");
+ return view;
+ }
+
+ static class ViewHolder {
+ TextView deviceName;
+ TextView deviceAddress;
+ TextView deviceRssi;
+ TextView ibeaconUUID;
+ TextView ibeaconMajor;
+ TextView ibeaconMinor;
+ TextView ibeaconTxPower;
+ TextView ibeaconDistance;
+ View ibeaconSection;
+ ImageView deviceIcon;
+ }
+
+}
\ No newline at end of file