diff --git a/sample_app/res/drawable-hdpi/ic_action_share.png b/sample_app/res/drawable-hdpi/ic_action_share.png new file mode 100644 index 0000000..2b267df Binary files /dev/null and b/sample_app/res/drawable-hdpi/ic_action_share.png differ diff --git a/sample_app/res/drawable-mdpi/ic_action_share.png b/sample_app/res/drawable-mdpi/ic_action_share.png new file mode 100644 index 0000000..5dba2eb Binary files /dev/null and b/sample_app/res/drawable-mdpi/ic_action_share.png differ diff --git a/sample_app/res/drawable-xhdpi/ic_action_share.png b/sample_app/res/drawable-xhdpi/ic_action_share.png new file mode 100644 index 0000000..0ae218e Binary files /dev/null and b/sample_app/res/drawable-xhdpi/ic_action_share.png differ diff --git a/sample_app/res/drawable-xxhdpi/ic_action_share.png b/sample_app/res/drawable-xxhdpi/ic_action_share.png new file mode 100644 index 0000000..ea9a8be Binary files /dev/null and b/sample_app/res/drawable-xxhdpi/ic_action_share.png differ diff --git a/sample_app/res/layout/activity_main.xml b/sample_app/res/layout/activity_main.xml index 49847ae..e1754f2 100644 --- a/sample_app/res/layout/activity_main.xml +++ b/sample_app/res/layout/activity_main.xml @@ -63,15 +63,37 @@ android:layout_height="1dp" android:background="@android:color/holo_blue_dark" /> - + + + + + + + - - - + \ No newline at end of file diff --git a/sample_app/res/menu/main.xml b/sample_app/res/menu/main.xml index 7b3160b..c1afc17 100644 --- a/sample_app/res/menu/main.xml +++ b/sample_app/res/menu/main.xml @@ -32,9 +32,15 @@ android:showAsAction="ifRoom|withText" android:title="@string/menu_stop"/> + \ No newline at end of file diff --git a/sample_app/res/values/strings.xml b/sample_app/res/values/strings.xml index 79a171e..73f138e 100644 --- a/sample_app/res/values/strings.xml +++ b/sample_app/res/values/strings.xml @@ -17,13 +17,17 @@ %sm %sdb + Items: %s - About + About Connect Disconnect Scan Stop + Share + + Data: @@ -36,8 +40,6 @@ State: TX Power: UUID: - - - This is a sample application using the Bluetooth LE Library.\n\nGithub: https://github.com/alt236/Bluetooth-LE-Library---Android\n\nCopyright: Alexandros Schillings + This is a sample application using the Bluetooth LE Library.\n\nGithub: https://github.com/alt236/Bluetooth-LE-Library---Android\n\nCopyright: Alexandros Schillings \ No newline at end of file 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 b17e5cb..3e0a043 100644 --- a/sample_app/src/uk/co/alt236/btlescan/activities/MainActivity.java +++ b/sample_app/src/uk/co/alt236/btlescan/activities/MainActivity.java @@ -27,6 +27,7 @@ import butterknife.InjectView; public class MainActivity extends ListActivity { @InjectView(R.id.tvBluetoothLe) TextView mTvBluetoothLeStatus; @InjectView(R.id.tvBluetoothStatus) TextView mTvBluetoothStatus; + @InjectView(R.id.tvItemCount) TextView mTvItemCount; private BluetoothUtils mBluetoothUtils; private BluetoothLeScanner mScanner; @@ -44,13 +45,21 @@ public class MainActivity extends ListActivity { public void run() { mDeviceStore.addDevice(deviceLe); mLeDeviceListAdapter.replaceData(mDeviceStore.getDeviceList()); + updateItemCount(mLeDeviceListAdapter.getCount()); } }); } }; + private void updateItemCount(int count){ + mTvItemCount.setText( + getString( + R.string.formatter_item_count, + String.valueOf(count))); + } + private void displayAboutDialog(){ - // REALLY REALLY LAZY LIKIFIED DIALOG + // REALLY REALLY LAZY LINKIFIED DIALOG final int paddingSizeDp = 5; final float scale = getResources().getDisplayMetrics().density; final int dpAsPixels = (int) (paddingSizeDp * scale + 0.5f); @@ -83,6 +92,7 @@ public class MainActivity extends ListActivity { mDeviceStore = new BluetoothLeDeviceStore(); mBluetoothUtils = new BluetoothUtils(this); mScanner = new BluetoothLeScanner(mLeScanCallback, mBluetoothUtils); + updateItemCount(0); } @Override @@ -97,6 +107,13 @@ public class MainActivity extends ListActivity { menu.findItem(R.id.menu_scan).setVisible(false); menu.findItem(R.id.menu_refresh).setActionView(R.layout.actionbar_progress_indeterminate); } + + if(getListView().getCount() > 0){ + menu.findItem(R.id.menu_share).setVisible(true); + } else { + menu.findItem(R.id.menu_share).setVisible(false); + } + return true; } @@ -125,6 +142,8 @@ public class MainActivity extends ListActivity { case R.id.menu_about: displayAboutDialog(); break; + case R.id.menu_share: + mDeviceStore.shareDataAsEmail(this); } return true; } @@ -160,6 +179,7 @@ public class MainActivity extends ListActivity { final boolean mIsBluetoothOn = mBluetoothUtils.isBluetoothOn(); final boolean mIsBluetoothLePresent = mBluetoothUtils.isBluetoothLeSupported(); mDeviceStore.clear(); + updateItemCount(0); mLeDeviceListAdapter = new LeDeviceListAdapter(this, mDeviceStore.getDeviceList()); setListAdapter(mLeDeviceListAdapter); diff --git a/sample_app/src/uk/co/alt236/btlescan/containers/BluetoothLeDeviceStore.java b/sample_app/src/uk/co/alt236/btlescan/containers/BluetoothLeDeviceStore.java index 188f8da..87379a7 100644 --- a/sample_app/src/uk/co/alt236/btlescan/containers/BluetoothLeDeviceStore.java +++ b/sample_app/src/uk/co/alt236/btlescan/containers/BluetoothLeDeviceStore.java @@ -1,5 +1,8 @@ package uk.co.alt236.btlescan.containers; +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; @@ -8,6 +11,11 @@ import java.util.List; import java.util.Map; import uk.co.alt236.bluetoothlelib.device.BluetoothLeDevice; +import uk.co.alt236.bluetoothlelib.util.ByteUtils; +import uk.co.alt236.btlescan.util.CsvWriterHelper; +import android.content.Context; +import android.content.Intent; +import android.net.Uri; public class BluetoothLeDeviceStore { private final Map mDeviceMap; @@ -29,6 +37,26 @@ public class BluetoothLeDeviceStore { mDeviceMap.clear(); } + + private FileWriter generateFile(File file, String contents){ + FileWriter writer = null; + try { + writer = new FileWriter(file); + writer.append(contents); + writer.flush(); + + } catch (IOException e) { + e.printStackTrace(); + }finally{ + try { + writer.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + return writer; + } + public List getDeviceList(){ final List methodResult = new ArrayList(mDeviceMap.values()); @@ -42,4 +70,55 @@ public class BluetoothLeDeviceStore { return methodResult; } + + + private String getListAsCsv(){ + final List list = getDeviceList(); + final StringBuilder sb = new StringBuilder(); + sb.append(CsvWriterHelper.addStuff("mac")); + sb.append(CsvWriterHelper.addStuff("name")); + sb.append(CsvWriterHelper.addStuff("firstTimestamp")); + sb.append(CsvWriterHelper.addStuff("firstRssi")); + sb.append(CsvWriterHelper.addStuff("currentTimestamp")); + sb.append(CsvWriterHelper.addStuff("currentRssi")); + sb.append(CsvWriterHelper.addStuff("adRecord")); + sb.append('\n'); + + for(BluetoothLeDevice device : list){ + sb.append(CsvWriterHelper.addStuff(device.getAddress())); + sb.append(CsvWriterHelper.addStuff(device.getName())); + sb.append(CsvWriterHelper.addStuff(device.getFirstTimestamp())); + sb.append(CsvWriterHelper.addStuff(device.getFirstRssi())); + sb.append(CsvWriterHelper.addStuff(device.getTimestamp())); + sb.append(CsvWriterHelper.addStuff(device.getRssi())); + sb.append(CsvWriterHelper.addStuff(ByteUtils.byteArrayToHexString(device.getScanRecord()))); + sb.append('\n'); + } + + return sb.toString(); + } + + + public void shareDataAsEmail(Context context){ + String to = null; + String subject = "Bluetooth LE Scan Results"; + String message = "Please find attached the scan results."; + + final Intent i = new Intent(Intent.ACTION_SEND); + i.setType("plain/text"); + try { + final File outputDir = context.getCacheDir(); + final File outputFile = File.createTempFile("export_tmp", ".csv", outputDir); + outputFile.setReadable(true, false); + generateFile(outputFile, getListAsCsv()); + i.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(outputFile)); + i.putExtra(Intent.EXTRA_EMAIL, new String[] { to }); + i.putExtra(Intent.EXTRA_SUBJECT, subject); + i.putExtra(Intent.EXTRA_TEXT, message); + context.startActivity(Intent.createChooser(i, "Please select your email client:")); + + } catch (IOException e) { + e.printStackTrace(); + } + } } diff --git a/sample_app/src/uk/co/alt236/btlescan/util/CsvWriterHelper.java b/sample_app/src/uk/co/alt236/btlescan/util/CsvWriterHelper.java new file mode 100644 index 0000000..b827126 --- /dev/null +++ b/sample_app/src/uk/co/alt236/btlescan/util/CsvWriterHelper.java @@ -0,0 +1,23 @@ +package uk.co.alt236.btlescan.util; + +public class CsvWriterHelper { + private static final String QUOTE = "\""; + public static String addStuff(Integer text){ + return QUOTE + text + QUOTE + ","; + } + + public static String addStuff(Long text){ + return QUOTE + text + QUOTE + ","; + } + + public static String addStuff(boolean value){ + return QUOTE + value + QUOTE + ","; + } + + public static String addStuff(String text){ + if(text == null){text = "";} + text = text.replace(QUOTE, "'"); + + return QUOTE + text.trim() + QUOTE + ","; + } +}