Added proximity descriptor

This commit is contained in:
Alexandros Schillings
2014-03-14 18:00:01 +00:00
parent 8c03f29c32
commit f08a561e7e
3 changed files with 136 additions and 103 deletions
@@ -66,7 +66,7 @@ public final class IBeaconManufacturerData {
mUUID = calculateUUIDString(Arrays.copyOfRange(mData, 4, 20)); mUUID = calculateUUIDString(Arrays.copyOfRange(mData, 4, 20));
mMajor = ByteUtils.getIntFrom2ByteArray(Arrays.copyOfRange(mData, 20, 22)); mMajor = ByteUtils.getIntFrom2ByteArray(Arrays.copyOfRange(mData, 20, 22));
mMinor = ByteUtils.getIntFrom2ByteArray(Arrays.copyOfRange(mData, 22, 24)); 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(); return sb.toString();
} }
public double getAccuracy(int rssi){ public double getAccuracy(double rssi){
return calculateAccuracy(mCalibratedTxPower, rssi); return calculateAccuracy(mCalibratedTxPower, rssi);
} }
@@ -99,6 +99,22 @@ public final class IBeaconManufacturerData {
return mCompanyIdentidier; 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(){ public int getIBeaconAdvertisement(){
return mIBeaconAdvertisment; return mIBeaconAdvertisment;
} }
@@ -116,7 +132,7 @@ public final class IBeaconManufacturerData {
} }
// Code taken from: http://stackoverflow.com/questions/20416218/understanding-ibeacon-distancing // 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) { if (rssi == 0) {
return -1.0; // if we cannot determine accuracy, return -1. return -1.0; // if we cannot determine accuracy, return -1.
} }
+17 -7
View File
@@ -48,7 +48,8 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:paddingRight="5dp" android:paddingRight="5dp"
android:text="@string/label_mac" android:text="@string/label_mac"
android:textSize="12sp" /> android:textSize="12sp"
android:textStyle="bold" />
<TextView <TextView
android:id="@+id/device_address" android:id="@+id/device_address"
@@ -60,9 +61,11 @@
<TextView <TextView
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:paddingLeft="5dp"
android:paddingRight="5dp" android:paddingRight="5dp"
android:text="@string/label_rssi" android:text="@string/label_rssi"
android:textSize="12sp" /> android:textSize="12sp"
android:textStyle="bold" />
<TextView <TextView
android:id="@+id/device_rssi" android:id="@+id/device_rssi"
@@ -83,7 +86,8 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:paddingRight="5dp" android:paddingRight="5dp"
android:text="@string/label_uuid" android:text="@string/label_uuid"
android:textSize="12sp" /> android:textSize="12sp"
android:textStyle="bold" />
<TextView <TextView
android:id="@+id/ibeacon_uuid" android:id="@+id/ibeacon_uuid"
@@ -98,7 +102,8 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:paddingRight="5dp" android:paddingRight="5dp"
android:text="@string/label_major" android:text="@string/label_major"
android:textSize="12sp" /> android:textSize="12sp"
android:textStyle="bold" />
<TextView <TextView
android:id="@+id/ibeacon_major" android:id="@+id/ibeacon_major"
@@ -110,9 +115,11 @@
<TextView <TextView
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:paddingLeft="5dp"
android:paddingRight="5dp" android:paddingRight="5dp"
android:text="@string/label_minor" android:text="@string/label_minor"
android:textSize="12sp" /> android:textSize="12sp"
android:textStyle="bold" />
<TextView <TextView
android:id="@+id/ibeacon_minor" android:id="@+id/ibeacon_minor"
@@ -126,7 +133,8 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:paddingRight="5dp" android:paddingRight="5dp"
android:text="@string/label_tx_power" android:text="@string/label_tx_power"
android:textSize="12sp" /> android:textSize="12sp"
android:textStyle="bold" />
<TextView <TextView
android:id="@+id/ibeacon_tx_power" android:id="@+id/ibeacon_tx_power"
@@ -138,9 +146,11 @@
<TextView <TextView
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:paddingLeft="5dp"
android:paddingRight="5dp" android:paddingRight="5dp"
android:text="@string/label_distance" android:text="@string/label_distance"
android:textSize="12sp" /> android:textSize="12sp"
android:textStyle="bold" />
<TextView <TextView
android:id="@+id/ibeacon_distance" android:id="@+id/ibeacon_distance"
@@ -1,5 +1,6 @@
package uk.co.alt236.btlescan.adapters; package uk.co.alt236.btlescan.adapters;
import java.text.DecimalFormat;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@@ -14,110 +15,116 @@ import android.view.ViewGroup;
import android.widget.BaseAdapter; import android.widget.BaseAdapter;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.TextView; import android.widget.TextView;
// Adapter for holding devices found through scanning. // Adapter for holding devices found through scanning.
public class LeDeviceListAdapter extends BaseAdapter { public class LeDeviceListAdapter extends BaseAdapter {
private final List<BluetoothLeDevice> mLeDevices; private static final DecimalFormat DOUBLE_TWO_DIGIT_ACCURACY = new DecimalFormat("#.##");
private final LayoutInflater mInflator;
public LeDeviceListAdapter(Activity activity) { private final List<BluetoothLeDevice> mLeDevices;
super(); private final LayoutInflater mInflator;
mLeDevices = new ArrayList<BluetoothLeDevice>();
mInflator = activity.getLayoutInflater();
}
public void addDevice(BluetoothLeDevice device) { public LeDeviceListAdapter(Activity activity) {
final int position = mLeDevices.indexOf(device); super();
if(position == -1){ mLeDevices = new ArrayList<BluetoothLeDevice>();
mLeDevices.add(device); mInflator = activity.getLayoutInflater();
} else { }
mLeDevices.set(position, device);
}
}
public BluetoothLeDevice getDevice(int position) { public void addDevice(BluetoothLeDevice device) {
return mLeDevices.get(position); final int position = mLeDevices.indexOf(device);
} if(position == -1){
mLeDevices.add(device);
} else {
mLeDevices.set(position, device);
}
}
public void clear() { public BluetoothLeDevice getDevice(int position) {
mLeDevices.clear(); return mLeDevices.get(position);
} }
@Override public void clear() {
public int getCount() { mLeDevices.clear();
return mLeDevices.size(); }
}
@Override @Override
public Object getItem(int i) { public int getCount() {
return mLeDevices.get(i); return mLeDevices.size();
} }
@Override @Override
public long getItemId(int i) { public Object getItem(int i) {
return i; return mLeDevices.get(i);
} }
@Override @Override
public View getView(int i, View view, ViewGroup viewGroup) { public long getItemId(int i) {
ViewHolder viewHolder; return i;
// 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();
}
final BluetoothLeDevice device = mLeDevices.get(i); @Override
final String deviceName = device.getName(); 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){ final BluetoothLeDevice device = mLeDevices.get(i);
viewHolder.deviceName.setText(deviceName); final String deviceName = device.getName();
} else{ final double rssi = device.getRssi();
viewHolder.deviceName.setText(R.string.unknown_device);
}
if (IBeaconUtils.isThisAnIBeacon(device)){ if (deviceName != null && deviceName.length() > 0){
final IBeaconManufacturerData data = new IBeaconManufacturerData(device); viewHolder.deviceName.setText(deviceName);
viewHolder.deviceIcon.setImageResource(R.drawable.ic_device_ibeacon); } else{
viewHolder.ibeaconSection.setVisibility(View.VISIBLE); viewHolder.deviceName.setText(R.string.unknown_device);
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);
}
viewHolder.deviceAddress.setText(device.getAddress()); if (IBeaconUtils.isThisAnIBeacon(device)){
viewHolder.deviceRssi.setText(String.valueOf(device.getRssi()) + "db"); final IBeaconManufacturerData data = new IBeaconManufacturerData(device);
return view; final double accuracy = data.getAccuracy(rssi);
}
static class ViewHolder { viewHolder.deviceIcon.setImageResource(R.drawable.ic_device_ibeacon);
TextView deviceName; viewHolder.ibeaconSection.setVisibility(View.VISIBLE);
TextView deviceAddress; viewHolder.ibeaconMajor.setText(String.valueOf(data.getMajor()));
TextView deviceRssi; viewHolder.ibeaconMinor.setText(String.valueOf(data.getMinor()));
TextView ibeaconUUID; viewHolder.ibeaconTxPower.setText(String.valueOf(data.getCalibratedTxPower()));
TextView ibeaconMajor; viewHolder.ibeaconUUID.setText(data.getUUID());
TextView ibeaconMinor; viewHolder.ibeaconDistance.setText(
TextView ibeaconTxPower; DOUBLE_TWO_DIGIT_ACCURACY.format(accuracy) + "m " + data.getDistanceDescriptor(accuracy));
TextView ibeaconDistance; } else {
View ibeaconSection; viewHolder.deviceIcon.setImageResource(R.drawable.ic_bluetooth);
ImageView deviceIcon; viewHolder.ibeaconSection.setVisibility(View.GONE);
} }
} 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;
}
}