From ec33fd7618ecb326e2b999706ebe57b2822bdf70 Mon Sep 17 00:00:00 2001 From: Alexandros Schillings Date: Wed, 24 Aug 2016 14:39:26 +0100 Subject: [PATCH 01/19] Materialized the UI, added runtme permissions support, now compiling against 24 --- .idea/compiler.xml | 2 +- .idea/encodings.xml | 6 ++ .idea/gradle.xml | 11 ++- .idea/inspectionProfiles/Project_Default.xml | 91 ++++++++++++++++++- .idea/misc.xml | 21 +---- .idea/runConfigurations.xml | 12 +++ .idea/runConfigurations/Run_Android_Tests.xml | 27 ------ .idea/runConfigurations/Run_JUnit_Tests.xml | 23 ----- .idea/runConfigurations/Run_Sample_App.xml | 26 ------ Bluetooth-LE-Library---Android.iml | 19 ++++ bluetooth-le-library.iml | 2 +- build.gradle | 8 +- gradle/wrapper/gradle-wrapper.properties | 4 +- library/library.iml | 48 ++++++---- sample_app/build.gradle | 3 +- sample_app/sample_app.iml | 80 +++++++++++----- sample_app/src/main/AndroidManifest.xml | 1 + .../activities/DeviceDetailsActivity.java | 13 ++- .../btlescan/activities/DialogFactory.java | 47 ++++++++++ .../btlescan/activities/MainActivity.java | 62 ++++++------- .../res/layout/activity_gatt_services.xml | 4 +- .../src/main/res/layout/activity_main.xml | 6 +- .../src/main/res/layout/dialog_textview.xml | 12 +++ .../main/res/layout/list_item_view_header.xml | 4 +- sample_app/src/main/res/values-v11/styles.xml | 11 --- sample_app/src/main/res/values-v14/styles.xml | 12 --- sample_app/src/main/res/values-v21/styles.xml | 11 +++ sample_app/src/main/res/values/colors.xml | 6 ++ sample_app/src/main/res/values/strings.xml | 3 + sample_app/src/main/res/values/styles.xml | 19 +--- 30 files changed, 360 insertions(+), 234 deletions(-) create mode 100644 .idea/encodings.xml create mode 100644 .idea/runConfigurations.xml delete mode 100644 .idea/runConfigurations/Run_Android_Tests.xml delete mode 100644 .idea/runConfigurations/Run_JUnit_Tests.xml delete mode 100644 .idea/runConfigurations/Run_Sample_App.xml create mode 100644 Bluetooth-LE-Library---Android.iml create mode 100644 sample_app/src/main/java/uk/co/alt236/btlescan/activities/DialogFactory.java create mode 100644 sample_app/src/main/res/layout/dialog_textview.xml delete mode 100644 sample_app/src/main/res/values-v11/styles.xml delete mode 100644 sample_app/src/main/res/values-v14/styles.xml create mode 100644 sample_app/src/main/res/values-v21/styles.xml diff --git a/.idea/compiler.xml b/.idea/compiler.xml index 9a8b7e5..96cc43e 100644 --- a/.idea/compiler.xml +++ b/.idea/compiler.xml @@ -1,7 +1,6 @@ - \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml index c1b4dde..1d9d626 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -1,8 +1,5 @@ - - - @@ -13,26 +10,10 @@ - + - - - - - Android API 18 Platform - - - - - - - \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 0000000..7f68460 --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations/Run_Android_Tests.xml b/.idea/runConfigurations/Run_Android_Tests.xml deleted file mode 100644 index 1f32fb7..0000000 --- a/.idea/runConfigurations/Run_Android_Tests.xml +++ /dev/null @@ -1,27 +0,0 @@ - - - - - \ No newline at end of file diff --git a/.idea/runConfigurations/Run_JUnit_Tests.xml b/.idea/runConfigurations/Run_JUnit_Tests.xml deleted file mode 100644 index 09ab733..0000000 --- a/.idea/runConfigurations/Run_JUnit_Tests.xml +++ /dev/null @@ -1,23 +0,0 @@ - - - - - - - - - - \ No newline at end of file diff --git a/.idea/runConfigurations/Run_Sample_App.xml b/.idea/runConfigurations/Run_Sample_App.xml deleted file mode 100644 index 8873b95..0000000 --- a/.idea/runConfigurations/Run_Sample_App.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - \ No newline at end of file diff --git a/Bluetooth-LE-Library---Android.iml b/Bluetooth-LE-Library---Android.iml new file mode 100644 index 0000000..dcc5098 --- /dev/null +++ b/Bluetooth-LE-Library---Android.iml @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/bluetooth-le-library.iml b/bluetooth-le-library.iml index cf2c73f..f36911a 100644 --- a/bluetooth-le-library.iml +++ b/bluetooth-le-library.iml @@ -8,7 +8,7 @@ - + diff --git a/build.gradle b/build.gradle index 327b2ba..1865bee 100644 --- a/build.gradle +++ b/build.gradle @@ -1,16 +1,16 @@ // Top-level build file where you can add configuration options common to all sub-projects/modules. -ext.compileSdkVersion = 22 -ext.buildToolsVersion = "22.0.1" +ext.compileSdkVersion = 24 +ext.buildToolsVersion = "24.0.1" ext.minSdkVersion = 18 -ext.targetSdkVersion = 22 +ext.targetSdkVersion = 24 buildscript { repositories { jcenter() } dependencies { - classpath 'com.android.tools.build:gradle:1.2.3' + classpath 'com.android.tools.build:gradle:2.1.3' } } diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 0c71e76..edae9ca 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Wed Apr 10 15:27:10 PDT 2013 +#Wed Aug 24 14:15:35 BST 2016 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-2.2.1-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-all.zip diff --git a/library/library.iml b/library/library.iml index 7656b88..eccbfd6 100644 --- a/library/library.iml +++ b/library/library.iml @@ -12,19 +12,19 @@ - + @@ -34,7 +34,13 @@ - + + + + + + + @@ -42,6 +48,7 @@ + @@ -49,6 +56,7 @@ + @@ -56,6 +64,7 @@ + @@ -63,32 +72,35 @@ + + + + + + + + + + - - - - - - + + - - - - + + - + - diff --git a/sample_app/build.gradle b/sample_app/build.gradle index 38e6eb0..f2f4905 100644 --- a/sample_app/build.gradle +++ b/sample_app/build.gradle @@ -17,8 +17,9 @@ repositories { dependencies { compile 'com.jakewharton:butterknife:7.0.1' - compile 'com.android.support:appcompat-v7:22.2.0' + compile 'com.android.support:appcompat-v7:24.2.0' compile 'com.commonsware.cwac:merge:1.1.0' + compile 'com.anthonycr.grant:permissions:1.0' compile fileTree(include: ['*.jar'], dir: 'libs') compile project(':library') } diff --git a/sample_app/sample_app.iml b/sample_app/sample_app.iml index 756895c..a26e01b 100644 --- a/sample_app/sample_app.iml +++ b/sample_app/sample_app.iml @@ -12,9 +12,9 @@ - + @@ -33,7 +33,13 @@ - + + + + + + + @@ -41,6 +47,7 @@ + @@ -48,6 +55,7 @@ + @@ -55,6 +63,15 @@ + + + + + + + + + @@ -62,41 +79,60 @@ + + - - - - - + + + + + + + + + + - - - - + + + + + + - - + + + + + - + - + + + + + + + + + + + - - - - + \ No newline at end of file diff --git a/sample_app/src/main/AndroidManifest.xml b/sample_app/src/main/AndroidManifest.xml index 7546b22..d67bb8f 100644 --- a/sample_app/src/main/AndroidManifest.xml +++ b/sample_app/src/main/AndroidManifest.xml @@ -5,6 +5,7 @@ + 0){ + for (final BluetoothService service : device.getBluetoothDeviceKnownSupportedServices()) { + if (sb.length() > 0) { sb.append(", "); } diff --git a/sample_app/src/main/java/uk/co/alt236/btlescan/activities/DialogFactory.java b/sample_app/src/main/java/uk/co/alt236/btlescan/activities/DialogFactory.java new file mode 100644 index 0000000..4ffb6f8 --- /dev/null +++ b/sample_app/src/main/java/uk/co/alt236/btlescan/activities/DialogFactory.java @@ -0,0 +1,47 @@ +package uk.co.alt236.btlescan.activities; + +import android.app.Activity; +import android.app.Dialog; +import android.content.Context; +import android.content.DialogInterface; +import android.support.v7.app.AlertDialog; +import android.text.SpannableString; +import android.text.method.LinkMovementMethod; +import android.text.util.Linkify; +import android.view.LayoutInflater; +import android.view.View; +import android.widget.TextView; + +import uk.co.alt236.btlescan.R; + +/*package*/ final class DialogFactory { + + private DialogFactory() { + // NOOP + } + + public static Dialog createAboutDialog(final Context context) { + final View view = LayoutInflater.from(context).inflate(R.layout.dialog_textview, null); + final TextView textView = (TextView) view.findViewById(R.id.text); + + final SpannableString text = new SpannableString(context.getString(R.string.about_dialog_text)); + + textView.setText(text); + textView.setAutoLinkMask(Activity.RESULT_OK); + textView.setMovementMethod(LinkMovementMethod.getInstance()); + + Linkify.addLinks(text, Linkify.ALL); + + final DialogInterface.OnClickListener listener = new DialogInterface.OnClickListener() { + public void onClick(final DialogInterface dialog, final int id) { + } + }; + + return new AlertDialog.Builder(context) + .setTitle(R.string.menu_about) + .setCancelable(false) + .setPositiveButton(android.R.string.ok, listener) + .setView(view) + .create(); + } +} diff --git a/sample_app/src/main/java/uk/co/alt236/btlescan/activities/MainActivity.java b/sample_app/src/main/java/uk/co/alt236/btlescan/activities/MainActivity.java index 153f522..659c578 100644 --- a/sample_app/src/main/java/uk/co/alt236/btlescan/activities/MainActivity.java +++ b/sample_app/src/main/java/uk/co/alt236/btlescan/activities/MainActivity.java @@ -1,21 +1,22 @@ package uk.co.alt236.btlescan.activities; -import android.app.AlertDialog; +import android.Manifest; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; -import android.content.DialogInterface; import android.content.Intent; import android.os.Bundle; +import android.support.annotation.NonNull; import android.support.v7.app.AppCompatActivity; -import android.text.SpannableString; -import android.text.method.LinkMovementMethod; -import android.text.util.Linkify; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.widget.AdapterView; import android.widget.ListView; import android.widget.TextView; +import android.widget.Toast; + +import com.anthonycr.grant.PermissionsManager; +import com.anthonycr.grant.PermissionsResultAction; import butterknife.Bind; import butterknife.ButterKnife; @@ -62,32 +63,6 @@ public class MainActivity extends AppCompatActivity implements AdapterView.OnIte } }; - private void displayAboutDialog() { - // REALLY REALLY LAZY LINKIFIED DIALOG - final int paddingSizeDp = 5; - final float scale = getResources().getDisplayMetrics().density; - final int dpAsPixels = (int) (paddingSizeDp * scale + 0.5f); - - final TextView textView = new TextView(this); - final SpannableString text = new SpannableString(getString(R.string.about_dialog_text)); - - textView.setText(text); - textView.setAutoLinkMask(RESULT_OK); - textView.setMovementMethod(LinkMovementMethod.getInstance()); - textView.setPadding(dpAsPixels, dpAsPixels, dpAsPixels, dpAsPixels); - - Linkify.addLinks(text, Linkify.ALL); - new AlertDialog.Builder(this) - .setTitle(R.string.menu_about) - .setCancelable(false) - .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { - public void onClick(final DialogInterface dialog, final int id) { - } - }) - .setView(textView) - .show(); - } - @Override protected void onCreate(final Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -138,14 +113,29 @@ public class MainActivity extends AppCompatActivity implements AdapterView.OnIte public boolean onOptionsItemSelected(final MenuItem item) { switch (item.getItemId()) { case R.id.menu_scan: - startScan(); + PermissionsManager.getInstance().requestPermissionsIfNecessaryForResult(this, + new String[]{Manifest.permission.ACCESS_COARSE_LOCATION}, new PermissionsResultAction() { + + @Override + public void onGranted() { + startScan(); + } + + @Override + public void onDenied(String permission) { + Toast.makeText(MainActivity.this, + R.string.permission_not_granted_coarse_location, + Toast.LENGTH_SHORT) + .show(); + } + }); break; case R.id.menu_stop: mScanner.scanLeDevice(-1, false); invalidateOptionsMenu(); break; case R.id.menu_about: - displayAboutDialog(); + DialogFactory.createAboutDialog(this).show(); break; case R.id.menu_share: mDeviceStore.shareDataAsEmail(this); @@ -203,4 +193,10 @@ public class MainActivity extends AppCompatActivity implements AdapterView.OnIte String.valueOf(count))); } + @Override + public void onRequestPermissionsResult(int requestCode, + @NonNull String[] permissions, + @NonNull int[] grantResults) { + PermissionsManager.getInstance().notifyPermissionsChange(permissions, grantResults); + } } diff --git a/sample_app/src/main/res/layout/activity_gatt_services.xml b/sample_app/src/main/res/layout/activity_gatt_services.xml index af806fb..15d2827 100644 --- a/sample_app/src/main/res/layout/activity_gatt_services.xml +++ b/sample_app/src/main/res/layout/activity_gatt_services.xml @@ -57,7 +57,7 @@ android:layout_width="match_parent" android:layout_height="1dp" android:layout_below="@id/deviceInformation" - android:background="@android:color/holo_blue_dark"/> + android:background="@color/colorSeparator" /> + android:background="@color/colorSeparator" /> + tools:context=".activities.MainActivity"> + android:background="@color/colorSeparator" /> + android:background="@color/colorSeparator" /> + + + + \ No newline at end of file diff --git a/sample_app/src/main/res/layout/list_item_view_header.xml b/sample_app/src/main/res/layout/list_item_view_header.xml index e92024e..1958014 100644 --- a/sample_app/src/main/res/layout/list_item_view_header.xml +++ b/sample_app/src/main/res/layout/list_item_view_header.xml @@ -11,13 +11,13 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:textAllCaps="true" - android:textColor="@android:color/holo_blue_dark" + android:textColor="@color/colorSeparator" android:textSize="14sp" android:textStyle="bold"/> + android:background="@color/colorSeparator" /> \ No newline at end of file diff --git a/sample_app/src/main/res/values-v11/styles.xml b/sample_app/src/main/res/values-v11/styles.xml deleted file mode 100644 index c0ef0ed..0000000 --- a/sample_app/src/main/res/values-v11/styles.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - diff --git a/sample_app/src/main/res/values-v14/styles.xml b/sample_app/src/main/res/values-v14/styles.xml deleted file mode 100644 index 664f4f1..0000000 --- a/sample_app/src/main/res/values-v14/styles.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - diff --git a/sample_app/src/main/res/values-v21/styles.xml b/sample_app/src/main/res/values-v21/styles.xml new file mode 100644 index 0000000..7b9a811 --- /dev/null +++ b/sample_app/src/main/res/values-v21/styles.xml @@ -0,0 +1,11 @@ + + + + + \ No newline at end of file diff --git a/sample_app/src/main/res/values/colors.xml b/sample_app/src/main/res/values/colors.xml index c64f146..0065566 100644 --- a/sample_app/src/main/res/values/colors.xml +++ b/sample_app/src/main/res/values/colors.xml @@ -1,3 +1,9 @@ #66e0e0e0 + #0000FF + #4400FF + #F06292 + + + @color/colorAccent diff --git a/sample_app/src/main/res/values/strings.xml b/sample_app/src/main/res/values/strings.xml index 84c3f4f..c0c87be 100644 --- a/sample_app/src/main/res/values/strings.xml +++ b/sample_app/src/main/res/values/strings.xml @@ -21,6 +21,7 @@ %sm %sdb Items: %s + \'%s\' About @@ -72,4 +73,6 @@ UUID: Updated: Descriptor: + + The ACCESS_COARSE_LOCATION permission is needed to receive bluetooth scan results \ No newline at end of file diff --git a/sample_app/src/main/res/values/styles.xml b/sample_app/src/main/res/values/styles.xml index c503b3f..d8baf48 100644 --- a/sample_app/src/main/res/values/styles.xml +++ b/sample_app/src/main/res/values/styles.xml @@ -1,20 +1,11 @@ - - + \ No newline at end of file diff --git a/sample_app/src/main/res/values/colors.xml b/sample_app/src/main/res/values/colors.xml index 0065566..8399d14 100644 --- a/sample_app/src/main/res/values/colors.xml +++ b/sample_app/src/main/res/values/colors.xml @@ -1,9 +1,10 @@ + #0082FC #66e0e0e0 - #0000FF - #4400FF - #F06292 + @color/bluetooth_blue + #0069E3 + #F06292 @color/colorAccent diff --git a/sample_app/src/main/res/values/dimens.xml b/sample_app/src/main/res/values/dimens.xml index 55c1e59..d72218f 100644 --- a/sample_app/src/main/res/values/dimens.xml +++ b/sample_app/src/main/res/values/dimens.xml @@ -4,4 +4,5 @@ 16dp 16dp + 8dp diff --git a/sample_app/src/main/res/values/styles.xml b/sample_app/src/main/res/values/styles.xml index d8baf48..c3f501b 100644 --- a/sample_app/src/main/res/values/styles.xml +++ b/sample_app/src/main/res/values/styles.xml @@ -4,7 +4,7 @@ From 727f2d89532f7efccb3f4401f4803dba752a71ed Mon Sep 17 00:00:00 2001 From: Alexandros Schillings Date: Wed, 31 Aug 2016 18:04:17 +0100 Subject: [PATCH 08/19] Moved the list adapter creation out of DeviceControlActivity --- .../ui/control/DeviceControlActivity.java | 91 +++++------------- .../ui/control/GattDataAdapterFactory.java | 94 +++++++++++++++++++ 2 files changed, 116 insertions(+), 69 deletions(-) create mode 100644 sample_app/src/main/java/uk/co/alt236/btlescan/ui/control/GattDataAdapterFactory.java diff --git a/sample_app/src/main/java/uk/co/alt236/btlescan/ui/control/DeviceControlActivity.java b/sample_app/src/main/java/uk/co/alt236/btlescan/ui/control/DeviceControlActivity.java index 727be6f..4f6d756 100644 --- a/sample_app/src/main/java/uk/co/alt236/btlescan/ui/control/DeviceControlActivity.java +++ b/sample_app/src/main/java/uk/co/alt236/btlescan/ui/control/DeviceControlActivity.java @@ -36,10 +36,7 @@ import android.widget.ExpandableListView; import android.widget.SimpleExpandableListAdapter; import android.widget.TextView; -import java.util.ArrayList; -import java.util.HashMap; import java.util.List; -import java.util.Map; import butterknife.Bind; import butterknife.ButterKnife; @@ -58,8 +55,6 @@ import uk.co.alt236.btlescan.services.BluetoothLeService; public class DeviceControlActivity extends AppCompatActivity { private static final String EXTRA_DEVICE = DeviceControlActivity.class.getName() + ".EXTRA_DEVICE"; private final static String TAG = DeviceControlActivity.class.getSimpleName(); - private static final String LIST_NAME = "NAME"; - private static final String LIST_UUID = "UUID"; @Bind(R.id.gatt_services_list) protected ExpandableListView mGattServicesList; @Bind(R.id.connection_state) @@ -75,7 +70,7 @@ public class DeviceControlActivity extends AppCompatActivity { private Exporter mExporter; private BluetoothGattCharacteristic mNotifyCharacteristic; private BluetoothLeService mBluetoothLeService; - private List> mGattCharacteristics = new ArrayList<>(); + // If a given GATT characteristic is selected, check for supported features. This sample // demonstrates 'Read' and 'Notify' features. See // http://d.android.com/reference/android/bluetooth/BluetoothGatt.html for the complete @@ -83,25 +78,27 @@ public class DeviceControlActivity extends AppCompatActivity { private final ExpandableListView.OnChildClickListener servicesListClickListner = new ExpandableListView.OnChildClickListener() { @Override public boolean onChildClick(final ExpandableListView parent, final View v, final int groupPosition, final int childPosition, final long id) { - if (mGattCharacteristics != null) { - final BluetoothGattCharacteristic characteristic = mGattCharacteristics.get(groupPosition).get(childPosition); - final int charaProp = characteristic.getProperties(); - if ((charaProp | BluetoothGattCharacteristic.PROPERTY_READ) > 0) { - // If there is an active notification on a characteristic, clear - // it first so it doesn't update the data field on the user interface. - if (mNotifyCharacteristic != null) { - mBluetoothLeService.setCharacteristicNotification(mNotifyCharacteristic, false); - mNotifyCharacteristic = null; - } - mBluetoothLeService.readCharacteristic(characteristic); + final GattDataAdapterFactory.GattDataAdapter adapter = + (GattDataAdapterFactory.GattDataAdapter) parent.getAdapter(); + + final BluetoothGattCharacteristic characteristic = + adapter.getBluetoothGattCharacteristic(groupPosition, childPosition); + + final int charaProp = characteristic.getProperties(); + if ((charaProp | BluetoothGattCharacteristic.PROPERTY_READ) > 0) { + // If there is an active notification on a characteristic, clear + // it first so it doesn't update the data field on the user interface. + if (mNotifyCharacteristic != null) { + mBluetoothLeService.setCharacteristicNotification(mNotifyCharacteristic, false); + mNotifyCharacteristic = null; } - if ((charaProp | BluetoothGattCharacteristic.PROPERTY_NOTIFY) > 0) { - mNotifyCharacteristic = characteristic; - mBluetoothLeService.setCharacteristicNotification(characteristic, true); - } - return true; + mBluetoothLeService.readCharacteristic(characteristic); } - return false; + if ((charaProp | BluetoothGattCharacteristic.PROPERTY_NOTIFY) > 0) { + mNotifyCharacteristic = characteristic; + mBluetoothLeService.setCharacteristicNotification(characteristic, true); + } + return true; } }; @@ -179,52 +176,8 @@ public class DeviceControlActivity extends AppCompatActivity { mDevice.getAddress(), gattServices); - String uuid = null; - final String unknownServiceString = getResources().getString(R.string.unknown_service); - final String unknownCharaString = getResources().getString(R.string.unknown_characteristic); - final List> gattServiceData = new ArrayList<>(); - final List>> gattCharacteristicData = new ArrayList<>(); - mGattCharacteristics = new ArrayList<>(); - - // Loops through available GATT Services. - for (final BluetoothGattService gattService : gattServices) { - final Map currentServiceData = new HashMap<>(); - uuid = gattService.getUuid().toString(); - currentServiceData.put(LIST_NAME, GattAttributeResolver.getAttributeName(uuid, unknownServiceString)); - currentServiceData.put(LIST_UUID, uuid); - gattServiceData.add(currentServiceData); - - final List> gattCharacteristicGroupData = new ArrayList<>(); - final List gattCharacteristics = gattService.getCharacteristics(); - final List charas = new ArrayList<>(); - - // Loops through available Characteristics. - for (final BluetoothGattCharacteristic gattCharacteristic : gattCharacteristics) { - charas.add(gattCharacteristic); - final Map currentCharaData = new HashMap<>(); - uuid = gattCharacteristic.getUuid().toString(); - currentCharaData.put(LIST_NAME, GattAttributeResolver.getAttributeName(uuid, unknownCharaString)); - currentCharaData.put(LIST_UUID, uuid); - gattCharacteristicGroupData.add(currentCharaData); - } - - mGattCharacteristics.add(charas); - gattCharacteristicData.add(gattCharacteristicGroupData); - } - - final SimpleExpandableListAdapter gattServiceAdapter = new SimpleExpandableListAdapter( - this, - gattServiceData, - android.R.layout.simple_expandable_list_item_2, - new String[]{LIST_NAME, LIST_UUID}, - new int[]{android.R.id.text1, android.R.id.text2}, - gattCharacteristicData, - android.R.layout.simple_expandable_list_item_2, - new String[]{LIST_NAME, LIST_UUID}, - new int[]{android.R.id.text1, android.R.id.text2} - ); - - mGattServicesList.setAdapter(gattServiceAdapter); + final GattDataAdapterFactory.GattDataAdapter adapter = GattDataAdapterFactory.createAdapter(this, gattServices); + mGattServicesList.setAdapter(adapter); invalidateOptionsMenu(); } diff --git a/sample_app/src/main/java/uk/co/alt236/btlescan/ui/control/GattDataAdapterFactory.java b/sample_app/src/main/java/uk/co/alt236/btlescan/ui/control/GattDataAdapterFactory.java new file mode 100644 index 0000000..f9c71b1 --- /dev/null +++ b/sample_app/src/main/java/uk/co/alt236/btlescan/ui/control/GattDataAdapterFactory.java @@ -0,0 +1,94 @@ +package uk.co.alt236.btlescan.ui.control; + +import android.bluetooth.BluetoothGattCharacteristic; +import android.bluetooth.BluetoothGattService; +import android.content.Context; +import android.widget.SimpleExpandableListAdapter; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import uk.co.alt236.bluetoothlelib.resolvers.GattAttributeResolver; +import uk.co.alt236.btlescan.R; + +/*package*/ class GattDataAdapterFactory { + private static final String LIST_NAME = "NAME"; + private static final String LIST_UUID = "UUID"; + + public static GattDataAdapter createAdapter(final Context context, + final List gattServices) { + + + final String unknownServiceString = context.getString(R.string.unknown_service); + final String unknownCharaString = context.getString(R.string.unknown_characteristic); + final List> gattServiceData = new ArrayList<>(); + final List>> gattCharacteristicData = new ArrayList<>(); + final List> fullGattCharacteristics = new ArrayList<>(); + + // Loops through available GATT Services. + String uuid; + for (final BluetoothGattService gattService : gattServices) { + final Map currentServiceData = new HashMap<>(); + uuid = gattService.getUuid().toString(); + currentServiceData.put(LIST_NAME, GattAttributeResolver.getAttributeName(uuid, unknownServiceString)); + currentServiceData.put(LIST_UUID, uuid); + gattServiceData.add(currentServiceData); + + final List> gattCharacteristicGroupData = new ArrayList<>(); + final List gattCharacteristics = gattService.getCharacteristics(); + final List charas = new ArrayList<>(); + + // Loops through available Characteristics. + for (final BluetoothGattCharacteristic gattCharacteristic : gattCharacteristics) { + charas.add(gattCharacteristic); + final Map currentCharaData = new HashMap<>(); + uuid = gattCharacteristic.getUuid().toString(); + currentCharaData.put(LIST_NAME, GattAttributeResolver.getAttributeName(uuid, unknownCharaString)); + currentCharaData.put(LIST_UUID, uuid); + gattCharacteristicGroupData.add(currentCharaData); + } + + fullGattCharacteristics.add(charas); + gattCharacteristicData.add(gattCharacteristicGroupData); + } + + return new GattDataAdapter( + context, + fullGattCharacteristics, + gattServiceData, + android.R.layout.simple_expandable_list_item_2, + new String[]{LIST_NAME, LIST_UUID}, + new int[]{android.R.id.text1, android.R.id.text2}, + gattCharacteristicData, + android.R.layout.simple_expandable_list_item_2, + new String[]{LIST_NAME, LIST_UUID}, + new int[]{android.R.id.text1, android.R.id.text2} + ); + } + + + public static class GattDataAdapter extends SimpleExpandableListAdapter { + + private final List> mGattCharacteristics; + + public GattDataAdapter(Context context, + List> gattCharacteristics, + List> groupData, + int groupLayout, String[] groupFrom, + int[] groupTo, + List>> childData, + int childLayout, + String[] childFrom, + int[] childTo) { + + super(context, groupData, groupLayout, groupFrom, groupTo, childData, childLayout, childFrom, childTo); + mGattCharacteristics = gattCharacteristics; + } + + public BluetoothGattCharacteristic getBluetoothGattCharacteristic(final int groupPosition, final int childPosition) { + return mGattCharacteristics.get(groupPosition).get(childPosition); + } + } +} From 7f15ea3d1e9f5b55931c1263e3744ac68e4f5831 Mon Sep 17 00:00:00 2001 From: Alexandros Schillings Date: Wed, 31 Aug 2016 19:09:38 +0100 Subject: [PATCH 09/19] We now have a "connecting" state in the ControlActivity. --- .../btlescan/services/BluetoothLeService.java | 114 +++++++++++++----- .../ui/control/DeviceControlActivity.java | 69 ++++++++--- sample_app/src/main/res/values/strings.xml | 1 + 3 files changed, 135 insertions(+), 49 deletions(-) diff --git a/sample_app/src/main/java/uk/co/alt236/btlescan/services/BluetoothLeService.java b/sample_app/src/main/java/uk/co/alt236/btlescan/services/BluetoothLeService.java index 53be95a..2320a13 100644 --- a/sample_app/src/main/java/uk/co/alt236/btlescan/services/BluetoothLeService.java +++ b/sample_app/src/main/java/uk/co/alt236/btlescan/services/BluetoothLeService.java @@ -39,22 +39,20 @@ import java.util.List; */ public class BluetoothLeService extends Service { public final static String ACTION_GATT_CONNECTED = BluetoothLeService.class.getName() + ".ACTION_GATT_CONNECTED"; + public final static String ACTION_GATT_CONNECTING = BluetoothLeService.class.getName() + ".ACTION_GATT_CONNECTING"; public final static String ACTION_GATT_DISCONNECTED = BluetoothLeService.class.getName() + ".ACTION_GATT_DISCONNECTED"; public final static String ACTION_GATT_SERVICES_DISCOVERED = BluetoothLeService.class.getName() + ".ACTION_GATT_SERVICES_DISCOVERED"; public final static String ACTION_DATA_AVAILABLE = BluetoothLeService.class.getName() + ".ACTION_DATA_AVAILABLE"; public final static String EXTRA_DATA_RAW = BluetoothLeService.class.getName() + ".EXTRA_DATA_RAW"; public final static String EXTRA_UUID_CHAR = BluetoothLeService.class.getName() + ".EXTRA_UUID_CHAR"; private final static String TAG = BluetoothLeService.class.getSimpleName(); - - private static final int STATE_DISCONNECTED = 0; - private static final int STATE_CONNECTING = 1; - private static final int STATE_CONNECTED = 2; private final IBinder mBinder = new LocalBinder(); private BluetoothManager mBluetoothManager; private BluetoothAdapter mBluetoothAdapter; private String mBluetoothDeviceAddress; private BluetoothGatt mBluetoothGatt; - private int mConnectionState = STATE_DISCONNECTED; + private State mConnectionState = State.DISCONNECTED; + // Implements callback methods for GATT events that the app cares about. For example, // connection change and services discovered. private final BluetoothGattCallback mGattCallback = new BluetoothGattCallback() { @@ -64,28 +62,35 @@ public class BluetoothLeService extends Service { } @Override - public void onCharacteristicRead(final BluetoothGatt gatt, final BluetoothGattCharacteristic characteristic, final int status) { + public void onCharacteristicRead(final BluetoothGatt gatt, + final BluetoothGattCharacteristic characteristic, + final int status) { + if (status == BluetoothGatt.GATT_SUCCESS) { broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic); } } @Override - public void onConnectionStateChange(final BluetoothGatt gatt, final int status, final int newState) { - final String intentAction; + public void onConnectionStateChange(final BluetoothGatt gatt, + final int status, + final int newState) { + + Log.d(TAG, "onConnectionStateChange: status=" + status + ", newState=" + newState); + if (newState == BluetoothProfile.STATE_CONNECTED) { - intentAction = ACTION_GATT_CONNECTED; - mConnectionState = STATE_CONNECTED; - broadcastUpdate(intentAction); + setConnectionState(State.CONNECTED, true); Log.i(TAG, "Connected to GATT server."); // Attempts to discover services after successful connection. Log.i(TAG, "Attempting to start service discovery:" + mBluetoothGatt.discoverServices()); } else if (newState == BluetoothProfile.STATE_DISCONNECTED) { - intentAction = ACTION_GATT_DISCONNECTED; - mConnectionState = STATE_DISCONNECTED; + // Make sure we tidy up. On certain devices reusing a Gatt after a disconnection + // can cause problems. + disconnect(); + + setConnectionState(State.DISCONNECTED, true); Log.i(TAG, "Disconnected from GATT server."); - broadcastUpdate(intentAction); } } @@ -139,37 +144,73 @@ public class BluetoothLeService extends Service { * callback. */ public boolean connect(final String address) { + + final boolean retVal; if (mBluetoothAdapter == null || address == null) { Log.w(TAG, "BluetoothAdapter not initialized or unspecified address."); - return false; - } + retVal = false; - // Previously connected device. Try to reconnect. - if (mBluetoothDeviceAddress != null + // Previously connected device. Try to reconnect. + } else if (mBluetoothDeviceAddress != null && address.equals(mBluetoothDeviceAddress) && mBluetoothGatt != null) { Log.d(TAG, "Trying to use an existing mBluetoothGatt for connection."); if (mBluetoothGatt.connect()) { - mConnectionState = STATE_CONNECTING; - return true; + Log.d(TAG, "Connection attempt OK."); + setConnectionState(State.CONNECTING, true); + retVal = true; } else { - return false; + Log.w(TAG, "Connection attempt failed."); + setConnectionState(State.DISCONNECTED, true); + retVal = false; + } + } else { + + final BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address); + if (device == null) { + Log.w(TAG, "Device not found. Unable to connect."); + retVal = false; + } else { + // We want to directly connect to the device, so we are setting the autoConnect + // parameter to false. + + Log.d(TAG, "Trying to create a new connection."); + mBluetoothGatt = device.connectGatt(this, false, mGattCallback); + mBluetoothDeviceAddress = address; + setConnectionState(State.CONNECTING, true); + retVal = true; } } - final BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address); - if (device == null) { - Log.w(TAG, "Device not found. Unable to connect."); - return false; + return retVal; + } + + private synchronized void setConnectionState(final State newState, final boolean broadCast) { + Log.i(TAG, "Setting internal state to " + newState); + mConnectionState = newState; + + final String broadcastAction; + + switch (newState) { + case CONNECTED: + broadcastAction = ACTION_GATT_CONNECTED; + break; + case CONNECTING: + broadcastAction = ACTION_GATT_CONNECTING; + break; + case DISCONNECTED: + broadcastAction = ACTION_GATT_DISCONNECTED; + break; + default: + throw new IllegalArgumentException("Unknown state: " + newState); } - // We want to directly connect to the device, so we are setting the autoConnect - // parameter to false. - mBluetoothGatt = device.connectGatt(this, false, mGattCallback); - Log.d(TAG, "Trying to create a new connection."); - mBluetoothDeviceAddress = address; - mConnectionState = STATE_CONNECTING; - return true; + + if (broadCast) { + Log.i(TAG, "Broadcasting " + broadcastAction); + broadcastUpdate(broadcastAction); + } + } /** @@ -184,6 +225,9 @@ public class BluetoothLeService extends Service { return; } mBluetoothGatt.disconnect(); + + // Reusing a Gatt after disconnecting can cause problems + mBluetoothGatt = null; } /** @@ -271,4 +315,10 @@ public class BluetoothLeService extends Service { return BluetoothLeService.this; } } + + private enum State { + DISCONNECTED, + CONNECTING, + CONNECTED + } } \ No newline at end of file diff --git a/sample_app/src/main/java/uk/co/alt236/btlescan/ui/control/DeviceControlActivity.java b/sample_app/src/main/java/uk/co/alt236/btlescan/ui/control/DeviceControlActivity.java index 4f6d756..96ace50 100644 --- a/sample_app/src/main/java/uk/co/alt236/btlescan/ui/control/DeviceControlActivity.java +++ b/sample_app/src/main/java/uk/co/alt236/btlescan/ui/control/DeviceControlActivity.java @@ -121,7 +121,8 @@ public class DeviceControlActivity extends AppCompatActivity { } }; private BluetoothLeDevice mDevice; - private boolean mConnected = false; + private State mCurrentState = State.DISCONNECTED; + private String mExportString; // Handles various events fired by the Service. // ACTION_GATT_CONNECTED: connected to a GATT server. @@ -134,14 +135,16 @@ public class DeviceControlActivity extends AppCompatActivity { public void onReceive(final Context context, final Intent intent) { final String action = intent.getAction(); if (BluetoothLeService.ACTION_GATT_CONNECTED.equals(action)) { - mConnected = true; - updateConnectionState(R.string.connected); + updateConnectionState(State.CONNECTED); invalidateOptionsMenu(); } else if (BluetoothLeService.ACTION_GATT_DISCONNECTED.equals(action)) { - mConnected = false; - updateConnectionState(R.string.disconnected); - invalidateOptionsMenu(); clearUI(); + updateConnectionState(State.DISCONNECTED); + invalidateOptionsMenu(); + } else if (BluetoothLeService.ACTION_GATT_CONNECTING.equals(action)) { + clearUI(); + updateConnectionState(State.CONNECTING); + invalidateOptionsMenu(); } else if (BluetoothLeService.ACTION_GATT_SERVICES_DISCOVERED.equals(action)) { // Show all the supported services and characteristics on the user interface. displayGattServices(mBluetoothLeService.getSupportedGattServices()); @@ -159,6 +162,7 @@ public class DeviceControlActivity extends AppCompatActivity { }; private void clearUI() { + mExportString = null; mGattServicesList.setAdapter((SimpleExpandableListAdapter) null); mGattUUID.setText(R.string.no_data); mGattUUIDDesc.setText(R.string.no_data); @@ -206,12 +210,26 @@ public class DeviceControlActivity extends AppCompatActivity { @Override public boolean onCreateOptionsMenu(final Menu menu) { getMenuInflater().inflate(R.menu.gatt_services, menu); - if (mConnected) { - menu.findItem(R.id.menu_connect).setVisible(false); - menu.findItem(R.id.menu_disconnect).setVisible(true); - } else { - menu.findItem(R.id.menu_connect).setVisible(true); - menu.findItem(R.id.menu_disconnect).setVisible(false); + + switch (mCurrentState) { + + case DISCONNECTED: + menu.findItem(R.id.menu_connect).setVisible(true); + menu.findItem(R.id.menu_disconnect).setVisible(false); + menu.findItem(R.id.menu_refresh).setActionView(null); + break; + case CONNECTING: + menu.findItem(R.id.menu_connect).setVisible(false); + menu.findItem(R.id.menu_disconnect).setVisible(false); + menu.findItem(R.id.menu_refresh).setActionView(R.layout.actionbar_progress_indeterminate); + break; + case CONNECTED: + menu.findItem(R.id.menu_connect).setVisible(false); + menu.findItem(R.id.menu_disconnect).setVisible(true); + menu.findItem(R.id.menu_refresh).setActionView(null); + break; + default: + throw new IllegalStateException("Don't know how to handle: " + mCurrentState); } if (mExportString == null) { @@ -278,25 +296,35 @@ public class DeviceControlActivity extends AppCompatActivity { } } - private void updateConnectionState(final int resourceId) { + private void updateConnectionState(final State state) { + mCurrentState = state; + runOnUiThread(new Runnable() { @Override public void run() { final int colourId; + final int resId; - switch (resourceId) { - case R.string.connected: + switch (state) { + case CONNECTED: colourId = android.R.color.holo_green_dark; + resId = R.string.connected; break; - case R.string.disconnected: + case DISCONNECTED: colourId = android.R.color.holo_red_dark; + resId = R.string.disconnected; + break; + case CONNECTING: + colourId = android.R.color.black; + resId = R.string.connecting; break; default: colourId = android.R.color.black; + resId = 0; break; } - mConnectionState.setText(resourceId); + mConnectionState.setText(resId); mConnectionState.setTextColor(ContextCompat.getColor(DeviceControlActivity.this, colourId)); } }); @@ -308,6 +336,7 @@ public class DeviceControlActivity extends AppCompatActivity { intentFilter.addAction(BluetoothLeService.ACTION_GATT_DISCONNECTED); intentFilter.addAction(BluetoothLeService.ACTION_GATT_SERVICES_DISCOVERED); intentFilter.addAction(BluetoothLeService.ACTION_DATA_AVAILABLE); + intentFilter.addAction(BluetoothLeService.ACTION_GATT_CONNECTING); return intentFilter; } @@ -324,4 +353,10 @@ public class DeviceControlActivity extends AppCompatActivity { intent.putExtra(DeviceControlActivity.EXTRA_DEVICE, device); return intent; } + + private enum State { + DISCONNECTED, + CONNECTING, + CONNECTED + } } \ No newline at end of file diff --git a/sample_app/src/main/res/values/strings.xml b/sample_app/src/main/res/values/strings.xml index c0c87be..17d8515 100644 --- a/sample_app/src/main/res/values/strings.xml +++ b/sample_app/src/main/res/values/strings.xml @@ -5,6 +5,7 @@ Bluetooth LE Scanner Connected Disconnected + Connecting Invalid Device Data! No data Not supported From 6f092344f5bebfdc1fc6a67761e7db1f93ccb4ab Mon Sep 17 00:00:00 2001 From: Alexandros Schillings Date: Wed, 31 Aug 2016 19:56:09 +0100 Subject: [PATCH 10/19] Fixed CSV sharing --- .../containers/BluetoothLeDeviceStore.java | 128 -------------- .../alt236/btlescan/ui/common/Navigation.java | 16 ++ .../{util => ui/main}/CsvWriterHelper.java | 4 +- .../alt236/btlescan/ui/main/MainActivity.java | 2 +- .../uk/co/alt236/btlescan/ui/main/Sharer.java | 161 ++++++++++++++++++ sample_app/src/main/res/values/strings.xml | 1 + 6 files changed, 181 insertions(+), 131 deletions(-) rename sample_app/src/main/java/uk/co/alt236/btlescan/{util => ui/main}/CsvWriterHelper.java (88%) create mode 100644 sample_app/src/main/java/uk/co/alt236/btlescan/ui/main/Sharer.java diff --git a/sample_app/src/main/java/uk/co/alt236/btlescan/containers/BluetoothLeDeviceStore.java b/sample_app/src/main/java/uk/co/alt236/btlescan/containers/BluetoothLeDeviceStore.java index 8b99033..acc0820 100644 --- a/sample_app/src/main/java/uk/co/alt236/btlescan/containers/BluetoothLeDeviceStore.java +++ b/sample_app/src/main/java/uk/co/alt236/btlescan/containers/BluetoothLeDeviceStore.java @@ -1,28 +1,13 @@ package uk.co.alt236.btlescan.containers; -import android.content.Context; -import android.content.Intent; -import android.net.Uri; - -import java.io.File; -import java.io.FileWriter; -import java.io.IOException; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.HashMap; import java.util.List; -import java.util.Locale; import java.util.Map; import uk.co.alt236.bluetoothlelib.device.BluetoothLeDevice; -import uk.co.alt236.bluetoothlelib.device.beacon.BeaconType; -import uk.co.alt236.bluetoothlelib.device.beacon.BeaconUtils; -import uk.co.alt236.bluetoothlelib.device.beacon.ibeacon.IBeaconDevice; -import uk.co.alt236.bluetoothlelib.util.ByteUtils; -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; public class BluetoothLeDeviceStore { @@ -65,117 +50,4 @@ 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(CsvWriterHelper.addStuff("iBeacon")); - sb.append(CsvWriterHelper.addStuff("uuid")); - sb.append(CsvWriterHelper.addStuff("major")); - sb.append(CsvWriterHelper.addStuff("minor")); - sb.append(CsvWriterHelper.addStuff("txPower")); - sb.append(CsvWriterHelper.addStuff("distance")); - sb.append(CsvWriterHelper.addStuff("accuracy")); - sb.append('\n'); - - for (final BluetoothLeDevice device : list) { - sb.append(CsvWriterHelper.addStuff(device.getAddress())); - sb.append(CsvWriterHelper.addStuff(device.getName())); - sb.append(CsvWriterHelper.addStuff(TimeFormatter.getIsoDateTime(device.getFirstTimestamp()))); - sb.append(CsvWriterHelper.addStuff(device.getFirstRssi())); - 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 = BeaconUtils.getBeaconType(device) == BeaconType.IBEACON; - final String uuid; - final String minor; - final String major; - final String txPower; - final String distance; - final String accuracy; - - if (isIBeacon) { - final IBeaconDevice beacon = new IBeaconDevice(device); - uuid = String.valueOf(beacon.getUUID()); - minor = String.valueOf(beacon.getMinor()); - major = String.valueOf(beacon.getMajor()); - txPower = String.valueOf(beacon.getCalibratedTxPower()); - distance = beacon.getDistanceDescriptor().toString().toLowerCase(Locale.US); - accuracy = String.valueOf(beacon.getAccuracy()); - } else { - uuid = ""; - minor = ""; - major = ""; - txPower = ""; - distance = ""; - accuracy = ""; - } - - sb.append(CsvWriterHelper.addStuff(isIBeacon)); - sb.append(CsvWriterHelper.addStuff(uuid)); - sb.append(CsvWriterHelper.addStuff(minor)); - sb.append(CsvWriterHelper.addStuff(major)); - sb.append(CsvWriterHelper.addStuff(txPower)); - sb.append(CsvWriterHelper.addStuff(distance)); - sb.append(CsvWriterHelper.addStuff(accuracy)); - - sb.append('\n'); - } - - return sb.toString(); - } - - public void shareDataAsEmail(final Context context) { - final long timeInMillis = System.currentTimeMillis(); - - final String to = null; - final String subject = context.getString( - R.string.exporter_email_device_list_subject, - TimeFormatter.getIsoDateTime(timeInMillis)); - - final String message = context.getString(R.string.exporter_email_device_list_body); - - final Intent i = new Intent(Intent.ACTION_SEND); - i.setType("plain/text"); - try { - final File outputDir = context.getCacheDir(); - 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, context.getString(R.string.exporter_email_device_list_picker_text))); - - } catch (final IOException e) { - e.printStackTrace(); - } - } - - private static FileWriter generateFile(final File file, final String contents) { - FileWriter writer = null; - try { - writer = new FileWriter(file); - writer.append(contents); - writer.flush(); - - } catch (final IOException e) { - e.printStackTrace(); - } finally { - try { - writer.close(); - } catch (final IOException e) { - e.printStackTrace(); - } - } - return writer; - } } diff --git a/sample_app/src/main/java/uk/co/alt236/btlescan/ui/common/Navigation.java b/sample_app/src/main/java/uk/co/alt236/btlescan/ui/common/Navigation.java index bae79c3..95846d6 100644 --- a/sample_app/src/main/java/uk/co/alt236/btlescan/ui/common/Navigation.java +++ b/sample_app/src/main/java/uk/co/alt236/btlescan/ui/common/Navigation.java @@ -2,9 +2,11 @@ package uk.co.alt236.btlescan.ui.common; import android.app.Activity; import android.content.Intent; +import android.net.Uri; import android.support.v4.app.ActivityCompat; import uk.co.alt236.bluetoothlelib.device.BluetoothLeDevice; +import uk.co.alt236.btlescan.R; import uk.co.alt236.btlescan.ui.control.DeviceControlActivity; import uk.co.alt236.btlescan.ui.details.DeviceDetailsActivity; @@ -28,6 +30,20 @@ public class Navigation { startActivity(intent); } + public void shareFileViaEmail(final Uri fileUri, final String[] recipient, final String subject, final String message) { + final Intent intent = new Intent(Intent.ACTION_SEND); + + intent.setType("plain/text"); + intent.putExtra(Intent.EXTRA_STREAM, fileUri); + intent.putExtra(Intent.EXTRA_EMAIL, recipient); + intent.putExtra(Intent.EXTRA_SUBJECT, subject); + intent.putExtra(Intent.EXTRA_TEXT, message); + + startActivity(Intent.createChooser(intent, + mActivity.getString(R.string.exporter_email_device_list_picker_text))); + } + + private void startActivity(final Intent intent) { ActivityCompat.startActivity(mActivity, intent, null); } diff --git a/sample_app/src/main/java/uk/co/alt236/btlescan/util/CsvWriterHelper.java b/sample_app/src/main/java/uk/co/alt236/btlescan/ui/main/CsvWriterHelper.java similarity index 88% rename from sample_app/src/main/java/uk/co/alt236/btlescan/util/CsvWriterHelper.java rename to sample_app/src/main/java/uk/co/alt236/btlescan/ui/main/CsvWriterHelper.java index f8bff7d..c73b4c7 100644 --- a/sample_app/src/main/java/uk/co/alt236/btlescan/util/CsvWriterHelper.java +++ b/sample_app/src/main/java/uk/co/alt236/btlescan/ui/main/CsvWriterHelper.java @@ -1,6 +1,6 @@ -package uk.co.alt236.btlescan.util; +package uk.co.alt236.btlescan.ui.main; -public class CsvWriterHelper { +/*package*/ class CsvWriterHelper { private static final String QUOTE = "\""; public static String addStuff(final Integer text) { diff --git a/sample_app/src/main/java/uk/co/alt236/btlescan/ui/main/MainActivity.java b/sample_app/src/main/java/uk/co/alt236/btlescan/ui/main/MainActivity.java index b6b4668..9b34960 100644 --- a/sample_app/src/main/java/uk/co/alt236/btlescan/ui/main/MainActivity.java +++ b/sample_app/src/main/java/uk/co/alt236/btlescan/ui/main/MainActivity.java @@ -132,7 +132,7 @@ public class MainActivity extends AppCompatActivity implements AdapterView.OnIte DialogFactory.createAboutDialog(this).show(); break; case R.id.menu_share: - mDeviceStore.shareDataAsEmail(this); + new Sharer().shareDataAsEmail(this, mDeviceStore); } return true; } diff --git a/sample_app/src/main/java/uk/co/alt236/btlescan/ui/main/Sharer.java b/sample_app/src/main/java/uk/co/alt236/btlescan/ui/main/Sharer.java new file mode 100644 index 0000000..0062c29 --- /dev/null +++ b/sample_app/src/main/java/uk/co/alt236/btlescan/ui/main/Sharer.java @@ -0,0 +1,161 @@ +package uk.co.alt236.btlescan.ui.main; + +import android.app.Activity; +import android.content.Context; +import android.net.Uri; +import android.support.v4.content.ContextCompat; +import android.widget.Toast; + +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.util.List; +import java.util.Locale; + +import uk.co.alt236.bluetoothlelib.device.BluetoothLeDevice; +import uk.co.alt236.bluetoothlelib.device.beacon.BeaconType; +import uk.co.alt236.bluetoothlelib.device.beacon.BeaconUtils; +import uk.co.alt236.bluetoothlelib.device.beacon.ibeacon.IBeaconDevice; +import uk.co.alt236.bluetoothlelib.util.ByteUtils; +import uk.co.alt236.btlescan.R; +import uk.co.alt236.btlescan.containers.BluetoothLeDeviceStore; +import uk.co.alt236.btlescan.ui.common.Navigation; +import uk.co.alt236.btlescan.util.TimeFormatter; + +/*package*/ class Sharer { + private static final String CSV_FILENAME_PREFIX = "bluetooth_le_%d"; + private static final String CSV_FILENAME_SUFFIX = ".csv"; + + private static File getExternalCacheDir(final Context context) { + final File[] files = ContextCompat.getExternalCacheDirs(context); + final File retVal; + + if (files == null || files.length == 0 || files[0] == null) { + retVal = null; + } else { + retVal = files[0]; + } + + return retVal; + } + + private static String getListAsCsv(List deviceList) { + + 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(CsvWriterHelper.addStuff("iBeacon")); + sb.append(CsvWriterHelper.addStuff("uuid")); + sb.append(CsvWriterHelper.addStuff("major")); + sb.append(CsvWriterHelper.addStuff("minor")); + sb.append(CsvWriterHelper.addStuff("txPower")); + sb.append(CsvWriterHelper.addStuff("distance")); + sb.append(CsvWriterHelper.addStuff("accuracy")); + sb.append('\n'); + + for (final BluetoothLeDevice device : deviceList) { + sb.append(CsvWriterHelper.addStuff(device.getAddress())); + sb.append(CsvWriterHelper.addStuff(device.getName())); + sb.append(CsvWriterHelper.addStuff(TimeFormatter.getIsoDateTime(device.getFirstTimestamp()))); + sb.append(CsvWriterHelper.addStuff(device.getFirstRssi())); + 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 = BeaconUtils.getBeaconType(device) == BeaconType.IBEACON; + final String uuid; + final String minor; + final String major; + final String txPower; + final String distance; + final String accuracy; + + if (isIBeacon) { + final IBeaconDevice beacon = new IBeaconDevice(device); + uuid = String.valueOf(beacon.getUUID()); + minor = String.valueOf(beacon.getMinor()); + major = String.valueOf(beacon.getMajor()); + txPower = String.valueOf(beacon.getCalibratedTxPower()); + distance = beacon.getDistanceDescriptor().toString().toLowerCase(Locale.US); + accuracy = String.valueOf(beacon.getAccuracy()); + } else { + uuid = ""; + minor = ""; + major = ""; + txPower = ""; + distance = ""; + accuracy = ""; + } + + sb.append(CsvWriterHelper.addStuff(isIBeacon)); + sb.append(CsvWriterHelper.addStuff(uuid)); + sb.append(CsvWriterHelper.addStuff(minor)); + sb.append(CsvWriterHelper.addStuff(major)); + sb.append(CsvWriterHelper.addStuff(txPower)); + sb.append(CsvWriterHelper.addStuff(distance)); + sb.append(CsvWriterHelper.addStuff(accuracy)); + + sb.append('\n'); + } + + return sb.toString(); + } + + private static FileWriter saveToFile(final File file, final String contents) { + FileWriter writer = null; + try { + writer = new FileWriter(file); + writer.append(contents); + writer.flush(); + + } catch (final IOException e) { + e.printStackTrace(); + } finally { + try { + if (writer != null) { + writer.close(); + } + } catch (final IOException e) { + e.printStackTrace(); + } + } + return writer; + } + + public void shareDataAsEmail(final Activity activity, + final BluetoothLeDeviceStore store) { + final long timeInMillis = System.currentTimeMillis(); + final String filename = String.format(Locale.US, CSV_FILENAME_PREFIX, timeInMillis); + + final String to = null; + final String subject = activity.getString( + R.string.exporter_email_device_list_subject, + TimeFormatter.getIsoDateTime(timeInMillis)); + + final String message = activity.getString(R.string.exporter_email_device_list_body); + + final String contents = getListAsCsv(store.getDeviceList()); + final File outputDir = getExternalCacheDir(activity); + + if (outputDir == null) { + Toast.makeText(activity, R.string.error_unable_to_access_external_storage, Toast.LENGTH_SHORT).show(); + } else { + try { + + final File outputFile = File.createTempFile(filename, CSV_FILENAME_SUFFIX, outputDir); + saveToFile(outputFile, contents); + + final Uri uri = Uri.fromFile(outputFile); + new Navigation(activity) + .shareFileViaEmail(uri, new String[]{to}, subject, message); + + } catch (final IOException e) { + e.printStackTrace(); + } + } + } +} diff --git a/sample_app/src/main/res/values/strings.xml b/sample_app/src/main/res/values/strings.xml index 17d8515..a6b422f 100644 --- a/sample_app/src/main/res/values/strings.xml +++ b/sample_app/src/main/res/values/strings.xml @@ -75,5 +75,6 @@ Updated: Descriptor: + "Could not access external storage!" The ACCESS_COARSE_LOCATION permission is needed to receive bluetooth scan results \ No newline at end of file From ef5b84387f10a597d43907066e8a17d7c15ab907 Mon Sep 17 00:00:00 2001 From: Alexandros Schillings Date: Wed, 31 Aug 2016 20:19:18 +0100 Subject: [PATCH 11/19] Fixed bug where the device class name was returned instead of the major class name --- .../btlescan/ui/details/recyclerview/model/DeviceInfoItem.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sample_app/src/main/java/uk/co/alt236/btlescan/ui/details/recyclerview/model/DeviceInfoItem.java b/sample_app/src/main/java/uk/co/alt236/btlescan/ui/details/recyclerview/model/DeviceInfoItem.java index b7cda0b..e2541d9 100644 --- a/sample_app/src/main/java/uk/co/alt236/btlescan/ui/details/recyclerview/model/DeviceInfoItem.java +++ b/sample_app/src/main/java/uk/co/alt236/btlescan/ui/details/recyclerview/model/DeviceInfoItem.java @@ -23,7 +23,7 @@ public class DeviceInfoItem implements RecyclerViewItem { } public String getBluetoothDeviceMajorClassName() { - return mDevice.getBluetoothDeviceClassName(); + return mDevice.getBluetoothDeviceMajorClassName(); } public String getBluetoothDeviceClassName() { From 1639e1a22df59234cc26269b7bb9baefc800a154 Mon Sep 17 00:00:00 2001 From: Alexandros Schillings Date: Wed, 31 Aug 2016 20:21:31 +0100 Subject: [PATCH 12/19] Updated share and bluetooth icons --- .../main/res/drawable-hdpi/ic_action_share.png | Bin 445 -> 710 bytes .../main/res/drawable-hdpi/ic_bluetooth.png | Bin 0 -> 508 bytes .../main/res/drawable-mdpi/ic_action_share.png | Bin 295 -> 487 bytes .../main/res/drawable-mdpi/ic_bluetooth.png | Bin 0 -> 374 bytes .../res/drawable-xhdpi/ic_action_share.png | Bin 548 -> 899 bytes .../main/res/drawable-xhdpi/ic_bluetooth.png | Bin 824 -> 662 bytes .../res/drawable-xxhdpi/ic_action_share.png | Bin 911 -> 1347 bytes .../main/res/drawable-xxhdpi/ic_bluetooth.png | Bin 0 -> 885 bytes .../res/drawable-xxxhdpi/ic_action_share.png | Bin 0 -> 1807 bytes .../main/res/drawable-xxxhdpi/ic_bluetooth.png | Bin 0 -> 1172 bytes .../src/main/res/layout/list_item_device.xml | 4 ++-- 11 files changed, 2 insertions(+), 2 deletions(-) create mode 100644 sample_app/src/main/res/drawable-hdpi/ic_bluetooth.png create mode 100644 sample_app/src/main/res/drawable-mdpi/ic_bluetooth.png create mode 100644 sample_app/src/main/res/drawable-xxhdpi/ic_bluetooth.png create mode 100644 sample_app/src/main/res/drawable-xxxhdpi/ic_action_share.png create mode 100644 sample_app/src/main/res/drawable-xxxhdpi/ic_bluetooth.png diff --git a/sample_app/src/main/res/drawable-hdpi/ic_action_share.png b/sample_app/src/main/res/drawable-hdpi/ic_action_share.png index 2b267dfdbc1e122ff97d66e77fb2de0d688de75d..838580781021dd4c6472a8a54ab0527f02726fba 100644 GIT binary patch literal 710 zcmV;%0y+JOP){B1gBEb1EN_d zC@PIaG*Lk!P^dv~Ghdmy{WmN@;_iLV-4|pnISW1x=pCHz?Dtwbpp*(6MgqQ=FXoFy zq69R6R(cjo7b^vmDtt_UphU46u&M0v7gS3U%L8l5TdacfQp8@W=;E0Kv11;(;Qz4! zQn`y=P;ODgUF?#hSUGpGJV&u?&SE#gCkLrHu9JrzA7jcrZgCUK1btvT2B|mT2p6#g z+VlM~yzEzS2lPjf(*IB9vh%nGW(_a;4|IXFeZQ{&FTiJ7uk`adxXNV{d=9*}eEk8C zFX`B#cM@&%wZp|naGlF}EDPMH78s>x6HNwQr|%We43fAUG#f2D??2$4hw1w%IL+w< z-R^M;-ZA`rlD15&QUjGStTo@jT@c4H=kd-#NKfD0Af0P6C)2T|%D88#E;@<@xr>z^ zRHv(!eZ-VSHOGA^3X$Feed_#)Z&9wI?^ZY7I2DVeJq~NZQl)oKWNPAgwMKVjE1<@ z$8^g)rj~Mz2b}9;1z^ZgY%9{(S$IFaIsVVBdVlJ@cf)5d-=0T3cD@P|lXPEQfZ_q(A ssOU>#iF8q{iY|yH`q%n=F<*=iyTt@LzstKw-v9sr07*qoM6N<$f{1`ZRR910 literal 445 zcmV;u0Yd(XP)UaqtK1GBFjsh{yVDx}H5srspv%%;Ae-b=kHyAzOMS=$u29v|3 zfVi2+^bf*|ftYbHI9v#bOMv(|lH)*S|4BTKKL*6wgQ22I1>%E94m$v?s6cXdXq6ZY zZv|qLfpj=45QhQrPP7m$0%Acdo&@EId?3yPVmF#qV9@g09*7-*SQbZ{2IPPZNDc?3 z_a;#KAIJ~|HMIKBGT&(+o({xvP&F3NOouE#35eAOIvtBa(7FWU&PUnugIl z&`Uy@y%va_2Sw3`6#B%L+37&cGT3TND-uHAXE0XzL*4^JI|&W>Ogt=#Q4%UL^FdjW z4U47(of~tmgJv{h$Tp{kO^0UKbSZ~Tr+zpMs|@*pt)V@%IOGR+p&l68!|O;D-O!xi nz|w{qdQ(iJU=)mkQNREIBWf@w^K&mR00000NkvXXu0mjfJW{Y{ diff --git a/sample_app/src/main/res/drawable-hdpi/ic_bluetooth.png b/sample_app/src/main/res/drawable-hdpi/ic_bluetooth.png new file mode 100644 index 0000000000000000000000000000000000000000..af26e939e1176fb772eb02e2991c5363c88e987a GIT binary patch literal 508 zcmV1V)a_L2UzZCfKFSHxd_HVQsnF_YRy1rpgYHxY!E4M#SK3 zFm>z*g-faA!wnHIm16`h^^U~gd@yzHi{)D99OKyFz-|8ETrhRcgXJ36fx`)8fDXag zU@p{64vK2#F=&Jhw=$HkkSNM2l?(S4SVo4To-4X=A-SbOAtu4D_of&MHM@_+k)x2y zmQdUs0)<|W`EW24H%v?s7WycPDLsm@orjo0=aJgoi<-OpR1^eP0`(eLMv6nDR701B z@}*-{AZnNd`%t}S*|I_5(5Re+rr=m;#xyAB)4)YZSnOT)!A@j;4ClPd?3IG0JUT8I z1eF3iO?V${FdOP47nK6rk$EKe#C?TCmjvrslHtRyv*ui!GJSScGDrP#2*7m#91tS#6od0Q$w z%pi@I~nx}qsJDdAE_nzmR|Gkb<$|)zDiclE{rNJ?HC5}KUDxq=k zseaZ67?T!i00k9XPoQ2>XiA0Gq@>USLug(~CnieEDvw z7xjBUmyO!$vKlZ4ioP3asZG#GPb?2!z%w`meYWc+Nt&IJdibJ)kU-R z*B!{vg8uWPLoc@6FYjKDtr+X#4J?6Ln`c>0@oE=z*gjm743P^kD0SL<3?WZ4eqw4<7}2bMv}H&&vtI*ACYJ8lNdf?nUaekuos>^)_m zn2In{4}&X1?9`AK5Bb&9nFZr;-3HCHac+QXY6gAXE)nvZz?Km|iUGM==V@0eVO|k)Rln#n!`6w82006e!>oq{~s*eBw002ovPDHLkV1i6Gb>aX3 diff --git a/sample_app/src/main/res/drawable-mdpi/ic_bluetooth.png b/sample_app/src/main/res/drawable-mdpi/ic_bluetooth.png new file mode 100644 index 0000000000000000000000000000000000000000..6734d1d2b1b5faa8943fec2843a8f975f5b6602e GIT binary patch literal 374 zcmV-+0g3*JP)w%~1l2Xj7-a)wgi>udg|HSNZInu*1*C+e4JZ-xFh!~SGo{c0 zg%Uv<$iW09YfyKdp$;;H!mDfqIqITR8d0cRKvBzn0=b}jW?fEd#t{?>gM3JV+U`Cq z3hiZ2q3Vtj;rp7vb0a?C>UB-zD?SN@1i>R9a(9Dm67vDoJ^;{^)2zX=8p0 zBpb4<&mogxw3fRrh{9YOuHSXaw*{gwDJqN!|4nRDv_Y9-s7D7QP;_s|-Vd z#*j0*XZfuS+7@!s#i$P1yu}vwi7=r{oBYtFV^HMMxh!(&pcuP!l#YYpb<974UfDz5 UgF!T^IsgCw07*qoM6N<$g3R5WrvLx| literal 0 HcmV?d00001 diff --git a/sample_app/src/main/res/drawable-xhdpi/ic_action_share.png b/sample_app/src/main/res/drawable-xhdpi/ic_action_share.png index 0ae218e05a93ef1a28490ad56e2f55cd616dd106..c7e0767566f218a0591aef90916843be623b16cd 100644 GIT binary patch literal 899 zcmV-}1AP36P)SmMaM7i&YUs|5xDu(gHB{Y;kD_(03$bEBQN)Fc?yHMvy4QtBDwJB$ zQXjaph^AdB+KrFuB2BU5fAI{2GRd4tPPF&TJ@7%GAuwM$_wk=QNqC-@a8$-gaDtp5 zC&&qMf*MW}$bca*4N71ROo1HejENI>ds?K`>K_4^eM1=D|qC|)-w$Y#WmoD(2P}Hv!KmpL1r6q9DHG1>5b52lori2D(wSsa2g3ONn z3~13Ps9SKFe+TwyJYhB=yij~ddo?wJ(#&8hN}0j`8d$ACP=ZcpMUnKCnK6F`y|ksV z{t#!H4j_fq6R?pkx|bwyx)eKX7v$4b7LpffF1=Qa*Y6#ORxK4UFq-)8(81tawO zBuLpVC~E6@hGaC;*5yJ-9Blq}xt8&4DK5^;MW0}HL0(h$gj;5Lvd(rv<$bhUp3Hf~ z#qFpT4T8!SrjLasUDPDV=b%t7<*%`l+64KhK?a2SbH_9a^2rJax}#apsDPkh&4NY* z1m)c=R=ox_3+fXPbVReDRGl-~4{pqB^E0cL>JW5Z<3cegDjBaq&RCQK6t+JWo{G3x z9ivzzRzED@#~rgFW6nS=M{hL!&PI~954UL%I80OdQSa}AG497rG)JyZkQ3wtIYEv9 Z{s1RcX?Aqo7(W02002ovPDHLkV1o5$p!@&; literal 548 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 FV1hPQb;$q# literal 911 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 e-l`vGykI|BKFZ& From 1d3dd85eeb8e91c4937c55908d1a626f6deb8c69 Mon Sep 17 00:00:00 2001 From: Alexandros Schillings Date: Wed, 31 Aug 2016 20:35:59 +0100 Subject: [PATCH 13/19] Updated the app icon --- sample_app/ic_launcher-web.png | Bin 42415 -> 0 bytes sample_app/src/main/AndroidManifest.xml | 2 +- .../src/main/res/drawable-hdpi/ic_launcher.png | Bin 4174 -> 0 bytes .../src/main/res/drawable-mdpi/ic_launcher.png | Bin 2532 -> 0 bytes .../src/main/res/drawable-xhdpi/ic_launcher.png | Bin 5549 -> 0 bytes .../main/res/drawable-xxhdpi/ic_launcher.png | Bin 8948 -> 0 bytes .../src/main/res/mipmap-hdpi/ic_launcher.png | Bin 0 -> 1937 bytes .../src/main/res/mipmap-mdpi/ic_launcher.png | Bin 0 -> 1327 bytes .../src/main/res/mipmap-xhdpi/ic_launcher.png | Bin 0 -> 2563 bytes .../src/main/res/mipmap-xxhdpi/ic_launcher.png | Bin 0 -> 3810 bytes .../src/main/res/mipmap-xxxhdpi/ic_launcher.png | Bin 0 -> 5415 bytes sample_app/web_hi_res_512.png | Bin 0 -> 21456 bytes 12 files changed, 1 insertion(+), 1 deletion(-) delete mode 100644 sample_app/ic_launcher-web.png delete mode 100644 sample_app/src/main/res/drawable-hdpi/ic_launcher.png delete mode 100644 sample_app/src/main/res/drawable-mdpi/ic_launcher.png delete mode 100644 sample_app/src/main/res/drawable-xhdpi/ic_launcher.png delete mode 100644 sample_app/src/main/res/drawable-xxhdpi/ic_launcher.png create mode 100644 sample_app/src/main/res/mipmap-hdpi/ic_launcher.png create mode 100644 sample_app/src/main/res/mipmap-mdpi/ic_launcher.png create mode 100644 sample_app/src/main/res/mipmap-xhdpi/ic_launcher.png create mode 100644 sample_app/src/main/res/mipmap-xxhdpi/ic_launcher.png create mode 100644 sample_app/src/main/res/mipmap-xxxhdpi/ic_launcher.png create mode 100644 sample_app/web_hi_res_512.png diff --git a/sample_app/ic_launcher-web.png b/sample_app/ic_launcher-web.png deleted file mode 100644 index 73c663bc8116de6933a03e2684db80a8c4fe818f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 42415 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 bPFHiVXmOic^9iQX0Q9l3a5OJI?iKq#pZ(tz diff --git a/sample_app/src/main/AndroidManifest.xml b/sample_app/src/main/AndroidManifest.xml index 51d15d9..7eafc25 100644 --- a/sample_app/src/main/AndroidManifest.xml +++ b/sample_app/src/main/AndroidManifest.xml @@ -12,7 +12,7 @@ {dwIzJ@d9~)@;pKGuDhX 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 diff --git a/sample_app/src/main/res/mipmap-hdpi/ic_launcher.png b/sample_app/src/main/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..42b3aa4349a6ee9d55561017211f8e07245b4648 GIT binary patch literal 1937 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 literal 0 HcmV?d00001 diff --git a/sample_app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/sample_app/src/main/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..69a00c02fabcea86994dd29a9f019d750be722a8 GIT binary patch literal 3810 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 literal 0 HcmV?d00001 diff --git a/sample_app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/sample_app/src/main/res/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..01f553908c4e2edd74466b375ee7931f2b8c3e9f GIT binary patch literal 5415 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 T7GR)mfP$;~W_qPpT%-O2`=Q#6 literal 0 HcmV?d00001 diff --git a/sample_app/web_hi_res_512.png b/sample_app/web_hi_res_512.png new file mode 100644 index 0000000000000000000000000000000000000000..7419be120a4c51d67f57e98730e0ce020165de17 GIT binary patch literal 21456 zcmeFZ`9G9z8$W!_7>s?8oou1(QT7;HDr+gbsO;Gzm1Ty?8j(s_GM_e;tw?sG6e2s> zcOv_~j+y7Yba#L5@ALff`~lyec+GX4+i|>){Wz}}GZO&0t*3qd#>M$cx)OfpM-<#UA5Ns?bV>LRpA8;v4l}m3!(on>Gm=8{~HX)Oo%@hlkb}5$c=ePi=@TKrNv0_ z#cko_#&RXb?w?YWp4ta?^?TGaj^%^w4hK0*4<2aKBEKlu4u1A9v?8oWOcW1AH_rA< zb#qYGWxj2)u$f+u59Y1YhBtymph8MdYb;(~uKkhx-6!}hUP=u|hpP6KT?;i$2qo2w z1&`mDRu`Nd0LVAvLQ-9>&J;>ku5i$3$#3+Ms5C`k)h|=Akcr+>V-8{>KBn}K#`ndi z8imME*m`a>+wMPo{#Q^uolCz6&7RnDn1 zu^hTV6AsD`G%2I!yLL6^q&OJ|m{CF_2g46NueKH28`_=BVG0``3U#^aH%N__sMGk6 z9gWkyoD-(Fd?fvkxZY%s7N$wv6OnqnAZ$)voeDJR{&@lVxUkzJQ6*f33!C$u@X}I} zWWECvLN@%;9X$DQeu(kcO`^<{cfb%KqbRL7_XXrOxO&u-Uu-OsRSJ7^sqV{HZCKOH zu}%x2X!NSjB|U1qpTeMYA~!*V;Efd8PSbiD7Ch`K9RX%de2DM1TD=$k7H_F%A*+5) zc7T*#7K2x#!;ds+4W(=O?42fFWg4|ST6$jeVgzqt)r zh2A$HuWP-`-*)RpPmT_Au+qW+@lD1$oxv7XNI7s>Z#<|kxR6%woO$C=fWxCahBswk z6wY9v^6@=VR7$z*y6EKMuOQxRn2(1< z1g1*aG$D+1FV8sa#+Jm+j;}ndQ;X@QuYBq5f<*SD^eieQS60l;Cu1|J4q6|y`fh~1 zK#iRkrPLXJgPj~*+}Pxvg_n8>mO`dx+gRgYwZuw?{z~?58rrn5N1eBaZYYFR z)VJRbQ}^`2{UVu%da2OC*mXv~fvk#hE?~C$R_}k;8s5E6)pGxz&_St3bZ?$R=!LiI zEuxf?jJ5dmwxg$RZdv}?ZH$MBaY`SXNfkznmSs54y0jA~lCM#8pX9Wd$(+EYvBe6# zg}AP@w{}v7f`eB~r!Yh zqVbZ>P^2a)@WqQ7!M*5vw^j!;hRMIDe71L^y$k?#&eYtL+O31M@%Z>!hc`LHj^40{*-j>5*{7ahtFd7NRXk3mH4gr-B@ z?w6m!2(u%sW*i9lfFTD#@@}(@=}=``VZ~k=rQwng%mhAEggfNL_>naEGZtSbXz#F~ z^6RPDQAg()#5*DAr_mnEOA4+$?VgSL;Sp|LyNbR3t%6I`@W`vE0A8#m%FPt;AzFjd zV>ww%C6{}dlW+#<7&zlVU40fuc5q*tAJE)u86Xxd@^8R2mDe7LZ^q}xRqQBd&{zp+ z?KWhIA_;8PP&YNUyqFT{x&BCVyZ(-^RNW~W2;n#u7s(0}MVbwrigXvK&Nhu12>#5y z-660i@|@-Vbj@&YMD;r~eyJa)yHUQrIBB0oN+`y~4NH5%qT-ldUF`u4iY;*@rBEbS zI-eUmZ+s`x(czccu_!Fvf?eT~sh)C(cYX1}A&c6IbrUEa4VQ`zPEU*^${2ua>q^F9&X2!0}A#3!QK+LC5nL(aEPP(r?W;y=wO>5 zja}RxSZ!ERWM_$m0q=OR_q#NH7U}4=Jj{n2Sx)&GvSpwgASv~(L>2}M`iX?R9z?R3 z$lA^2V}(Z5AQV=c*~@Zo_{?5DCnUGB;gG0Y!U$dsmt+Iv&BDp75NY$cSfNxp-!f(b zJrDk8J8@)GOP+dZivf+73==KQk`I?)wjAv5ckR3EP}_1P(8%Y2YIy<5LdIvFc4r8ww&?6Ksjlwe@-xGE)sd#ZDyA|=3 z6BWtEje$(#H1?!8ARoRTP)=+PjqfMsYG*`i7}-G|P*W=k8cDMYL|W59lgHK(4&t&{ z)cF%GCB!?ZNP5WL`ZWv1SD4Td2wh->a%U(%1v#J=5r~aOElS-$$PhtL#w}lVFuAN& zU8+(&!cWHt*6|UA((|Z%?V&pzl-wwsA*68|s$Vwz+$xTCl7ZG<=iTT@S!{NZt-f>n z=<^VyE_Jm!4K+5A+O7M*DX;4;*9brex_l@yh^1pl0%?(%bHY%F1wr66wVi0(QfEbM z-@4zHAtZkus!$Yx)HskLkiWlo30mF_I&cxm?F3;URaN|@c}%?_gz7-B|5A1qQ>#v> z`S9`vvW5ZLyN)u4Mg@==0R9gV+}_mKV^mAZ3eY#4Wy$3asFeedw)n`zwlPnSUNQ@6 z=9J?b=tj3Z4XechR4fK+SZat0Rek)W`dt+JW_Loh8DeR{j7G=?9Szm1M)Vay z%xVygF&=DQJ$!T?bNCE2E#Of0vPkcJW-6qPz>96Ob6iHo0oukL zDT$y%>eJ)He?zI%PnXnB9ymoPgwUx7)ym`YNJ6#M*f~u718f^os2+7M&5&2fP)p(Q zCE(~QHuHGX3zgC1c_Bsbn#2n9Lt$v`Vh{GP+SRrm$j7%Avv1As_rWS6FojEhE$ z@KelTL+H(Niq=Hq^0l;frx-`^Dksbf02TbYzLWDy0eN$Xx|A7VhH;Y}rwLb}uEvTx zCdsicT&5CMeoifA&T3^2xvdjpArI&r!Wef>9f4UuzM*LP`|=3!;MdYsJ6Ms<4A8d# z@?KT?C;VKhsPOHlr|AN?piyu9=X2P~SoYGR-Ej~rbebx4TuQe(0z$v0N=Unneq-e5 zCz=gHlOK9iJdk2uHHHC|gNB?x%SLdDAo&y|S}#J=$FL==iG{YvWJJBjWo``e8|M8X zXf2`0x^?SjC+fg>Xx=$A0)-WRGH&x<1i?-2;y~Y-CoHIR;QY#u zE1>W^mX6WX$UHy;{Y;2~^)^!spbnd8<17k=z39Z#eHtlC2kGIHg(KSlw~xZ3=ovp? ztB)fvMzrZ_;2aFgx0#NDy7UX4Nbn`L%&5^>1RU>m+ms{LwNb`o(Ymjto4k=m+@cE zA?dFiN_XJVcc}h58Ys8Zg+dHx?=tDaPf)18Pu|f%&bPL8tN80?z_NFl&cKXe{>zy2 zXQ9L0tBaeH!JB66j>5GbK43~Cc!mMWZ! z2V#xxJtpvYAp*c)^e>fWM4*R7N(`ykIxNE_OF2HUQ&RljktVQ^w@TOROmx-5`v8%} ze>R#1nf>w3x>q~U9cI6-FB$xNlCT>qYq?Xg-84RceFi(dWv5TdO-6YbN|st_!zl= zkAZA?}7VY1GDccyzR&Hh=FUkk*iT{+t;L z9ndc$%+3{lkZ|=HPK=bG^15jHtoxziVA(4c5Z2Rvv{h9~%%k zM;3gRUTm&grm;&)v$&~W3znKZKy&?0JT!eUic5CQ`HOugDnQ~Js~4;kQ8X~*AMmYc zEv`DXD-8~lYD8xP@SlRaRP8mdvSFdGar8T=uj60OdhN^3zT`dNDHs-imd<}9oygPK)2e9J~L z(ybYbMq3F(V|q=kR|2>`Cr>Hg&ApRcm_5k@-uE_uVGyKSwRO?dWLT*;9ans|NE|yn zGR@v9au=HBJUUMadlw5SVb0Lzd%FrlKW^~Dy0nJRzn)fuXZP(;J2@loy$%BvD*}x_ zNMx|ooNN40_?B*(^~$;_n0)ytOe{6N=RV{tujG~*t&(>x$b_fg0w5mzP!%Rcc6svU zP2=ANv}-g44X~8m;DYC$XKGWW2rfME>cf@TYI>eD53?C}(Y8QU&r0dn-aB?MUEoKW zf2N%4P#oH~BbeGM9y$#9R~QOGV}6p8Zw?uU6)3!4Xo|=|-CpvSi-4779rrM@|ecrZf%De`m@J zvP1#3wO04avk(J02am+h!V2MXkuWW;I@wQ^gY>O(uq=-mn7~d;!5b+Omh-)d#rI-o zRc&E5jZZ1P`hLdTHsMGIFADo~Ey|7$KBP$5hn6YwVDhyfY42uY|9rO>mGD(0cJIYg zywrv-2%<8fL3KwCMdV0`e zIGmhGDK76oObsux7)dRM<6*cWkk!#r%mY7?lRtf2{Uum?F6%dx4ePfOJND`!#K|zv z1|=$l*(cgJ2>EdY>vqFPt)?g=am4)+;W}f5)9E6KYcdQ_d@oC7e{$x+U}93}V-b}q znK=>e%nQ!<^#Fimc<>MGKeW_7OaEZ6dy+S7i#FOqNk1XodR`OplN!G>Cdzk1VXu(s zX5;jO+sc!Za(2^=zk|%#6WKC%vjC>HFbK2fQXjwHZ{Ai$$~|;5d|+rCyNngcVJrVp7*{$WrTq zJLkkZ2(5r94rv?YF1z7(RqB!^2T<7ZG@kg-hTHwhlnGEt`Mx5vyLOouLl&qY3yRU z^X?FIjMILRUH*bT)Pb-j=RDNnL=r*-8Ey9U`bH$<9LM|IG#@`3ZWX^O+op(j;?S{o zc5;jrE0-J+GMeo0%bD-CegV~3*sy&Hg>A+ca$np<@e}oRPpXzsrNeq^vN-_DL5;5+ ziR#{*SQ+G7;WS92-t+Zc#D@i7Ikk>VCWJ$WQ*hHWu%|*Q$Q)m9-g2 zRwdGvTxJQ&^4e1rkz>0p@oVDjdnB7fF#Wb0LfqUY& zkDzuQokBvufLg`{Wdz0v>Ah7^E`rV44?pTR(h|qr(0Kk)aXwx|;=PpbFOIXzyQf9o z3s_RNW1uRU+7&bOG@=C_mz&wuy6WufK|xR7F6g}FJG<B= zCKpAlToDA#R(lk#AgkP#?kcdk45>PG)k8Q_e?9~vk+1J1l_>OpO);!ugHELzz%o@N z>xWd38esv6t=Wyff6KqKP9WWsm*id69@xHRdO8dsZskgvuM-NZ<0#9YCo=M5e((os znnoviK{DUkY>>J-Wq9%X_k@int&$H`7gi^8f}hgJ@2TGfOgRV(y3^HY6WV*b57U|= z&ZF*SbUe()T?o14m_d!tJKUBb(aoFWCCzy>b>s1qs+UE9^2Z^4%;G37FwY~-!IDTJ z+h?y&^7UY+&AnZa2b_4`4uHrtgZwR7aG^c1YJ}_a`9mx|_pVcsmPM;VQecidGBAOjNOy4;bVmL$2Q+{KD59TfaW9PBvIF2!x98pq~jEBeS(xR zaNv&3Qc#y@?glYzIq>;5?re4#HJ}&^Jo-7eZh+J%oo%`G+^ahYB{IVa;ei-vXDPER zF6|n5r-Hbq?O;-J`#SC$>GFgx2MWt<*1;45ovLg4U1;ac`O>h$r1^uj8HhNhC>_Zi z#eqT2(FQw4uV@+R@04}3zwRSJr1$_d67^(!lO)>75ZIrVN80S-Iv7a-At7~$EE6GvC)CJ zzyXzYF7Ec1+b#uttEsw|)|iG93%dbWG7t?D+@F!hjq~H(w5O2RLon)V0X7WSR9Tlv-gUYljHby-TEj7EISI9G^ufqNTsms zNx^o-llys7#7FtoZ(RsA0pBezW~IZ}yFR5D?`bSna=ekKUl;o&_WOl(we(laDj_1I?72c|^U$w%BhH@GC>t2bV^K zRITp*%jd3{94e*tiI*~b3SXKm5dJ;)w#s2Y;^T-<>I=Tz=``Z?t?^NZ>`Zo6fZ!+? z!CyWJ2Ld190pwd6bo=D)9rZN-(dSO)$379othnMJq!8z85oR6efOe@!H_%uu14DzU z_zuov&V6H}f+`?;k)piOHko?GRe7?Gxbl0+GHEzcuQ(h!bw{e@Hps2C=Z^FMvVXyq zTDw<0cc5u+vZTB#MEhz(U^fdB)0dM4?f>!HiFj@IH4R6N6SzFYh7=NiLt@c|CR$4T zErHK-MPN|hEaT_^jSlepnztQ37N%A1t&ie1Dvh7|Yq?Vz_6{E^6-Hs%Y)TKt!I%uB z?G}p|?r&~;hhdB26lnQDVd#j%2B2F-SZ64j|t>kxTrapHCLxU1fO7ef6s;dM!+Sn~%t82nVdQ5)i|jjUW=UJpqhzIw;XUys z@@h&hn?(2a)!^arsbiC|25u`?L?1BPzyLo0n~(E#7!XZv9#M|_`ELB~*rHyXqy*3t zH1-q@7GkVqK!`=aQf2I~piZbTi zGv$@a7k<~QXHw)w>Ejc?Q=|Q-9hmN*ob1<@1(i}>E34xMhqoFZd)zh91=21HOZ&U4 z^;L_T6AyErFuzHSIzF#;Da<@d^Y*_g%g@sT*(W_+VtS7I2`}LTd(p@u zztYChUmONMVAXM8e=?tF7o@o7{4bO1U7IE(^|?)b@g`Tp;jOPK{vZ*Fe~RCCP);!V z-K6^G){Qs2_6OCok60>94GSDF_y~K^>~KJw_vXGZ;2Yz-|I`SL&iZnDYS6p+P}3)d zQAD*mtoUXERFAsCd0Pl7Ak=fm(79#eKXjrF{j&H;r#6NAd17rtE)Mr94^Hctz%=M= z!OU~tXn*Yei779+xThz}WJq@8A}d6VO$eexVKq$nAF(4+sV7lNHJ991l7)>T*}#cn zko#l1F@yR`a{^WZjz^InM;7admotd^!zx$V!Fgw4%$)Vn4Tu@plKIWuLSO%`_uRFWir01<7;2pU(foN}UR~_|B;#V(2;zh%PaKY=rFJ> zU~he_Ky65P_a-Jiq@G|CI=20tTIx2l0W9pA@c3}y3^btfwIDsj1gmge)9Yf~K|7vn z-1`ZfeWlIFlYo!KD;7(zCti3s{kZCiYhkv7g$9oV0*EfsYWpBCekpPc>x6ciOlaUb~8gw&0i0I z%!Pn<^UPC_4RgI?%>*Pc_R#o&lXw^H-)B1}Bu=O||A+<}STwPc zsG-q`sTWiPK>P5)RK$fpoeJ#fuVWEk$cOLj&(GT%gbJnq7^}%6g^nCeP&RbTj6b1z z#nuD)v2u~_TAKei(I4AsOh485A_1sF|7?d7_0hC?*|sx?OM9?q>PK*@KUwGJwkxaY zy`=xw0ol2MXQIESfH<~&l>gzAPpL5LkNshN!68BiqECWglIaK5`OP*&nw_{NvB&|G zkQXe9)rmQDZkI-SkGpdQ%;mf$JrUQkj>3#j!rY?mI)6n3I(KROkR^JW?ens&MX@O` zIHvm&@T+O~(UY9Y3^0i>?2*zlevboAe>ctOoAriTH zBuY*ZJeneQLX%D(+x9zp-~$hUAk7~L-ed=SdOc?q{{@?|N?c)WC*Q1N9G}91jZk$4 z=!!t?e&f;xbki1Jl0UiEpE3x=*OEOCQ>WAxsopYqXn0? zIrp+&mqcjYk}!E$Vb}Knlr@$aB8*EhJy))n=JhwWSyIqRd){shk62WfgP+97@pS$P zZeW#59XWB@kgyV0PC2X8x4!u1sj(_0Ob`3auck*8gM}ubaN!zL~U9UUI0n*(0ATE6p#kt;$=T4^`@+nSkp%s)io zs?X?G|3h?Z5Icr!5Dnp0WC3K>c=MW<9g#@SCsB&UPLc9^3xz{vFHF8fl`poWt&B%~ zN4@-7=dKU3rw2|4_gsYoU8F7mNEg|1@oanqvBZwK>ZuXd&Vt`k1c*?~Qq)CW*em6J zz!Cngc{^xa*BFG>q)IxV7udbcKy4aU9o86?>D$lJ%XQc3$zuf|-SA^RhdH`2Zu|`B zwL6TswQKlCLEaL3KUMq8?nAKd$<1}O2mMpCY@cs?KR3nqU(9*G4q(&_r`4$=*L1Lg z5-2W;C3U0D1N2C7^h_oPC-`#B*Y^%A&)r&6h%?9l{cx)_PmC)O*wb9OSZ;~WkEBAk6$evuZ@3Yv7R4!z$!`HbY0e+wWx zR;wwZK;*m12@q|s-H~fdW`(TVopN;0(`gj3^5rE{`to5e)j2NX(rLtNss{z*TZ|xh zQMl9FZw8j!^1J>S1-z(qfm6F#-|{*THtf|jI_`A-7h8a$I3fDO0~F~k4)I6?A#LVy zLna4E>-07ZRDpreQ~br#{$Y}U+2?y!ROo<=Ua0+%jt54e>mU=4b^ZqV=`}{0&foYw zA4jTx1|UUWS6GR+{ZZn-^?=*H{f(w6V&zI>y#OG>k30K`cKMeAi1~RfXMb??$i>Ri~-kc54b8L#Ln-~%ffhvn#n zbJ84apwY1yI4h$Lc1DT;6U6TDKEFopo;&S>i(>^;=BykmF$OC#!%0>B6HIL$lU6TK?i-% z@B+7Zp0iM{ee$XA6P*nl&Kt_*r17Y$UR{)6A9=^p)U#jjf=|&|hnb(peOvgr8Q28s zH6pZwdYMo+$)))sc$xxB`SXL3trK;jS{>5$p@NTZ(W3F^mZRigGQ`gC6;NEB*_9~T z?vyRKH=+2CC;x`J_pDO)KvJO9K<*y=k_Vqoa;C?&9d2C$DAA&ftC8rR&oje(=Eu5rH>(z9Vr^d1XQ(xNRaUb;xUw z1Elok2Kg75{znVvaHHH-*s0FxGyh|4rq6Hv)k_G9CGgLJ^oP|GmBU968LL{syOBA^ zMSef!Ulc)r1pAz)62`wR=x+Z#=rI4yECyI5JXec!E27*~2Ua^!gLl#7qx@3+Q&?b9 zslSO@bi4o@+%Gf6dT>8C4hyS@N;BMBlezve>C@L8`M{&W?Tc~zzM^1%%U;dDWkDxG zxUr@*Qb<*?c^V6=kcG)#wVFF4?ap4Vo>yzgK0|#EkEoa0YP=P3++kBdkgPt!hKrpO za5~SoAMgg?KPY7hl;MUfbS!1`hM^)ovVk*SN%JZuPZZIiAa^to>GSQPR{riECcu>LOT ztRe)%J=wvgCJ$Vwp#ZR8$y_-m7i`&~*qwgC^@)#O13&T(kLM4534pYC|1F}?Z^A(A zUYvJ{wb|{>)W|=QHF!MWSs&=5)2sg74>F==yC8BM+EiDLWBng*Lr{pY+L1E%%R8y> zl47dAc3S0pE2MtHvAjr1HnXac3Q{T_{<_~8*;dyp^K|IrKMu(i+E zW-^SQ9(cNXU#){0K~NGTpEVU%wc+kr(>Hn2|4?ypS>N)~(pw(bWBVJf=lRU7W<0GS zZqu&WvqBz=;eu{ng>y5mUqT#A%BZME-cio=$3v&$WoOxel4j2xxzRT2{!v_z)e+UBNa}kZ?V<_x~k(A=|*Ly`A z^N0Bc{n-7wWCO~YwFV|6nju+ws8Y_0^O*Zps>mVqb^O!wn5DP!FkPl#+4_K1a{%0EsUYVR4HlHXW0|QW8*V# z15GCczj(kWT4`G~h*o(j=J-5r;>U*V&W27wEL;zR3)Lspdpd;OI0FXe#0^owbly^c zt~ob!_K%$-9PB;!ouj;b8`~P8C4=eE`H-Up5{M0_l`*N)zJ-M4+wmEP8GoqFFdSq- zn8`0Sr@-E!zF*{Y4aLSFjWliJH`rd>?Ljg5m@N&_yf)ID`2H|sKzif+Zc+L8ksud2 zQta-ApBRW!>GtE)16NLEq>;V~+kxg9MmNp_5^O5s%HY@ot>OaQh{T6aYU-|j9=7f; z2Z_&)s^MpC4+Ujoi62aPExWWq@nlcQYdyr*FOwFS_7rOq|28GI_<6KAL(2+W*n`$sAeY&=j58G`jv*FkS@ zW4rNZ6UVrK}gcYuej3 zs7lEnZh!cex@FtoZMQw-Srsm!NXZhOO;|W_u#tQ83vGz%*r(Syb8_P|c8Z+9Pn9;( z=f49Tj_^lxw?a#|?qOU;N?Oz{1I?HFY1dG9ICt4fdbq;$3MDRJiV| zU1PsOkQ=TjI-(Z;weFApfMrdjQn+uzb;oruy%@ytABnpY)Jo?*1vWt;A-bk6i?iMv zrxXoRwa3OGSmj9U^C&|Y6b3T(^Qx4Xpq`ss*|amDXSxYDs=WZxl%Kw)Q29)ZW-f5O zyaNi3Vpt#CX_#1tl)p|E_1`MiSKf}%E%8QN-}~hfUb` z#uRkzhI$OL_gE^6j&yLQXiW*ex+sAlP~(cjJ_zHK#jWS8Rc(|b)k0{lku6B9{mlQ9 zS!5ocg>$UGJd!~$+-N_eoNfpjl$3&tB?_ws5{vU5>Eb!%C)UKO_yf$%Z>-8e*MFvf zpu_ms`VBO`bGkwGEF4sIG!2oR!CuEdsG%X?&0fU?O_A1{D0~M<-{@S^>Hzt+s9{w# z_{X>O-HftL+4-%x@L1~t7nD}jpR7+?&Zo;Iw=tQRc4VuNBrxN__doqVb+gmyl-_>j zuirH1Z_So{xKF;pHQ29pWJ8hx&*C%k9W+|h_jj9|`Bu9O3>gS7tv@wHp0G-K08%4j zC3B{_kWC^o(a$fl)e%MHB>iqbtC_$K z3#AYYzdpX_m3#R;gH6shAk)^6VXT__5(rw!r!Z2%i$%`8a{)cg0qHZsMZ89#%S zDJRUt9Cx&FSZt6<7pl5WY0W9Th8nl?E8p5{Z3j(jRXK8_VDUvaw2B&rd zdxv-Q%>&*(UXLJ3GJw+zuicHTXlw%*bzJLLJiKMNR5;oUmkg@*;nIi!avR8{JVgq; zlF7~pvuy@gnPc;~{*-~xRo4t$`l-MzZg7Mt7{fYFoADak-!FPAZMS*g2D@5bfn{7E zJGre6W*qJN5BL9Zc*Sp|{cjMjpcNM%s$h`nflX0_%Ca*#N%0GYfwQkNU;2=3mJEW2 z+wGI`LDx>mwm3H^-9Q!>qh``6s_G@XHMz!NuVwu6NAl0`KwgW%<5Pq7Q~BjP0?KLe zp({J_M~}n#TM)*GmFr~hwe){)iVp?b200p|(w3$OBG7SOi|RqckvZyR6OJY~w;LaC z`OEX|zI-_~;ttMlq6llRlWG=)Z**S zTOR>iMXTpb3?QdEg|1V>Jrx%ql`r7}Hi4p?Ud>~dqlhKVexMq)b|P0?3kQ2XT+(Z_ zO3^mGg56U5mPg=~7xW-*-)~8Rn@;UNKk0*{)T|oiJHxx}UxIhS0}&%T=d?iXdg-?L zCpt8~;KWkxIxBS2&Tmb^Mx=Ty0AID8dBb2`kjzW}m>RE1;!>-~&a~JSJe4dcN>mX` z1?>i`{kCH7R_W6*1Dnh9nndO<~l_CKdl(yoIiMrMnDh060dk}VLKyfUp|~fz zX}<$MXF9{m%|h z*^G6dhv>{Bkm6F5;zacQn+iAk{S^>9OWopH$qVngYldx@@UwioW=m6FO^ugNia@ch zL!+^<*}iP7yV2j7Y{}JTKM1NBDHRW0 zd65K-jZWyvrQxnbf^}jnzA7S>`aX8UW741i1?T*d%xcoC_1=``xl)t?@l8;d4^ z)2vRQwSc`XikP=5F`t=kFVh0+Lv?uSF`nllBmIKQ6ZhtCr7^qhD6~GEAK0Ba0gMi4 z@!^X4eAZ?@pHEN5_R*Y1Lf+AR?;A#q$W!6r?I#kT881)XOnF1~lDBztS=KYdy-3k` zC|WQI2m^F$w~n?pNd^XU(tbsMB64~LWY|p~)3w5?XYnJi5-^C|2u#!iGz;ZMy2?8y zu)x#z`!1B4?gJ%;ch{0LRqn7tgGY=@TT(>5UyS6dA4zaCg!B6Hu%ilEH3v1f8q;nl zcy%v4#pe&UAIK5H7}lPgTusEk0C@{ba77v+*6zt?BQTJ4(lLeR&w^{f1n@mi=z0}4oMBvqW9tUD zonF404`r!}iNZZl8SA;UpO~VBIZ$v^4|EHW5T>$QMpqm&D4SQyvK?$v(fEHRo~)Yk zolfsgf|K38`#y`h?s=5wHp{agyNcJyr{9V|7VI4nZMwM6>9}_8u`O8`UOIo<)IpJ9 zl3How116rM2yXWM07C@s!pA@&Tqj227Fa*iB1_?fZN%{=0t`KstOC@GEEHDqrU)qd z#FcO?JY%V&vEpH*5YzGIx66}LJhM3`9H za0xfYTaIKuv#XgAch^yT_BGK6-FX25#d=#JxJ8&ObUASp?sL#X!{>*a$<^o~da|_M z#duGc^-6z#E~A6&XM*aRoK~d2Ui8|3cKq)%H9F9p@S=RDt$+Cc+g%+8wQf|Eb^1{A z?OLJBZ}r0H^MQ>x+1J(_{T(+cx?`Uq75{fziHCWN?}8wcPR~)K2F7 z!oc?s<{>}K!~H(>RA^+>NBG_QOaIms_tz0aV3P$ISno1j1#EdjNB?)v;I0qwJUfkG zZkqRC_Om){|6K{(JQ~Gq-FuyLxhV5);+M$7uoOLkNeNFnQU*C*5o9=fhp7f6n4i#L z{!S{(09)lH1QzSB_UbRM6*&c@)d&EaqxEmE)hX1idaO>f-=Y{vm^eJS(+XKHsGsQ&T276uqP2N z3({Z;d60-iCWDi2(TJ-^Z2xZ9ss%k+lI`LE&2i{8e8HeWfZJRNVTi=5QVL##&ra#! z8L_ff9gMM{#vgx8(y%%frX-b*Q!}w3++vCkMA82qngNOJ-WCj1H{6r{N~JXMe-w&x zV%ZMcLT*vS8dv!#hqk4$Pe5650A*#qQ2nHU?%@&WV=+bh*!B^1R7uznsvep!R@vA> z<9ptyyk|x=ut6Zj6L0%uHDC8$7x^HN0=WNu|9T6S2RZV`II`dv$aRrOKudZ&{~{Y2 z59?@gR4ga-*Drr3jxRNaY5f&;g7<}4gc_8sws&NVt-m!Ask^V}o&~JdPg=MIx&S| z72J`vI8a-w$w`W3iiD}5vTx$SRUxbea-=}4DrEjK2xW_XEqfq@E_~+nKjjKAI|D*K z@N9OCAow~2;a~Gd9SL7(eFH!SV$aRP&@mzp z$tDaZ=m0LJX6a7K@Es&Z9_d6(ObMKXS1}VqNnTCp0Ga@xsA-Rn#zNUV_9S3?EFQdjx)he0^s)MF>3j|IGTTKgOFw4u2WQTTQ^WRdIGL!t*uB6o4 z%!b8Dm<@kZ)W5RVxSj4#Tm@-$t5WG^vZOMReM*LGc71un>Z1i{f+lO zC`0o}G}yK#a6OY+r6LV#eT5H4yA`1hp15@P$8mkQIt-c4U?aDJJ6n=Rryq9#0M*A{_k1k?f!(YPi zO~QMV3jN!8*UQ+0HH^r}a}V z$cX%;VlB#2M+R5(4cAtT%cb%yU|Oo)&A&o6E?@(9fX#%LVqQ?phc-)Ro!80~gpema z&W^l!jOMOKmPCI&%5oXL8y?n@m+1vBL-BH@J86*4yPGm93^Un z*Vj07ldg^q7ZNiLt%}bmt$Y^O`h1JBq_w`dM!elgER=%4z06B#7Z|5A-GoP$kXZfd zXB|YzS??Qfa#ouy&Jtu<8BJ+HcMv5gQ3_Ushf}fgQ^c_gK-xaOBRhl`O-vGvQu^yM zIC>}ZlOgmXlDio~1&x1YgFi|zeXjaCQfLdOO~gme9o_T2*%-W$5;!DV@UtxUAVTz` z^ZTFFYiGHw*0_>qVQkeWSM#w@EcGsSM^T1pruGDh7T$vDeoMKUqz%D}c>_i0^A0X+ zijsW@df`$6c8_dx;rD0M==M`1?LD@u4_kN5W1roHMfe&hq13H*&=;on?+ML@KR3Z z2ORI%B;YzmTq@f5g{3X`J+Uax6en+V=O-Q{sM2&Iy7ahkYHT+T- z(ua(@+K3ZSG#Oe;5OAI^j=R_995Ksi!r*q&(YI8{kj9YiyevJ?B91qZNwh@o*=&}u z(An;XAY&;L>hgGC_4e{ggTuwE=HG`;Lw6LBqcb?yZc4cZHHH)VOpLOm3P`0#KSt%L zGQGdW`#G6Ku%OiQ{q`a2sd=0-5QWOpE;&cSDc{_#yAi2OH(prDd$2j2hmVP=&%`dZ zE(#iL=3}h4Q=^qO+mtDXK?yQ9P!Kiz;Ak^)T0(8ss;Ij$CeCx+azwcZsdZTp z-&NwFSK@AO?XVi90(^&%m8`AGBYXk%mi%?LMps8R* z7!Z66Av{WjKmc7HoFd-vQq_q*S@_srR^Q!aQ={bp{+wU<2If60-Y z=A`W=*UTvC9~9O?ii*5{H8pU}V{I{&jwQBwhMQPLWAE2Pb$Bc3W(pBI8QvEB$CghHrhMRs;P zGoa*)@=Kw;Fhxe!#iviFN*?|;0|gxJloIA9%=vDqJiVVWpg05$#t7!Sxlia)DTr4j z7U9Hy;Lo#-TFec-c2^=>5TCzznPEE^g1g2x+|5Ef6gmzx^(E?GD?(Q$Z^7JpSdH~m z>&RKFlJl0)o3G|Y=7~b}r2B;VMJyfR@o-}z)G={2&c!Zm(NFfWamv{i#Y-N(g|}!# zP$$bFwZgL)R9|_Q)TSYWUH-t2+wre1Z@>p3a{%V&Fe4GvjMY$L2rE3_8s({xPvVMj zaYa{>!j{I_K+CZ?Oa5EgzR9Q#ZMwzZjmi+lX}OSlBs=a|h3YgT%|>{RVX;NTLk5OZ ziTo*oyuk0!@?aBBNn109xuS&W|l9KEvYn zf*rI?CKBaBiR#a@55BZ;L0S6-tK!hTsM-t0H1^MgG2~wVfOSa#RiiQ^?Suk)Xq*D>-RxvP!Pj zGGiWwEggTF7}=?s6LN7mlOn-|4dQ$ew-;*$7QPQmrXslT0t03~RBNE>zD%V3N4+%J z263Oeh_~Ge2>lc&d-CR>*?`oA(~g`Xnt@@gy@cM6=0>83(UuOgHEW_?WP56o+J~Ju$O#S|-=1t2JvLh=dNDf~Qdj`2JVvc3i-!D4 zJa(xpKi8m}<;y<3Au0snPpoPhRu(*EXWH*9@hwI_4b&XY!29ZaMvzSq>#Wn6e{&n1KZvJ@Evm-RPTonCV^gGXj^dw-95uQ&u=hVZ*MYrD!B3i|ZQzyp@S= zAW_E}cX~O#|G==?<53e6O#}s9$+(Qcs;(}v+uoH^x{23X;Bns%-A0Lyxg#;SD#9we z$0w<6f!W)>>P$e?mHa9FA&jpQ#%DLlRo}Mq7pcIAAJ5fpU?D+11n<`K@7traR%l0@ zsU*!5KLP?WsCRztwggo^<~x32k$X_K@%O73Qu0O{y>2%gezk*iRQ0({(ZSKF+ff&( z=vp#3ZeYrgE=AI?HGy>WuTfK3^c^=FH1>lAY3d&Pek{$Q&PsG|m!Z8Ws)U79VMuSR z8UIukVtme^=tI8I&H^wKB|SGRkzwnvpoJQ1aNV4+L9W#CBt_)MWGG}9BDZmCMl^oi z6viW_G~I;v5hDO-jno*Tfs1w@=LUdMq!+S%+WA%9x~FIc(z*M; Date: Sun, 4 Sep 2016 20:42:48 +0100 Subject: [PATCH 14/19] Fixed crash when selecting GATT service --- .../uk/co/alt236/btlescan/ui/control/DeviceControlActivity.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sample_app/src/main/java/uk/co/alt236/btlescan/ui/control/DeviceControlActivity.java b/sample_app/src/main/java/uk/co/alt236/btlescan/ui/control/DeviceControlActivity.java index 96ace50..bce6683 100644 --- a/sample_app/src/main/java/uk/co/alt236/btlescan/ui/control/DeviceControlActivity.java +++ b/sample_app/src/main/java/uk/co/alt236/btlescan/ui/control/DeviceControlActivity.java @@ -79,7 +79,7 @@ public class DeviceControlActivity extends AppCompatActivity { @Override public boolean onChildClick(final ExpandableListView parent, final View v, final int groupPosition, final int childPosition, final long id) { final GattDataAdapterFactory.GattDataAdapter adapter = - (GattDataAdapterFactory.GattDataAdapter) parent.getAdapter(); + (GattDataAdapterFactory.GattDataAdapter) parent.getExpandableListAdapter(); final BluetoothGattCharacteristic characteristic = adapter.getBluetoothGattCharacteristic(groupPosition, childPosition); From 9ba9f2728b08acd6171d85e10a09fb015ddc5bbe Mon Sep 17 00:00:00 2001 From: Alexandros Schillings Date: Sun, 4 Sep 2016 20:50:37 +0100 Subject: [PATCH 15/19] Updated app icon (again) --- .../src/main/res/mipmap-hdpi/ic_launcher.png | Bin 1937 -> 2407 bytes .../src/main/res/mipmap-mdpi/ic_launcher.png | Bin 1327 -> 1710 bytes .../src/main/res/mipmap-xhdpi/ic_launcher.png | Bin 2563 -> 3247 bytes .../main/res/mipmap-xxhdpi/ic_launcher.png | Bin 3810 -> 4963 bytes .../main/res/mipmap-xxxhdpi/ic_launcher.png | Bin 5415 -> 6851 bytes sample_app/web_hi_res_512.png | Bin 21456 -> 26244 bytes 6 files changed, 0 insertions(+), 0 deletions(-) diff --git a/sample_app/src/main/res/mipmap-hdpi/ic_launcher.png b/sample_app/src/main/res/mipmap-hdpi/ic_launcher.png index 42b3aa4349a6ee9d55561017211f8e07245b4648..2e1adee48ab0f9d32a61320680d38a5c64c620da 100644 GIT binary patch delta 2397 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 delta 1309 zcmV+&1>*Xy4X+B2BYy<;NklffOmVO0wGcs4=a< zM*S z1*4u4PRpnPqAZdRM9BzRUqXralTq!U3HF}$(hf@x5j zwySHU0$3BG=Vu{iybTyn02G>RUH;z3IvAa}F0={Jl1u3jYJg3DegG0pz|?tc7RV$Fg`oM*tS;q zhnQ>tX@9{P8u0$30xK3fL!<+|bjZLR^T?jzZ+}wYv0Kz1JGxFW8ajM>Ay)ui;w|I)hR6kg zN`Jgt8ubMcG=NIH6nJq2c;ZhCIn8*g!vi8H05|b6Rm$6{9YEF$@|o@ifro4!gTxw5cX*JUJYg`5G%f~LJrV1G@;SgKTQ%5;E_eq{gRB~=g}Xs#l>v)n8x zoid6Y;Jb5-C3DH2*40U+NkA(ky7GFCOd#VJTeL!`vXA%$Ti$PtEd2ciw`P< zGP%v917s!sS^>yfeAWOrRUQRIQ8u?x%R80_;tAlnZjV&y=2G8#VB_%$%!?e!_J2BU zX=$w?ti6@+*0-FjiL)Mdfc`@@=&1cw{dwJL8Z>q+K-tQlpyh?ZMm*VKqA6z$=)&bP*(9m9={Gh37G3BGV|6>%D);^aTDn^EJ9&d>MniClO_K z1{i~w0pLcIEnkc|C9`43+x^wS94rXg`f(y8aPfQ$XZH^P7(|q>r1!3!8{OSa8ou9} z5BRHz1MpD-cWsDc^_GOH@$PO-xmkvagSEI9aq$pa8&)-SYQ=ep&*1lI4;Ju04@k3Z Tc%gE-00000NkvXXu0mjfZ*6Eb diff --git a/sample_app/src/main/res/mipmap-xhdpi/ic_launcher.png b/sample_app/src/main/res/mipmap-xhdpi/ic_launcher.png index f36a820ea21633662238bd24b33bdf509df30637..f2df588749064159be49fe8216bbac5ce04f3094 100644 GIT binary patch delta 3244 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 QkpKVy07*qoM6N<$f-l^yg#Z8m diff --git a/sample_app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/sample_app/src/main/res/mipmap-xxhdpi/ic_launcher.png index 69a00c02fabcea86994dd29a9f019d750be722a8..f6afb980459ee31f734389f4f6773c7226c143b8 100644 GIT binary patch literal 4963 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 literal 3810 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 diff --git a/sample_app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/sample_app/src/main/res/mipmap-xxxhdpi/ic_launcher.png index 01f553908c4e2edd74466b375ee7931f2b8c3e9f..05b1dbe8176484af5eb9d2e093ef873547212842 100644 GIT binary patch literal 6851 zcmb7p^;ZARvO$2ri0*NOy`f zyZ}MEKfKTR{sZ41X6DQ}&w1|LxpU^;=iC@WeJx6IHgW&}rH;1xoy(Q@zd?$;obODz zkpRHc;KcZ(P_?wUT(d~mNn zXeUd_OMj8h`|sJ6b9PqR8$=RIbSo1LPx(#LY+-=JN1}(A?11V9u3P~|6r*vaz<@k| zWz!tUEDLEhf(38bm@C)|yiiXkpeStdbZ?3ikVUGxLy+j9&E=mGfCH9S17I|+2R@6e zATHd{5)UD*KB@nQ0`1sh;RJ3_z>o$gc6cf%3_7X&;OEeoCp=;_(oYjqCa=hX>nmF5 z#NzewD_p)BM?sT#giYdW^|!Jd+XTBUZot3QrE$h2!cy~zvusTo@8}LI|8wQ|A!PEI z^*;ON~nkXZ}PSx@6cbBjRM+|Y-uFZeM zh>z;{%UC&o)$3xjb8MRox&sVr7qxTP-zcD-m$D0(kXUM}FfK(3Cv-#U=u}(L>S6_y zLmq)B>W$lCy!443F~Vw0lI*WKpPCY^w5RGG$fBP`3c!Ct<}y2_O#++s=xe|Y1dmYb zBZTXP4>i|Du;5R=SQ=V%+d`x{xb7p$?2S69ys2I#{)elClq8Hk&V;*Ev(h1kv}6?e z-(7qa|k`m4pb z-IpZc7Z2qgbP0G_T(C1`la@XR{^nVeTy~_!-4cw{UV=l}afp&sD&ip|so&uqJf+?9 z$fk4N_!lJM*FZQslQO(?MIcp)OYz$q#|kWOT!s{_iEt2A??Drbs7_jjo*fcjaGDpQ zfpP0}BlU*61!uea%ymKBiO|=wYcd)Y{@YG0J_AO;mA$RMI>}xF$bPsW+~Djx#|QAV zdQ>=asEPyR6!)>EwjkAz*4AYHqM2kV|HI!$oXBRluB>Hq%a4y2jbBx2MS(?I=C`5Bb{(14{rmWF zn&;Av;CLft+>PSiZ6T}D|LB@=f)ujf^X}eWs|fU0HksPhSEI%P=T0;|Ahp_gD8{uZ zhzY!7x*psiq-~DUk;4uqW4p?`%GQ}KNb2&wwPiV4DA_{?gl9p;ev$mC**Ld^#}kq# zT#0GH?$$gIyFaHf*8S&O>GlZxX-y5X&gEI`4GLDM18)&@>-(?4t^Ex+-dYx*Sgj+( zn9XGaLS=jv{58`cUg)}AzfH1Gh@Jfp@QckThHFt;pewr{-5W2?6E1X#eeC3%7_W?ywcDQ-iRWMg9#7~xN^=NL}4k)mQSW+e6 z1bfI7SY!tI5Y$BCYrZtErXPyLkr~Tsvbx9QT|B}JcOZwjwe;dIK1^{Ot`0pg-td1j zFj5qUc?PhX^@*OP<~ON;PYg^av-s!}!igimWUeF6`&SU55ThBM2-GoK^&TkfLoFYD zB5*b%REXT|hRE_`7GyRdDAs{K_b*Uv{BjmClAZ-nYwm2*ae~0-Ly->uZ)XiSNCPLH z<|nZL4K;*s1{o+WR*)}P!632yhLG%sX{>OzTf;Sqx@0C5!&_`(Iq z@^}1EK%$8&_X3l-fvg2jBG9NvBA>PlTk5H+983mGio{#K zy6+FiVqB0a94de)r}BcI72n-PNWB;zEc+e#`)F}Gm#;iXkcBh?ddYzND-Lwjs@#zZ zLzAipap}yTj0|X=a*)$q`oiYVQe>U)V)}d`B5msfiI-$p&1^t$1RCu{fo-B>aKVvd zhPnj5&%g|~lxKRsLZH<^mS%R4(oo}hc?d+kSxx(>e8zyTQ zSc2Zp@-6?fUu09zt>b`B-m~rIRB3o#7MA%QFmW`HW;sn%vjKH;dh8~-C;9`?Xx~dK zhTeL0AwT(x-N70ZU(-{e+L*SOZIptn zhcZ9BjI-wcz+W=mMff#<8K+-RqsksIpDm{svN}nP9ala%3*ij0sWhWn^@pBpX#cmu_qMT*q3f3kvfI7+eHK=WDjjKO*-56oKNWW8)1rYQ z&Ws{Ujwdb!r>FS<)JV#zB=lwxse$fK9_7aoZY_TUm$-f0US<7fEJ_4!AC7m@=?@WL z_>(z9;6DZmMad#PLw&C!cIg@066WO93}wsnYG2O2zfpC{#sjSQUk`gt^=J7(;o5G$ zD4l7u{rsC)c{L=qVaapdL*}dd{E_G$zAG>ciEbRbfZ=L?pqRAU!7cJ57{Xons8n}ba9($U8^fboSvX4wEPU& zg9}}LN80qiv9=7#gmg^jz|-l|kVF$vX}`Qy+lLusxc0fT1E#>Tj|eGvLIRdI>J=9X zpCPBWx@>hBBdDEgGri0Cj%{V7(aGeh5${ zd&Gw`r1x`(44@D%_3r4idC=B5^kCn_cEJC;FZ=vg=`@rCSOc;&hetU?IEX5~gw$(@ zVUFA=PS%S@C}3sj>B+QvPKQ z(@nl1y?Xm*bO>uJSb^C+emG*J)&pc5nqVB*@;9I~)bFHQLFQe!$fE>SdqE7wX-W>YYR-6@dbS7zKN zuMK~zS>sV-~^l!1zWYnU1-_BYN2FUq5J^*#Ewnnc6js; zagr*=K!=3m6Z~geY0S;!5b!Q-+xHI761?z%fdl@+r@Zxv&r}zBV%%fmh<3fXDWl#q z+r{A*a|YXUh@nKy=x6d9{20bl-jGc>o|9+yc|Z1q3}-48)&8f*SX;)i7t{KDd{bre z+Zz;qwC~>6a+=4`uaaTc1p9m!a~$T){@8aea4HH}g(g^Baa)MRzzAF&@=i+<{9DF5 zPMHo+J1ld! z)^RZe8-nCKakJ`;o`S86_ihZUT>2ut!PkA^unCm&1>PmtI&;|M=uz@OR!r*rlzQllhO+ncw zBGmcZcRtvfI1@xdm^&rC^YeQ^#S*wZp@=|y3rhIB&w;uL~*c9EityYlKfpH<25(vGeM zl+=Lv%Lrx2-Uod05Bw{&Z___%r9zOnk=LB?wpyPM1y^bkN<8$c|5k zT!jL*UU*{K;7~A_5I?IE+YCt;c59=%Zc3VdG;PqGTl(~fg79nQbTibWrTjiJEpqs*J*k%Z8Dz^U0 zkG{W0eW&#=JfP5EO$W7tfM!9lF9S`IE`vfxRD>s8R@K_)xPP+j5;!|BRK~bvessxP zvgV{u^G3VsJmuvy$&wf+Lg1oc{|8H=IZ6BrhkBCqABxy=(*DyX8p*J7fx{H~(9dkL z>+fZyg90zSwp*YE`^LBNE~7CHT8)1lYd%pdgL>5;(|@B1j(k$4o^sskCCfQgpChOC z#J?{)IQWFw^{R#k?mE$3oXNuyy4u6fZJuW+zk%pt6Ef&g>2C9Psc-YFa`A?l$dGW! zceklEkYN;)L-1BS`THR}kIt>6Fe&uAt3p`OqAzZ7ll4+tosP7Ure^*+HiYpe17jqZXjGG3YXH-dZ?DdZcgLxqo_GL8m{0exX)3SkWy=eAZUp}n&RNhGl} z`jeHDz#l)0KZ|ONg(`)~QA^WFo6=&Rhmtw|-JjDswy67*$#yClcGbJ53%RR&8!cKs z5gL1=JC`kRdvY3vr7$?X{xZjJ=wqQ2$&N^@-NzBv(bFSg_V~~RT$b_{MDVeB zp~boH>K{fRkbC3C{y=EVZQI(tdlvPW|2jj+by*9f&kY`dxX`vXCobvf`@l-}U8S)e zf=$n~IrL|$&%PfZh-X5R+Qxe`ogG%?)ifV1NP8?$@1+)H9*W?Nxi%qFa$}zF^C-Y@ zn+dDa>2>eCaH+Of^T1^$A_=ob-}{sdZs+yf83@Zw7T{-`!M5fmG%g9jcjn;Hbqi7# z!4a8pOm!#l>i%5MFjyQHXZwV!U+$tp5~RZ=zm=@8K%@MRrZGtSMW#))$LgfS?`)0y z5@rMssWsYZf%))xY*maJz722!kJ*0@?IKf{^{+v^77}83?gTfUC>!rFPZU|4Bt{}M zZ}gnyiT3ub8;B;Yv*4%1a`sTh!4`h6rX@jC27RAqqo=L&p9<^YwsV~qduO$=b$Nd- zeslIHV*TYK`c7934q!m*TkNW+7k=q}sIeS`uj#YMEBrp>j@)(DA|r`;5?I1`fr`sH z0btVG)7Y-O+rFrT2^os?jj0%y#RppWkkq+R+ku)I-GmHfZIHnXqwo2I4KMQP!zoBI z+NVZqh_3d&`=rqSaa%FbBhzs{=OEPi>^%lWOcf!s*daj>{rQM$O~QROSLNIDtF^!I z;gIaFd7_yUy1P-^gdj3+5PnxaL?s&6wzz$rGTn=2OXNyFY28KwJgu|}MC1=p< z9^bn^3%C3WW2t|>%!NKm>}vIo5|}@&Ked0%(2=~((`^vG;ALP1wKMq4Yf1H&&j$y??BTBPLC24gCcp#K!Prz zmwwN;o^;wfd2NcTHf~QK+-$$D+V}g>rG73kP*JmWl`GC}%t4PPKa4Newpv1fV~)g_ zydJbxh_Bm&-3bhA7K?51F(Hv66&H4pT&1Z6CZ}ln`Gv`EvR`#>vNoEIT}o@i*J`-V z922Jo1b(UWztEoK98Q7m-oFs>TFxrz6sEWbU1SlYI8i$7TE1PM;7E^gXnjryzWZTM zD*fU6BR{Qh-w591jNA}>o7yv`SAA8a{9^kK#h)wb>Qb;a5W?)&$1i&6yT34rbo^IG zGBz>ML*t^SSoO7GbL5Q*pmFW)Rm59p*SN>E9uG=gtDQ9rtojX}+U!UGa-+0%<4ZLv z6^3m81pnz!yIvOn}o zs~`{xQIL;y1jBhp6T%v;-pZe}uvg=>kr@3B3Z!ovV92JcPyPW zVG|iUsY&RS`jK|*MXS#>PNrooMVVi$STOw{1P`T3DKwXa663Tg=5`nlS5^nNwu?XZ z*BhWHibfcrfT_XnyEVNz9*`m3t{S;V6 zK#p5ut!lpQnNLyy%vK)zvNk{Y%J3c6%q{F+k1>+Hk@Q1O&T zuo-V9dFHCyc*Iww^o8lsl7|2TxK6w}<~Mp@$aV&W^+8!n(h5)dsqwPijw2O={fWE( zvASsF_Y3>^wPG{*fM$+>sY!FSV@U1Xl3Iy zoPiKrji?QiSuQ+l9DLj?tdRuNvcdVyiS=RX$pCmhpIECS?Nc`b-rg`S+AwR3ru~k# zy1L?;gHh$0pxxpqy8j1#M>=qXh5WHrn^Ytp!yAKwG!V)-^tcNY+ zv-9Ml!gxMsUzsq?jr_dQ1)lfo7K_vx&XOCqYUqx|Wpa&$e1#mxNf+%;J6?$Qx^6e0z& z)wf6HqFK8x+3vfl2{C;(`V#qc%p`Wgf;@OR9>>4&QSo@5VJaDZtBHFLN(JYQCWRl% zyl^hPuWqm5z^-#R_*qZc_BT&xbf_8nHL5MY8*xA3`CU2j=<|28MPb>qMH~ZWbI$T0 zo8Ye*Rm`t__Ld_Y#Gog>kUqC~&Ll>9L|XqXuu#3sMzz(soElNHqs5jBRoWA+UKBM0 z9OjE1Jmmi5$3x0%oTN0zv5{XfP_f*1UeBP}G42d2aO_&{PUg0~+Mpt~gyC_-&G9*Y zN7}Rg3s!vSGb?+=o1B2$KLUTA#nmF$Zr1hJlq$hv!bB%IORAxM(SWzrB?xbeWlHU; zmwX?-4zEoblmE~pF*q1ln(KOwhV}$KqhDXW$l!{d+nVqfn#Ctfd@HKmZ?iljK(zn5 z-^rtZ65aVZzF7|Ja)k^1c{EGH7yh_D8PegH=XJ`ZUEw6oM`9-nef22)2NVUOHH(Fb n;OWGfRS**I@c-M>xd>yFQ)g?`Rd2g&P5~Vaef4rxyNLe-mGO(U literal 5415 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 T7GR)mfP$;~W_qPpT%-O2`=Q#6 diff --git a/sample_app/web_hi_res_512.png b/sample_app/web_hi_res_512.png index 7419be120a4c51d67f57e98730e0ce020165de17..439bcb0ac9a9e015a759f9e5e6a958cc94fff342 100644 GIT binary patch literal 26244 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 literal 21456 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 Date: Tue, 17 Jan 2017 17:07:16 +0000 Subject: [PATCH 16/19] Added circle.yml --- circle.yml | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 circle.yml diff --git a/circle.yml b/circle.yml new file mode 100644 index 0000000..23d13c5 --- /dev/null +++ b/circle.yml @@ -0,0 +1,7 @@ + test: + override: + - (echo "Running JUnit tests!") + - ./gradlew test -PdisablePreDex + post: + - mkdir -p $CIRCLE_TEST_REPORTS/junit/ + - find . -type f -regex ".*/build/test-results/.*xml" -exec cp {} $CIRCLE_TEST_REPORTS/junit/ \; From 81d984efac1bc06618794c1e63093538ab22ebe6 Mon Sep 17 00:00:00 2001 From: Alexandros Schillings Date: Tue, 17 Jan 2017 17:31:53 +0000 Subject: [PATCH 17/19] The dound device list is now implemented as a recyclerview. --- .../recyclerview/BaseRecyclerViewAdapter.java | 30 +++-- .../recyclerview/RecyclerViewBinderCore.java | 6 + .../btlescan/ui/main/DeviceListAdapter.java | 126 ------------------ .../ui/main/DeviceRecyclerAdapter.java | 10 ++ .../alt236/btlescan/ui/main/MainActivity.java | 58 ++++---- .../ui/main/RecyclerViewCoreFactory.java | 24 ++++ .../recyclerview/binder/CommonBinding.java | 36 +++++ .../recyclerview/binder/IBeaconBinder.java | 54 ++++++++ .../recyclerview/binder/LeDeviceBinder.java | 42 ++++++ .../holder/CommonDeviceHolder.java | 13 ++ .../recyclerview/holder/IBeaconHolder.java | 83 ++++++++++++ .../recyclerview/holder/LeDeviceHolder.java | 45 +++++++ .../main/recyclerview/model/IBeaconItem.java | 18 +++ .../main/recyclerview/model/LeDeviceItem.java | 17 +++ .../src/main/res/layout/activity_main.xml | 2 +- ...evice.xml => list_item_device_ibeacon.xml} | 63 +-------- .../main/res/layout/list_item_device_le.xml | 21 +++ .../viewpart_list_item_device_common.xml | 65 +++++++++ 18 files changed, 495 insertions(+), 218 deletions(-) delete mode 100644 sample_app/src/main/java/uk/co/alt236/btlescan/ui/main/DeviceListAdapter.java create mode 100644 sample_app/src/main/java/uk/co/alt236/btlescan/ui/main/DeviceRecyclerAdapter.java create mode 100644 sample_app/src/main/java/uk/co/alt236/btlescan/ui/main/RecyclerViewCoreFactory.java create mode 100644 sample_app/src/main/java/uk/co/alt236/btlescan/ui/main/recyclerview/binder/CommonBinding.java create mode 100644 sample_app/src/main/java/uk/co/alt236/btlescan/ui/main/recyclerview/binder/IBeaconBinder.java create mode 100644 sample_app/src/main/java/uk/co/alt236/btlescan/ui/main/recyclerview/binder/LeDeviceBinder.java create mode 100644 sample_app/src/main/java/uk/co/alt236/btlescan/ui/main/recyclerview/holder/CommonDeviceHolder.java create mode 100644 sample_app/src/main/java/uk/co/alt236/btlescan/ui/main/recyclerview/holder/IBeaconHolder.java create mode 100644 sample_app/src/main/java/uk/co/alt236/btlescan/ui/main/recyclerview/holder/LeDeviceHolder.java create mode 100644 sample_app/src/main/java/uk/co/alt236/btlescan/ui/main/recyclerview/model/IBeaconItem.java create mode 100644 sample_app/src/main/java/uk/co/alt236/btlescan/ui/main/recyclerview/model/LeDeviceItem.java rename sample_app/src/main/res/layout/{list_item_device.xml => list_item_device_ibeacon.xml} (70%) create mode 100644 sample_app/src/main/res/layout/list_item_device_le.xml create mode 100644 sample_app/src/main/res/layout/viewpart_list_item_device_common.xml diff --git a/sample_app/src/main/java/uk/co/alt236/btlescan/ui/common/recyclerview/BaseRecyclerViewAdapter.java b/sample_app/src/main/java/uk/co/alt236/btlescan/ui/common/recyclerview/BaseRecyclerViewAdapter.java index 6bf83dc..4181345 100644 --- a/sample_app/src/main/java/uk/co/alt236/btlescan/ui/common/recyclerview/BaseRecyclerViewAdapter.java +++ b/sample_app/src/main/java/uk/co/alt236/btlescan/ui/common/recyclerview/BaseRecyclerViewAdapter.java @@ -3,25 +3,24 @@ package uk.co.alt236.btlescan.ui.common.recyclerview; import android.support.v7.widget.RecyclerView; import android.view.ViewGroup; +import java.util.ArrayList; +import java.util.Collection; import java.util.List; public abstract class BaseRecyclerViewAdapter extends RecyclerView.Adapter> { - private final List mItemList; + private final List mItemList; private final RecyclerViewBinderCore mCore; public BaseRecyclerViewAdapter(final RecyclerViewBinderCore core, final List items) { - mItemList = items; + mItemList = new ArrayList<>(); mCore = core; + mItemList.addAll(items); } - private static void bind(final BaseViewBinder binder, - final BaseViewHolder holder, - final RecyclerViewItem item) { - - //noinspection unchecked - binder.bind((BaseViewHolder) holder, (T) item); + public BaseRecyclerViewAdapter(final RecyclerViewBinderCore core) { + this(core, new ArrayList()); } @Override @@ -52,4 +51,19 @@ public abstract class BaseRecyclerViewAdapter extends RecyclerView.Adapter data) { + + mItemList.clear(); + mItemList.addAll(data); + notifyDataSetChanged(); + } + + private static void bind(final BaseViewBinder binder, + final BaseViewHolder holder, + final RecyclerViewItem item) { + + //noinspection unchecked + binder.bind((BaseViewHolder) holder, (T) item); + } } diff --git a/sample_app/src/main/java/uk/co/alt236/btlescan/ui/common/recyclerview/RecyclerViewBinderCore.java b/sample_app/src/main/java/uk/co/alt236/btlescan/ui/common/recyclerview/RecyclerViewBinderCore.java index c76983d..acadb5c 100644 --- a/sample_app/src/main/java/uk/co/alt236/btlescan/ui/common/recyclerview/RecyclerViewBinderCore.java +++ b/sample_app/src/main/java/uk/co/alt236/btlescan/ui/common/recyclerview/RecyclerViewBinderCore.java @@ -1,5 +1,6 @@ package uk.co.alt236.btlescan.ui.common.recyclerview; +import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -12,6 +13,7 @@ import java.util.List; public class RecyclerViewBinderCore { public static final int INVALID_VIEWTYPE = -1; + private static final String TAG = RecyclerViewBinderCore.class.getSimpleName(); private final List>> mViewHolderClasses; private final List> mViewBinders; private final List mLayoutIds; @@ -64,6 +66,10 @@ public class RecyclerViewBinderCore { count++; } + if (result == INVALID_VIEWTYPE) { + Log.w(TAG, "Could not get viewType for " + item); + } + return result; } diff --git a/sample_app/src/main/java/uk/co/alt236/btlescan/ui/main/DeviceListAdapter.java b/sample_app/src/main/java/uk/co/alt236/btlescan/ui/main/DeviceListAdapter.java deleted file mode 100644 index 57f40da..0000000 --- a/sample_app/src/main/java/uk/co/alt236/btlescan/ui/main/DeviceListAdapter.java +++ /dev/null @@ -1,126 +0,0 @@ -package uk.co.alt236.btlescan.ui.main; - -import android.app.Activity; -import android.support.v4.widget.SimpleCursorAdapter; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.ImageView; -import android.widget.TextView; - -import uk.co.alt236.bluetoothlelib.device.BluetoothLeDevice; -import uk.co.alt236.bluetoothlelib.device.beacon.BeaconType; -import uk.co.alt236.bluetoothlelib.device.beacon.BeaconUtils; -import uk.co.alt236.bluetoothlelib.device.beacon.ibeacon.IBeaconDevice; -import uk.co.alt236.btlescan.R; -import uk.co.alt236.btlescan.util.Constants; -import uk.co.alt236.easycursor.objectcursor.EasyObjectCursor; - -// Adapter for holding devices found through scanning. -/*package*/ class DeviceListAdapter extends SimpleCursorAdapter { - private final LayoutInflater mInflator; - private final Activity mActivity; - - public DeviceListAdapter(final Activity activity, final EasyObjectCursor cursor) { - super(activity, R.layout.list_item_device, cursor, new String[0], new int[0], 0); - mInflator = activity.getLayoutInflater(); - mActivity = activity; - } - - @SuppressWarnings("unchecked") - @Override - public EasyObjectCursor getCursor() { - return ((EasyObjectCursor) super.getCursor()); - } - - @Override - public BluetoothLeDevice getItem(final int i) { - return getCursor().getItem(i); - } - - @Override - public long getItemId(final int i) { - return i; - } - - @Override - public View getView(final int i, View view, final ViewGroup viewGroup) { - final 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.deviceLastUpdated = (TextView) view.findViewById(R.id.device_last_update); - 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.findViewById(R.id.ibeacon_section); - viewHolder.ibeaconDistanceDescriptor = (TextView) view.findViewById(R.id.ibeacon_distance_descriptor); - view.setTag(viewHolder); - } else { - viewHolder = (ViewHolder) view.getTag(); - } - - final BluetoothLeDevice device = getCursor().getItem(i); - final String deviceName = device.getName(); - final double rssi = device.getRssi(); - - if (deviceName != null && deviceName.length() > 0) { - viewHolder.deviceName.setText(deviceName); - } else { - viewHolder.deviceName.setText(R.string.unknown_device); - } - - if (BeaconUtils.getBeaconType(device) == BeaconType.IBEACON) { - final IBeaconDevice iBeacon = new IBeaconDevice(device); - final String accuracy = Constants.DOUBLE_TWO_DIGIT_ACCURACY.format(iBeacon.getAccuracy()); - - viewHolder.deviceIcon.setImageResource(R.drawable.ic_device_ibeacon); - viewHolder.ibeaconSection.setVisibility(View.VISIBLE); - viewHolder.ibeaconMajor.setText(String.valueOf(iBeacon.getMajor())); - viewHolder.ibeaconMinor.setText(String.valueOf(iBeacon.getMinor())); - viewHolder.ibeaconTxPower.setText(String.valueOf(iBeacon.getCalibratedTxPower())); - viewHolder.ibeaconUUID.setText(iBeacon.getUUID()); - 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( - Constants.TIME_FORMAT, new java.util.Date(device.getTimestamp()))); - viewHolder.deviceAddress.setText(device.getAddress()); - viewHolder.deviceRssi.setText(rssiString + " / " + runningAverageRssiString); - return view; - } - - static class ViewHolder { - TextView deviceName; - TextView deviceAddress; - TextView deviceRssi; - TextView ibeaconUUID; - TextView ibeaconMajor; - TextView ibeaconMinor; - TextView ibeaconTxPower; - TextView ibeaconDistance; - TextView ibeaconDistanceDescriptor; - TextView deviceLastUpdated; - View ibeaconSection; - ImageView deviceIcon; - } - -} \ No newline at end of file diff --git a/sample_app/src/main/java/uk/co/alt236/btlescan/ui/main/DeviceRecyclerAdapter.java b/sample_app/src/main/java/uk/co/alt236/btlescan/ui/main/DeviceRecyclerAdapter.java new file mode 100644 index 0000000..57dc71a --- /dev/null +++ b/sample_app/src/main/java/uk/co/alt236/btlescan/ui/main/DeviceRecyclerAdapter.java @@ -0,0 +1,10 @@ +package uk.co.alt236.btlescan.ui.main; + +import uk.co.alt236.btlescan.ui.common.recyclerview.BaseRecyclerViewAdapter; +import uk.co.alt236.btlescan.ui.common.recyclerview.RecyclerViewBinderCore; + +/*package*/ class DeviceRecyclerAdapter extends BaseRecyclerViewAdapter { + public DeviceRecyclerAdapter(RecyclerViewBinderCore core) { + super(core); + } +} diff --git a/sample_app/src/main/java/uk/co/alt236/btlescan/ui/main/MainActivity.java b/sample_app/src/main/java/uk/co/alt236/btlescan/ui/main/MainActivity.java index 9b34960..f7fcdaf 100644 --- a/sample_app/src/main/java/uk/co/alt236/btlescan/ui/main/MainActivity.java +++ b/sample_app/src/main/java/uk/co/alt236/btlescan/ui/main/MainActivity.java @@ -6,28 +6,37 @@ import android.bluetooth.BluetoothDevice; import android.os.Bundle; import android.support.annotation.NonNull; import android.support.v7.app.AppCompatActivity; +import android.support.v7.widget.LinearLayoutManager; +import android.support.v7.widget.RecyclerView; import android.view.Menu; import android.view.MenuItem; import android.view.View; -import android.widget.AdapterView; -import android.widget.ListView; import android.widget.TextView; import android.widget.Toast; import com.anthonycr.grant.PermissionsManager; import com.anthonycr.grant.PermissionsResultAction; +import java.util.ArrayList; +import java.util.List; + import butterknife.Bind; import butterknife.ButterKnife; import uk.co.alt236.bluetoothlelib.device.BluetoothLeDevice; +import uk.co.alt236.bluetoothlelib.device.beacon.BeaconType; +import uk.co.alt236.bluetoothlelib.device.beacon.BeaconUtils; +import uk.co.alt236.bluetoothlelib.device.beacon.ibeacon.IBeaconDevice; import uk.co.alt236.btlescan.R; import uk.co.alt236.btlescan.containers.BluetoothLeDeviceStore; import uk.co.alt236.btlescan.ui.common.Navigation; +import uk.co.alt236.btlescan.ui.common.recyclerview.RecyclerViewBinderCore; +import uk.co.alt236.btlescan.ui.common.recyclerview.RecyclerViewItem; +import uk.co.alt236.btlescan.ui.main.recyclerview.model.IBeaconItem; +import uk.co.alt236.btlescan.ui.main.recyclerview.model.LeDeviceItem; import uk.co.alt236.btlescan.util.BluetoothLeScanner; import uk.co.alt236.btlescan.util.BluetoothUtils; -import uk.co.alt236.easycursor.objectcursor.EasyObjectCursor; -public class MainActivity extends AppCompatActivity implements AdapterView.OnItemClickListener { +public class MainActivity extends AppCompatActivity { @Bind(R.id.tvBluetoothLe) protected TextView mTvBluetoothLeStatus; @Bind(R.id.tvBluetoothStatus) @@ -35,14 +44,15 @@ public class MainActivity extends AppCompatActivity implements AdapterView.OnIte @Bind(R.id.tvItemCount) protected TextView mTvItemCount; @Bind(android.R.id.list) - protected ListView mList; + protected RecyclerView mList; @Bind(android.R.id.empty) protected View mEmpty; + private RecyclerViewBinderCore mCore; private BluetoothUtils mBluetoothUtils; private BluetoothLeScanner mScanner; - private DeviceListAdapter mDeviceListAdapter; private BluetoothLeDeviceStore mDeviceStore; + private DeviceRecyclerAdapter mRecyclerAdapter; private final BluetoothAdapter.LeScanCallback mLeScanCallback = new BluetoothAdapter.LeScanCallback() { @Override @@ -50,13 +60,21 @@ public class MainActivity extends AppCompatActivity implements AdapterView.OnIte final BluetoothLeDevice deviceLe = new BluetoothLeDevice(device, rssi, scanRecord, System.currentTimeMillis()); mDeviceStore.addDevice(deviceLe); - final EasyObjectCursor c = mDeviceStore.getDeviceCursor(); + final List itemList = new ArrayList<>(); + + for (final BluetoothLeDevice leDevice : mDeviceStore.getDeviceList()) { + if (BeaconUtils.getBeaconType(leDevice) == BeaconType.IBEACON) { + itemList.add(new IBeaconItem(new IBeaconDevice(leDevice))); + } else { + itemList.add(new LeDeviceItem(leDevice)); + } + } runOnUiThread(new Runnable() { @Override public void run() { - mDeviceListAdapter.swapCursor(c); - updateItemCount(mDeviceListAdapter.getCount()); + mRecyclerAdapter.setData(itemList); + updateItemCount(mRecyclerAdapter.getItemCount()); } }); } @@ -67,8 +85,8 @@ public class MainActivity extends AppCompatActivity implements AdapterView.OnIte super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ButterKnife.bind(this); - mList.setEmptyView(mEmpty); - mList.setOnItemClickListener(this); + mCore = RecyclerViewCoreFactory.create(this, new Navigation(this)); + mList.setLayoutManager(new LinearLayoutManager(this)); mDeviceStore = new BluetoothLeDeviceStore(); mBluetoothUtils = new BluetoothUtils(this); mScanner = new BluetoothLeScanner(mLeScanCallback, mBluetoothUtils); @@ -88,7 +106,7 @@ public class MainActivity extends AppCompatActivity implements AdapterView.OnIte menu.findItem(R.id.menu_refresh).setActionView(R.layout.actionbar_progress_indeterminate); } - if (mList.getCount() > 0) { + if (mRecyclerAdapter != null && mRecyclerAdapter.getItemCount() > 0) { menu.findItem(R.id.menu_share).setVisible(true); } else { menu.findItem(R.id.menu_share).setVisible(false); @@ -97,12 +115,6 @@ public class MainActivity extends AppCompatActivity implements AdapterView.OnIte return true; } - @Override - public void onItemClick(AdapterView adapterView, View view, int position, long l) { - final BluetoothLeDevice device = mDeviceListAdapter.getItem(position); - new Navigation(this).openDetailsActivity(device); - } - @Override public boolean onOptionsItemSelected(final MenuItem item) { switch (item.getItemId()) { @@ -146,16 +158,14 @@ public class MainActivity extends AppCompatActivity implements AdapterView.OnIte @Override public void onResume() { super.onResume(); - final boolean mIsBluetoothOn = mBluetoothUtils.isBluetoothOn(); - final boolean mIsBluetoothLePresent = mBluetoothUtils.isBluetoothLeSupported(); - if (mIsBluetoothOn) { + if (mBluetoothUtils.isBluetoothOn()) { mTvBluetoothStatus.setText(R.string.on); } else { mTvBluetoothStatus.setText(R.string.off); } - if (mIsBluetoothLePresent) { + if (mBluetoothUtils.isBluetoothLeSupported()) { mTvBluetoothLeStatus.setText(R.string.supported); } else { mTvBluetoothLeStatus.setText(R.string.not_supported); @@ -170,8 +180,8 @@ public class MainActivity extends AppCompatActivity implements AdapterView.OnIte mDeviceStore.clear(); updateItemCount(0); - mDeviceListAdapter = new DeviceListAdapter(this, mDeviceStore.getDeviceCursor()); - mList.setAdapter(mDeviceListAdapter); + mRecyclerAdapter = new DeviceRecyclerAdapter(mCore); + mList.setAdapter(mRecyclerAdapter); mBluetoothUtils.askUserToEnableBluetoothIfNeeded(); if (mIsBluetoothOn && mIsBluetoothLePresent) { diff --git a/sample_app/src/main/java/uk/co/alt236/btlescan/ui/main/RecyclerViewCoreFactory.java b/sample_app/src/main/java/uk/co/alt236/btlescan/ui/main/RecyclerViewCoreFactory.java new file mode 100644 index 0000000..dc6fe60 --- /dev/null +++ b/sample_app/src/main/java/uk/co/alt236/btlescan/ui/main/RecyclerViewCoreFactory.java @@ -0,0 +1,24 @@ +package uk.co.alt236.btlescan.ui.main; + +import android.content.Context; + +import uk.co.alt236.btlescan.R; +import uk.co.alt236.btlescan.ui.common.Navigation; +import uk.co.alt236.btlescan.ui.common.recyclerview.RecyclerViewBinderCore; +import uk.co.alt236.btlescan.ui.main.recyclerview.binder.IBeaconBinder; +import uk.co.alt236.btlescan.ui.main.recyclerview.binder.LeDeviceBinder; +import uk.co.alt236.btlescan.ui.main.recyclerview.holder.IBeaconHolder; +import uk.co.alt236.btlescan.ui.main.recyclerview.holder.LeDeviceHolder; + +/*protected*/ final class RecyclerViewCoreFactory { + + public static RecyclerViewBinderCore create(final Context context, final Navigation navigation) { + final RecyclerViewBinderCore core = new RecyclerViewBinderCore(); + + core.add(new IBeaconBinder(context, navigation), IBeaconHolder.class, R.layout.list_item_device_ibeacon); + core.add(new LeDeviceBinder(context, navigation), LeDeviceHolder.class, R.layout.list_item_device_le); + + return core; + } + +} diff --git a/sample_app/src/main/java/uk/co/alt236/btlescan/ui/main/recyclerview/binder/CommonBinding.java b/sample_app/src/main/java/uk/co/alt236/btlescan/ui/main/recyclerview/binder/CommonBinding.java new file mode 100644 index 0000000..2a31192 --- /dev/null +++ b/sample_app/src/main/java/uk/co/alt236/btlescan/ui/main/recyclerview/binder/CommonBinding.java @@ -0,0 +1,36 @@ +package uk.co.alt236.btlescan.ui.main.recyclerview.binder; + +import android.content.Context; + +import uk.co.alt236.bluetoothlelib.device.BluetoothLeDevice; +import uk.co.alt236.btlescan.R; +import uk.co.alt236.btlescan.ui.main.recyclerview.holder.CommonDeviceHolder; +import uk.co.alt236.btlescan.util.Constants; + +/*package*/ class CommonBinding { + + public static void bind(final Context context, + final CommonDeviceHolder holder, + final BluetoothLeDevice device) { + + final String deviceName = device.getName(); + final double rssi = device.getRssi(); + + if (deviceName != null && deviceName.length() > 0) { + holder.getDeviceName().setText(deviceName); + } else { + holder.getDeviceName().setText(R.string.unknown_device); + } + + final String rssiString = + context.getString(R.string.formatter_db, String.valueOf(rssi)); + final String runningAverageRssiString = + context.getString(R.string.formatter_db, String.valueOf(device.getRunningAverageRssi())); + + holder.getDeviceLastUpdated().setText( + android.text.format.DateFormat.format( + Constants.TIME_FORMAT, new java.util.Date(device.getTimestamp()))); + holder.getDeviceAddress().setText(device.getAddress()); + holder.getDeviceRssi().setText(rssiString + " / " + runningAverageRssiString); + } +} diff --git a/sample_app/src/main/java/uk/co/alt236/btlescan/ui/main/recyclerview/binder/IBeaconBinder.java b/sample_app/src/main/java/uk/co/alt236/btlescan/ui/main/recyclerview/binder/IBeaconBinder.java new file mode 100644 index 0000000..9ccfb7f --- /dev/null +++ b/sample_app/src/main/java/uk/co/alt236/btlescan/ui/main/recyclerview/binder/IBeaconBinder.java @@ -0,0 +1,54 @@ +package uk.co.alt236.btlescan.ui.main.recyclerview.binder; + +import android.content.Context; +import android.view.View; + +import uk.co.alt236.bluetoothlelib.device.beacon.ibeacon.IBeaconDevice; +import uk.co.alt236.btlescan.R; +import uk.co.alt236.btlescan.ui.common.Navigation; +import uk.co.alt236.btlescan.ui.common.recyclerview.BaseViewBinder; +import uk.co.alt236.btlescan.ui.common.recyclerview.BaseViewHolder; +import uk.co.alt236.btlescan.ui.common.recyclerview.RecyclerViewItem; +import uk.co.alt236.btlescan.ui.main.recyclerview.holder.IBeaconHolder; +import uk.co.alt236.btlescan.ui.main.recyclerview.model.IBeaconItem; +import uk.co.alt236.btlescan.util.Constants; + +public class IBeaconBinder extends BaseViewBinder { + + private final Navigation navigation; + + public IBeaconBinder(Context context, Navigation navigation) { + super(context); + this.navigation = navigation; + } + + @Override + public void bind(BaseViewHolder holder, IBeaconItem item) { + + final IBeaconHolder actualHolder = (IBeaconHolder) holder; + final IBeaconDevice device = item.getDevice(); + + final String accuracy = Constants.DOUBLE_TWO_DIGIT_ACCURACY.format(device.getAccuracy()); + + actualHolder.getIbeaconMajor().setText(String.valueOf(device.getMajor())); + actualHolder.getIbeaconMinor().setText(String.valueOf(device.getMinor())); + actualHolder.getIbeaconTxPower().setText(String.valueOf(device.getCalibratedTxPower())); + actualHolder.getIbeaconUUID().setText(device.getUUID()); + actualHolder.getIbeaconDistance().setText( + getContext().getString(R.string.formatter_meters, accuracy)); + actualHolder.getIbeaconDistanceDescriptor().setText(device.getDistanceDescriptor().toString()); + + CommonBinding.bind(getContext(), actualHolder, device); + actualHolder.getView().setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + navigation.openDetailsActivity(device); + } + }); + } + + @Override + public boolean canBind(RecyclerViewItem item) { + return item instanceof IBeaconItem; + } +} diff --git a/sample_app/src/main/java/uk/co/alt236/btlescan/ui/main/recyclerview/binder/LeDeviceBinder.java b/sample_app/src/main/java/uk/co/alt236/btlescan/ui/main/recyclerview/binder/LeDeviceBinder.java new file mode 100644 index 0000000..e6018b0 --- /dev/null +++ b/sample_app/src/main/java/uk/co/alt236/btlescan/ui/main/recyclerview/binder/LeDeviceBinder.java @@ -0,0 +1,42 @@ +package uk.co.alt236.btlescan.ui.main.recyclerview.binder; + +import android.content.Context; +import android.view.View; + +import uk.co.alt236.bluetoothlelib.device.BluetoothLeDevice; +import uk.co.alt236.btlescan.ui.common.Navigation; +import uk.co.alt236.btlescan.ui.common.recyclerview.BaseViewBinder; +import uk.co.alt236.btlescan.ui.common.recyclerview.BaseViewHolder; +import uk.co.alt236.btlescan.ui.common.recyclerview.RecyclerViewItem; +import uk.co.alt236.btlescan.ui.main.recyclerview.holder.LeDeviceHolder; +import uk.co.alt236.btlescan.ui.main.recyclerview.model.LeDeviceItem; + +public class LeDeviceBinder extends BaseViewBinder { + + private final Navigation navigation; + + public LeDeviceBinder(Context context, Navigation navigation) { + super(context); + this.navigation = navigation; + } + + @Override + public void bind(BaseViewHolder holder, LeDeviceItem item) { + + final LeDeviceHolder actualHolder = (LeDeviceHolder) holder; + final BluetoothLeDevice device = item.getDevice(); + + CommonBinding.bind(getContext(), actualHolder, device); + actualHolder.getView().setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + navigation.openDetailsActivity(device); + } + }); + } + + @Override + public boolean canBind(RecyclerViewItem item) { + return item instanceof LeDeviceItem; + } +} diff --git a/sample_app/src/main/java/uk/co/alt236/btlescan/ui/main/recyclerview/holder/CommonDeviceHolder.java b/sample_app/src/main/java/uk/co/alt236/btlescan/ui/main/recyclerview/holder/CommonDeviceHolder.java new file mode 100644 index 0000000..eee330d --- /dev/null +++ b/sample_app/src/main/java/uk/co/alt236/btlescan/ui/main/recyclerview/holder/CommonDeviceHolder.java @@ -0,0 +1,13 @@ +package uk.co.alt236.btlescan.ui.main.recyclerview.holder; + +import android.widget.TextView; + +public interface CommonDeviceHolder { + TextView getDeviceName(); + + TextView getDeviceAddress(); + + TextView getDeviceRssi(); + + TextView getDeviceLastUpdated(); +} diff --git a/sample_app/src/main/java/uk/co/alt236/btlescan/ui/main/recyclerview/holder/IBeaconHolder.java b/sample_app/src/main/java/uk/co/alt236/btlescan/ui/main/recyclerview/holder/IBeaconHolder.java new file mode 100644 index 0000000..9d69dc1 --- /dev/null +++ b/sample_app/src/main/java/uk/co/alt236/btlescan/ui/main/recyclerview/holder/IBeaconHolder.java @@ -0,0 +1,83 @@ +package uk.co.alt236.btlescan.ui.main.recyclerview.holder; + +import android.view.View; +import android.widget.TextView; + +import uk.co.alt236.btlescan.R; +import uk.co.alt236.btlescan.ui.common.recyclerview.BaseViewHolder; +import uk.co.alt236.btlescan.ui.main.recyclerview.model.IBeaconItem; + +public class IBeaconHolder extends BaseViewHolder implements CommonDeviceHolder { + + private final TextView ibeaconUUID; + private final TextView ibeaconMajor; + private final TextView ibeaconMinor; + private final TextView ibeaconTxPower; + private final TextView ibeaconDistance; + private final TextView ibeaconDistanceDescriptor; + + private final TextView deviceName; + private final TextView deviceAddress; + private final TextView deviceRssi; + private final TextView deviceLastUpdated; + + public IBeaconHolder(View itemView) { + super(itemView); + + this.deviceAddress = (TextView) itemView.findViewById(R.id.device_address); + this.deviceName = (TextView) itemView.findViewById(R.id.device_name); + this.deviceRssi = (TextView) itemView.findViewById(R.id.device_rssi); + this.deviceLastUpdated = (TextView) itemView.findViewById(R.id.device_last_update); + + this.ibeaconMajor = (TextView) itemView.findViewById(R.id.ibeacon_major); + this.ibeaconMinor = (TextView) itemView.findViewById(R.id.ibeacon_minor); + this.ibeaconDistance = (TextView) itemView.findViewById(R.id.ibeacon_distance); + this.ibeaconUUID = (TextView) itemView.findViewById(R.id.ibeacon_uuid); + this.ibeaconTxPower = (TextView) itemView.findViewById(R.id.ibeacon_tx_power); + this.ibeaconDistanceDescriptor = (TextView) itemView.findViewById(R.id.ibeacon_distance_descriptor); + } + + @Override + public TextView getDeviceName() { + return deviceName; + } + + @Override + public TextView getDeviceAddress() { + return deviceAddress; + } + + @Override + public TextView getDeviceRssi() { + return deviceRssi; + } + + @Override + public TextView getDeviceLastUpdated() { + return deviceLastUpdated; + } + + public TextView getIbeaconUUID() { + return ibeaconUUID; + } + + public TextView getIbeaconMajor() { + return ibeaconMajor; + } + + public TextView getIbeaconMinor() { + return ibeaconMinor; + } + + public TextView getIbeaconTxPower() { + return ibeaconTxPower; + } + + public TextView getIbeaconDistance() { + return ibeaconDistance; + } + + public TextView getIbeaconDistanceDescriptor() { + return ibeaconDistanceDescriptor; + } +} diff --git a/sample_app/src/main/java/uk/co/alt236/btlescan/ui/main/recyclerview/holder/LeDeviceHolder.java b/sample_app/src/main/java/uk/co/alt236/btlescan/ui/main/recyclerview/holder/LeDeviceHolder.java new file mode 100644 index 0000000..793bd70 --- /dev/null +++ b/sample_app/src/main/java/uk/co/alt236/btlescan/ui/main/recyclerview/holder/LeDeviceHolder.java @@ -0,0 +1,45 @@ +package uk.co.alt236.btlescan.ui.main.recyclerview.holder; + +import android.view.View; +import android.widget.TextView; + +import uk.co.alt236.btlescan.R; +import uk.co.alt236.btlescan.ui.common.recyclerview.BaseViewHolder; +import uk.co.alt236.btlescan.ui.main.recyclerview.model.LeDeviceItem; + +public class LeDeviceHolder extends BaseViewHolder implements CommonDeviceHolder { + + private final TextView deviceName; + private final TextView deviceAddress; + private final TextView deviceRssi; + private final TextView deviceLastUpdated; + + public LeDeviceHolder(View itemView) { + super(itemView); + + this.deviceAddress = (TextView) itemView.findViewById(R.id.device_address); + this.deviceName = (TextView) itemView.findViewById(R.id.device_name); + this.deviceRssi = (TextView) itemView.findViewById(R.id.device_rssi); + this.deviceLastUpdated = (TextView) itemView.findViewById(R.id.device_last_update); + } + + @Override + public TextView getDeviceName() { + return deviceName; + } + + @Override + public TextView getDeviceAddress() { + return deviceAddress; + } + + @Override + public TextView getDeviceRssi() { + return deviceRssi; + } + + @Override + public TextView getDeviceLastUpdated() { + return deviceLastUpdated; + } +} diff --git a/sample_app/src/main/java/uk/co/alt236/btlescan/ui/main/recyclerview/model/IBeaconItem.java b/sample_app/src/main/java/uk/co/alt236/btlescan/ui/main/recyclerview/model/IBeaconItem.java new file mode 100644 index 0000000..1c7c802 --- /dev/null +++ b/sample_app/src/main/java/uk/co/alt236/btlescan/ui/main/recyclerview/model/IBeaconItem.java @@ -0,0 +1,18 @@ +package uk.co.alt236.btlescan.ui.main.recyclerview.model; + +import uk.co.alt236.bluetoothlelib.device.beacon.ibeacon.IBeaconDevice; +import uk.co.alt236.btlescan.ui.common.recyclerview.RecyclerViewItem; + +public class IBeaconItem implements RecyclerViewItem { + + private final IBeaconDevice device; + + public IBeaconItem(final IBeaconDevice device) { + this.device = device; + } + + public IBeaconDevice getDevice() { + return device; + } + +} diff --git a/sample_app/src/main/java/uk/co/alt236/btlescan/ui/main/recyclerview/model/LeDeviceItem.java b/sample_app/src/main/java/uk/co/alt236/btlescan/ui/main/recyclerview/model/LeDeviceItem.java new file mode 100644 index 0000000..77ac046 --- /dev/null +++ b/sample_app/src/main/java/uk/co/alt236/btlescan/ui/main/recyclerview/model/LeDeviceItem.java @@ -0,0 +1,17 @@ +package uk.co.alt236.btlescan.ui.main.recyclerview.model; + +import uk.co.alt236.bluetoothlelib.device.BluetoothLeDevice; +import uk.co.alt236.btlescan.ui.common.recyclerview.RecyclerViewItem; + +public class LeDeviceItem implements RecyclerViewItem { + + private final BluetoothLeDevice device; + + public LeDeviceItem(final BluetoothLeDevice device) { + this.device = device; + } + + public BluetoothLeDevice getDevice() { + return device; + } +} diff --git a/sample_app/src/main/res/layout/activity_main.xml b/sample_app/src/main/res/layout/activity_main.xml index 2ed9f24..b3ef06c 100644 --- a/sample_app/src/main/res/layout/activity_main.xml +++ b/sample_app/src/main/res/layout/activity_main.xml @@ -96,7 +96,7 @@ android:layout_alignParentTop="true" android:orientation="vertical"> - diff --git a/sample_app/src/main/res/layout/list_item_device.xml b/sample_app/src/main/res/layout/list_item_device_ibeacon.xml similarity index 70% rename from sample_app/src/main/res/layout/list_item_device.xml rename to sample_app/src/main/res/layout/list_item_device_ibeacon.xml index eb387ef..d0b9ca9 100644 --- a/sample_app/src/main/res/layout/list_item_device.xml +++ b/sample_app/src/main/res/layout/list_item_device_ibeacon.xml @@ -1,5 +1,4 @@ - -