From e2294ca926345f16b0f179b7e0d56e8d2cc4c446 Mon Sep 17 00:00:00 2001 From: Alexandros Schillings Date: Tue, 18 Mar 2014 15:23:14 +0000 Subject: [PATCH] Updated the UI to support the runing average --- sample_app/res/layout/list_item_device.xml | 11 +-- sample_app/res/values/colors.xml | 3 + sample_app/res/values/strings.xml | 6 ++ .../btlescan/activities/DetailsActivity.java | 53 +++++++++++--- .../btlescan/activities/MainActivity.java | 21 +++--- .../adapters/LeDeviceListAdapter.java | 70 +++++++------------ .../BluetoothLeDeviceStore.java | 10 +-- .../uk/co/alt236/btlescan/util/Constants.java | 8 +++ 8 files changed, 103 insertions(+), 79 deletions(-) create mode 100644 sample_app/res/values/colors.xml rename sample_app/src/uk/co/alt236/btlescan/{util => containers}/BluetoothLeDeviceStore.java (84%) create mode 100644 sample_app/src/uk/co/alt236/btlescan/util/Constants.java diff --git a/sample_app/res/layout/list_item_device.xml b/sample_app/res/layout/list_item_device.xml index 2f4e504..62be902 100644 --- a/sample_app/res/layout/list_item_device.xml +++ b/sample_app/res/layout/list_item_device.xml @@ -17,11 +17,12 @@ - - - diff --git a/sample_app/res/values/colors.xml b/sample_app/res/values/colors.xml new file mode 100644 index 0000000..9e35dd2 --- /dev/null +++ b/sample_app/res/values/colors.xml @@ -0,0 +1,3 @@ + + #e0e0e0 + diff --git a/sample_app/res/values/strings.xml b/sample_app/res/values/strings.xml index 92a09d8..ab8ac0e 100644 --- a/sample_app/res/values/strings.xml +++ b/sample_app/res/values/strings.xml @@ -11,11 +11,17 @@ No data Unknown Device + + %sm + %sdb + Connect Disconnect Scan Stop + + Distance: TX Power: Minor: diff --git a/sample_app/src/uk/co/alt236/btlescan/activities/DetailsActivity.java b/sample_app/src/uk/co/alt236/btlescan/activities/DetailsActivity.java index ac4df26..3b8bacd 100644 --- a/sample_app/src/uk/co/alt236/btlescan/activities/DetailsActivity.java +++ b/sample_app/src/uk/co/alt236/btlescan/activities/DetailsActivity.java @@ -9,6 +9,7 @@ import uk.co.alt236.bluetoothlelib.util.AdRecordUtils; import uk.co.alt236.bluetoothlelib.util.ByteUtils; import uk.co.alt236.bluetoothlelib.util.IBeaconUtils; import uk.co.alt236.btlescan.R; +import uk.co.alt236.btlescan.util.Constants; import android.app.Activity; import android.os.Bundle; import android.widget.TextView; @@ -16,6 +17,7 @@ import butterknife.ButterKnife; import butterknife.InjectView; public class DetailsActivity extends Activity{ + private static final String SECTION_LINE = "------------------------------"; public static final String EXTRA_DEVICE = "extra_device"; @InjectView(R.id.tvDetails) TextView mTvDetails; @@ -33,6 +35,19 @@ public class DetailsActivity extends Activity{ pupulateDetails(mDevice); } + private String formatTime(long time){ + return android.text.format.DateFormat.format( + Constants.TIME_FORMAT, new java.util.Date(time)).toString(); + } + + private String formatRssi(int rssi){ + return getString(R.string.formatter_db, String.valueOf(rssi)); + } + + private String formatRssi(double rssi){ + return getString(R.string.formatter_db, String.valueOf(rssi)); + } + private void pupulateDetails(BluetoothLeDevice device) { final StringBuilder sb = new StringBuilder(); @@ -46,14 +61,24 @@ public class DetailsActivity extends Activity{ append(sb, "Device Class", device.getBluetoothDeviceClassName()); append(sb, "Bonding State", device.getBluetoothDeviceBondState()); + + append(sb, "", null); + append(sb, "RSSI Info", null); + append(sb, SECTION_LINE, null); + append(sb, "First Timestamp", formatTime(device.getFirstTimestamp())); + append(sb, "First RSSI", formatRssi(device.getFirstRssi())); + append(sb, "Current Timestamp", formatTime(device.getTimestamp())); + append(sb, "Current RSSI", formatRssi(device.getRssi())); + append(sb, "Running Average RSSI", formatRssi(device.getRunningAverageRssi())); + append(sb, "", null); append(sb, "Scan Record", null); - append(sb, "-----------------", null); + append(sb, SECTION_LINE, null); append(sb, device.getScanRecord()); append(sb, "", null); append(sb, "Raw Ad Records As String", null); - append(sb, "-----------------", null); + append(sb, SECTION_LINE, null); final Collection adRecords = device.getAdRecordStore().getRecordsAsCollection(); @@ -65,14 +90,14 @@ public class DetailsActivity extends Activity{ } append(sb, "Additional", null); - append(sb, "-----------------", null); + append(sb, SECTION_LINE, null); final boolean isIBeacon = IBeaconUtils.isThisAnIBeacon(device); append(sb, "Is iBeacon", isIBeacon); if(isIBeacon){ final IBeaconManufacturerData iBeaconData = new IBeaconManufacturerData(device); append(sb, "Company ID", iBeaconData.getCompanyIdentifier() + " (" + Integer.toHexString( iBeaconData.getCompanyIdentifier() ) + ")"); - append(sb, "iBeacon Advertisment", iBeaconData.getIBeaconAdvertisement() + " (" + Integer.toHexString( iBeaconData.getIBeaconAdvertisement() ) + ")"); + append(sb, "Advertisment", iBeaconData.getIBeaconAdvertisement() + " (" + Integer.toHexString( iBeaconData.getIBeaconAdvertisement() ) + ")"); append(sb, "UUID", iBeaconData.getUUID().toString()); append(sb, "Major", iBeaconData.getMajor() + " (" + Integer.toHexString( iBeaconData.getMajor() ) + ")"); append(sb, "Minor", iBeaconData.getMinor() + " (" + Integer.toHexString( iBeaconData.getMinor() ) + ")"); @@ -91,17 +116,25 @@ public class DetailsActivity extends Activity{ append(sb, label, String.valueOf(value)); } - private static void append(StringBuilder sb, String label, int value) { - append(sb, label, String.valueOf(value)); - } +// private static void append(StringBuilder sb, String label, double value) { +// append(sb, label, String.valueOf(value)); +// } +// +// private static void append(StringBuilder sb, String label, int value) { +// append(sb, label, String.valueOf(value)); +// } +// +// private static void append(StringBuilder sb, String label, long value) { +// append(sb, label, String.valueOf(value)); +// } - private static void append(StringBuilder sb, String label, long value) { - append(sb, label, String.valueOf(value)); + public static String padRight(String s, int n) { + return String.format("%1$-" + n + "s", s); } private static void append(StringBuilder sb, String label, String value){ if(value != null){ - sb.append("\u2022" + label +":\t" + value + "\n"); + sb.append("\u2022" + padRight(label, 10) +":\t" + value + "\n"); } else { sb.append(label + "\n"); } diff --git a/sample_app/src/uk/co/alt236/btlescan/activities/MainActivity.java b/sample_app/src/uk/co/alt236/btlescan/activities/MainActivity.java index 6e293ce..29bb119 100644 --- a/sample_app/src/uk/co/alt236/btlescan/activities/MainActivity.java +++ b/sample_app/src/uk/co/alt236/btlescan/activities/MainActivity.java @@ -1,11 +1,9 @@ package uk.co.alt236.btlescan.activities; -import java.util.ArrayList; -import java.util.List; - import uk.co.alt236.bluetoothlelib.device.BluetoothLeDevice; import uk.co.alt236.btlescan.R; import uk.co.alt236.btlescan.adapters.LeDeviceListAdapter; +import uk.co.alt236.btlescan.containers.BluetoothLeDeviceStore; import uk.co.alt236.btlescan.util.BluetoothLeScanner; import uk.co.alt236.btlescan.util.BluetoothUtils; import uk.co.alt236.btlescan.views.RadarView; @@ -30,10 +28,7 @@ public class MainActivity extends ListActivity { private BluetoothUtils mBluetoothUtils; private BluetoothLeScanner mScanner; private LeDeviceListAdapter mLeDeviceListAdapter; - private List mDeviceList; - - - + private BluetoothLeDeviceStore mDeviceStore; private BluetoothAdapter.LeScanCallback mLeScanCallback = new BluetoothAdapter.LeScanCallback() { @Override @@ -44,17 +39,18 @@ public class MainActivity extends ListActivity { runOnUiThread(new Runnable() { @Override public void run() { - mLeDeviceListAdapter.addDevice(deviceLe); + mDeviceStore.addDevice(deviceLe); + mLeDeviceListAdapter.clear(); + mLeDeviceListAdapter.addAll(mDeviceStore.getDeviceList()); mLeDeviceListAdapter.notifyDataSetChanged(); } }); - } }; @Override protected void onListItemClick(ListView l, View v, int position, long id) { - final BluetoothLeDevice device = mLeDeviceListAdapter.getDevice(position); + final BluetoothLeDevice device = mLeDeviceListAdapter.getItem(position); if (device == null) return; @@ -69,8 +65,8 @@ public class MainActivity extends ListActivity { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ButterKnife.inject(this); - mDeviceList = new ArrayList(); + mDeviceStore = new BluetoothLeDeviceStore(); mBluetoothUtils = new BluetoothUtils(this); mScanner = new BluetoothLeScanner(mLeScanCallback, mBluetoothUtils); } @@ -134,8 +130,9 @@ public class MainActivity extends ListActivity { private void startScan(){ final boolean mIsBluetoothOn = mBluetoothUtils.isBluetoothOn(); final boolean mIsBluetoothLePresent = mBluetoothUtils.isBluetoothLeSupported(); + mDeviceStore.clear(); - mLeDeviceListAdapter = new LeDeviceListAdapter(this); + mLeDeviceListAdapter = new LeDeviceListAdapter(this, mDeviceStore.getDeviceList()); setListAdapter(mLeDeviceListAdapter); mBluetoothUtils.askUserToEnableBluetoothIfNeeded(); diff --git a/sample_app/src/uk/co/alt236/btlescan/adapters/LeDeviceListAdapter.java b/sample_app/src/uk/co/alt236/btlescan/adapters/LeDeviceListAdapter.java index 47b6614..4dbc5cd 100644 --- a/sample_app/src/uk/co/alt236/btlescan/adapters/LeDeviceListAdapter.java +++ b/sample_app/src/uk/co/alt236/btlescan/adapters/LeDeviceListAdapter.java @@ -1,60 +1,38 @@ package uk.co.alt236.btlescan.adapters; -import java.text.DecimalFormat; -import java.util.ArrayList; import java.util.List; import uk.co.alt236.bluetoothlelib.device.BluetoothLeDevice; import uk.co.alt236.bluetoothlelib.device.IBeaconDevice; import uk.co.alt236.bluetoothlelib.util.IBeaconUtils; import uk.co.alt236.btlescan.R; +import uk.co.alt236.btlescan.util.Constants; import android.app.Activity; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; -import android.widget.BaseAdapter; +import android.widget.ArrayAdapter; import android.widget.ImageView; import android.widget.TextView; // Adapter for holding devices found through scanning. -public class LeDeviceListAdapter extends BaseAdapter { - private static final DecimalFormat DOUBLE_TWO_DIGIT_ACCURACY = new DecimalFormat("#.##"); - private static final String TIME_FORMAT = "yyyy-MM-dd hh:mm:ss"; - - private final List mLeDevices; +public class LeDeviceListAdapter extends ArrayAdapter { private final LayoutInflater mInflator; + private final Activity mActivity; - public LeDeviceListAdapter(Activity activity) { - super(); - mLeDevices = new ArrayList(); + public LeDeviceListAdapter(Activity activity, List list) { + super(activity, R.layout.list_item_device, list); mInflator = activity.getLayoutInflater(); + mActivity = activity; } - public void addDevice(BluetoothLeDevice device) { - final int position = mLeDevices.indexOf(device); - if(position == -1){ - mLeDevices.add(device); - } else { - mLeDevices.set(position, device); - } - } - - public BluetoothLeDevice getDevice(int position) { - return mLeDevices.get(position); - } - - public void clear() { - mLeDevices.clear(); - } - - @Override - public int getCount() { - return mLeDevices.size(); - } - - @Override - public Object getItem(int i) { - return mLeDevices.get(i); - } +// public void addDevice(BluetoothLeDevice device) { +// final int position = mLeDevices.indexOf(device); +// if(position == -1){ +// mLeDevices.add(device); +// } else { +// mLeDevices.set(position, device); +// } +// } @Override public long getItemId(int i) { @@ -85,7 +63,7 @@ public class LeDeviceListAdapter extends BaseAdapter { viewHolder = (ViewHolder) view.getTag(); } - final BluetoothLeDevice device = mLeDevices.get(i); + final BluetoothLeDevice device = getItem(i); final String deviceName = device.getName(); final double rssi = device.getRssi(); @@ -96,11 +74,8 @@ public class LeDeviceListAdapter extends BaseAdapter { } if (IBeaconUtils.isThisAnIBeacon(device)){ - // Alternatively you can just call - // IBeaconManufacturerData data = new IBeaconManufacturerData(device); - final IBeaconDevice iBeacon = new IBeaconDevice(device); - final double accuracy = iBeacon.getAccuracy(); + final String accuracy = Constants.DOUBLE_TWO_DIGIT_ACCURACY.format(iBeacon.getAccuracy()); viewHolder.deviceIcon.setImageResource(R.drawable.ic_device_ibeacon); viewHolder.ibeaconSection.setVisibility(View.VISIBLE); @@ -108,17 +83,22 @@ public class LeDeviceListAdapter extends BaseAdapter { viewHolder.ibeaconMinor.setText(String.valueOf(iBeacon.getMinor())); viewHolder.ibeaconTxPower.setText(String.valueOf(iBeacon.getCalibratedTxPower())); viewHolder.ibeaconUUID.setText(iBeacon.getUUID()); - viewHolder.ibeaconDistance.setText(DOUBLE_TWO_DIGIT_ACCURACY.format(accuracy) + "m"); + viewHolder.ibeaconDistance.setText( + mActivity.getString(R.string.formatter_meters, accuracy)); viewHolder.ibeaconDistanceDescriptor.setText(iBeacon.getDistanceDescriptor().toString()); } else { viewHolder.deviceIcon.setImageResource(R.drawable.ic_bluetooth); viewHolder.ibeaconSection.setVisibility(View.GONE); } + final String rssiString = mActivity.getString(R.string.formatter_db, String.valueOf(rssi)); + final String runningAverageRssiString = mActivity.getString(R.string.formatter_db, String.valueOf(device.getRunningAverageRssi())); + viewHolder.deviceLastUpdated.setText( - android.text.format.DateFormat.format(TIME_FORMAT, new java.util.Date(device.getTimestamp()))); + android.text.format.DateFormat.format( + Constants.TIME_FORMAT, new java.util.Date(device.getTimestamp()))); viewHolder.deviceAddress.setText(device.getAddress()); - viewHolder.deviceRssi.setText(String.valueOf(rssi) + "db"); + viewHolder.deviceRssi.setText(rssiString + " / " + runningAverageRssiString); return view; } diff --git a/sample_app/src/uk/co/alt236/btlescan/util/BluetoothLeDeviceStore.java b/sample_app/src/uk/co/alt236/btlescan/containers/BluetoothLeDeviceStore.java similarity index 84% rename from sample_app/src/uk/co/alt236/btlescan/util/BluetoothLeDeviceStore.java rename to sample_app/src/uk/co/alt236/btlescan/containers/BluetoothLeDeviceStore.java index 4d09fc0..188f8da 100644 --- a/sample_app/src/uk/co/alt236/btlescan/util/BluetoothLeDeviceStore.java +++ b/sample_app/src/uk/co/alt236/btlescan/containers/BluetoothLeDeviceStore.java @@ -1,4 +1,4 @@ -package uk.co.alt236.btlescan.util; +package uk.co.alt236.btlescan.containers; import java.util.ArrayList; import java.util.Collections; @@ -12,23 +12,26 @@ import uk.co.alt236.bluetoothlelib.device.BluetoothLeDevice; public class BluetoothLeDeviceStore { private final Map mDeviceMap; + public BluetoothLeDeviceStore(){ mDeviceMap = new HashMap(); } public void addDevice(BluetoothLeDevice device){ if(mDeviceMap.containsKey(device.getAddress())){ - + mDeviceMap.get(device.getAddress()).updateRssiReading(device.getTimestamp(), device.getRssi()); } else { mDeviceMap.put(device.getAddress(), device); } } + public void clear(){ + mDeviceMap.clear(); + } public List getDeviceList(){ final List methodResult = new ArrayList(mDeviceMap.values()); - Collections.sort(methodResult, new Comparator() { @Override @@ -37,7 +40,6 @@ public class BluetoothLeDeviceStore { } }); - return methodResult; } } diff --git a/sample_app/src/uk/co/alt236/btlescan/util/Constants.java b/sample_app/src/uk/co/alt236/btlescan/util/Constants.java new file mode 100644 index 0000000..87376a8 --- /dev/null +++ b/sample_app/src/uk/co/alt236/btlescan/util/Constants.java @@ -0,0 +1,8 @@ +package uk.co.alt236.btlescan.util; + +import java.text.DecimalFormat; + +public class Constants { + public static final DecimalFormat DOUBLE_TWO_DIGIT_ACCURACY = new DecimalFormat("#.##"); + public static final String TIME_FORMAT = "yyyy-MM-dd HH:mm:ss"; +}