diff --git a/sample_app/res/values/strings.xml b/sample_app/res/values/strings.xml index 73f138e..4c6cd43 100644 --- a/sample_app/res/values/strings.xml +++ b/sample_app/res/values/strings.xml @@ -41,5 +41,8 @@ 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 + Bluetooth LE Scan Results (%s) + Please find attached the scan results. + Please select your email client: \ No newline at end of file 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 dabbf0a..c41c439 100644 --- a/sample_app/src/uk/co/alt236/btlescan/containers/BluetoothLeDeviceStore.java +++ b/sample_app/src/uk/co/alt236/btlescan/containers/BluetoothLeDeviceStore.java @@ -15,7 +15,9 @@ import uk.co.alt236.bluetoothlelib.device.BluetoothLeDevice; import uk.co.alt236.bluetoothlelib.device.IBeaconDevice; 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.CsvWriterHelper; +import uk.co.alt236.btlescan.util.TimeFormatter; import uk.co.alt236.easycursor.objectcursor.EasyObjectCursor; import android.content.Context; import android.content.Intent; @@ -99,16 +101,15 @@ public class BluetoothLeDeviceStore { sb.append(CsvWriterHelper.addStuff("minor")); sb.append(CsvWriterHelper.addStuff("txPower")); sb.append(CsvWriterHelper.addStuff("distance")); - sb.append(CsvWriterHelper.addStuff("distance")); sb.append(CsvWriterHelper.addStuff("accuracy")); 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(TimeFormatter.getIsoDateTime(device.getFirstTimestamp()))); sb.append(CsvWriterHelper.addStuff(device.getFirstRssi())); - sb.append(CsvWriterHelper.addStuff(device.getTimestamp())); + sb.append(CsvWriterHelper.addStuff(TimeFormatter.getIsoDateTime(device.getTimestamp()))); sb.append(CsvWriterHelper.addStuff(device.getRssi())); sb.append(CsvWriterHelper.addStuff(ByteUtils.byteArrayToHexString(device.getScanRecord()))); final boolean isIBeacon = IBeaconUtils.isThisAnIBeacon(device); @@ -152,22 +153,27 @@ public class BluetoothLeDeviceStore { public void shareDataAsEmail(Context context){ - String to = null; - String subject = "Bluetooth LE Scan Results"; - String message = "Please find attached the scan results."; + final long timeInMillis = System.currentTimeMillis(); + + final String to = null; + final String subject = context.getString( + R.string.exporter_email_subject, + TimeFormatter.getIsoDateTime(timeInMillis)); + + final String message = context.getString(R.string.exporter_email_body); 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); + final File outputFile = File.createTempFile("bluetooth_le_" + timeInMillis, ".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:")); + context.startActivity(Intent.createChooser(i, context.getString(R.string.exporter_email_picker_text))); } catch (IOException e) { e.printStackTrace(); diff --git a/sample_app/src/uk/co/alt236/btlescan/util/TimeFormatter.java b/sample_app/src/uk/co/alt236/btlescan/util/TimeFormatter.java new file mode 100644 index 0000000..8c7f925 --- /dev/null +++ b/sample_app/src/uk/co/alt236/btlescan/util/TimeFormatter.java @@ -0,0 +1,18 @@ +package uk.co.alt236.btlescan.util; + +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Locale; + +public class TimeFormatter { + private final static String ISO_FORMAT = "yyyy-MM-dd'T'HH:mm:ss.SSS zzz"; + private final static SimpleDateFormat ISO_FORMATTER = new UtcDateFormatter(ISO_FORMAT, Locale.US); + + public static String getIsoDateTime(Date date){ + return ISO_FORMATTER.format(date); + } + + public static String getIsoDateTime(long millis){ + return getIsoDateTime(new Date(millis)); + } +} diff --git a/sample_app/src/uk/co/alt236/btlescan/util/UtcDateFormatter.java b/sample_app/src/uk/co/alt236/btlescan/util/UtcDateFormatter.java new file mode 100644 index 0000000..f0dca69 --- /dev/null +++ b/sample_app/src/uk/co/alt236/btlescan/util/UtcDateFormatter.java @@ -0,0 +1,72 @@ +/******************************************************************************* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * GenieConnect Ltd. ("COMPANY") CONFIDENTIAL + * Unpublished Copyright (c) 2010-2013 GenieConnect Ltd., All Rights Reserved. + * + * NOTICE: + * All information contained herein is, and remains the property of COMPANY. + * The intellectual and technical concepts contained herein are proprietary to + * COMPANY and may be covered by U.S. and Foreign Patents, patents in process, and + * are protected by trade secret or copyright law. Dissemination of this + * information or reproduction of this material is strictly forbidden unless prior + * written permission is obtained from COMPANY. Access to the source code + * contained herein is hereby forbidden to anyone except current COMPANY employees, + * managers or contractors who have executed Confidentiality and Non-disclosure + * agreements explicitly covering such access. + * + * The copyright notice above does not evidence any actual or intended publication + * or disclosure of this source code, which includes information that is + * confidential and/or proprietary, and is a trade secret, of COMPANY. + * + * ANY REPRODUCTION, MODIFICATION, DISTRIBUTION, PUBLIC PERFORMANCE, OR PUBLIC + * DISPLAY OF OR THROUGH USE OF THIS SOURCE CODE WITHOUT THE EXPRESS WRITTEN + * CONSENT OF COMPANY IS STRICTLY PROHIBITED, AND IN VIOLATION OF APPLICABLE LAWS + * AND INTERNATIONAL TREATIES. THE RECEIPT OR POSSESSION OF THIS SOURCE CODE + * AND/OR RELATED INFORMATION DOES NOT CONVEY OR IMPLY ANY RIGHTS TO REPRODUCE, + * DISCLOSE OR DISTRIBUTE ITS CONTENTS, OR TO MANUFACTURE, USE, OR SELL ANYTHING + * THAT IT MAY DESCRIBE, IN WHOLE OR IN PART. + ******************************************************************************/ +package uk.co.alt236.btlescan.util; + +import java.text.DateFormatSymbols; +import java.util.Locale; +import java.util.TimeZone; + +import android.annotation.SuppressLint; + +public class UtcDateFormatter extends java.text.SimpleDateFormat{ + private static final long serialVersionUID = 1L; + + private static final String TIME_ZONE_STRING = "UTC"; + private static final TimeZone TIME_ZONE_UTC = TimeZone.getTimeZone(TIME_ZONE_STRING); + + @SuppressLint("SimpleDateFormat") + public UtcDateFormatter(String template){ + super(template); + super.setTimeZone(TIME_ZONE_UTC); + } + + @SuppressLint("SimpleDateFormat") + public UtcDateFormatter(String template, DateFormatSymbols symbols){ + super(template, symbols); + super.setTimeZone(TIME_ZONE_UTC); + } + + public UtcDateFormatter(String template, Locale locale){ + super(template, locale); + super.setTimeZone(TIME_ZONE_UTC); + } + + /* + * This function will throw an UnsupportedOperationException. + * You are not be able to change the TimeZone of this object + * + * (non-Javadoc) + * @see java.text.DateFormat#setTimeZone(java.util.TimeZone) + */ + @Override + public void setTimeZone(TimeZone timezone){ + throw new UnsupportedOperationException("This SimpleDateFormat can only be in " + TIME_ZONE_STRING); + } +}