From b0d65c08dd761c3a2df5dc35bddd1072964dedd3 Mon Sep 17 00:00:00 2001 From: Alexandros Schillings Date: Mon, 28 Apr 2014 17:39:31 +0100 Subject: [PATCH] Added GATT Services Exporter --- sample_app/res/menu/gatt_services.xml | 10 ++- sample_app/res/values/strings.xml | 7 +- .../activities/DeviceControlActivity.java | 86 +++++++++++++++++-- .../activities/DeviceDetailsActivity.java | 3 +- .../containers/BluetoothLeDeviceStore.java | 6 +- 5 files changed, 96 insertions(+), 16 deletions(-) diff --git a/sample_app/res/menu/gatt_services.xml b/sample_app/res/menu/gatt_services.xml index 0661f05..5c2909b 100644 --- a/sample_app/res/menu/gatt_services.xml +++ b/sample_app/res/menu/gatt_services.xml @@ -22,13 +22,19 @@ android:orderInCategory="1" android:showAsAction="ifRoom"/> + diff --git a/sample_app/res/values/strings.xml b/sample_app/res/values/strings.xml index 55bdd70..7c2b260 100644 --- a/sample_app/res/values/strings.xml +++ b/sample_app/res/values/strings.xml @@ -41,9 +41,10 @@ TX Power: UUID: This is a sample application using the Bluetooth LE Library.\n\nGithub: https://github.com/alt236/Bluetooth-LE-Library---Android\n\nCopyright: Alexandros Schillings - Bluetooth LE Scan Results (%s) - Please find attached the scan results. - Please select your email client: + Bluetooth LE Scan Results (%s) + Bluetooth LE Device GATT Results (%s, %s) + Please find attached the scan results. + Please select your email client: iBeacon Data Raw Ad Records Scan Record diff --git a/sample_app/src/uk/co/alt236/btlescan/activities/DeviceControlActivity.java b/sample_app/src/uk/co/alt236/btlescan/activities/DeviceControlActivity.java index a3ce5e6..314f41e 100644 --- a/sample_app/src/uk/co/alt236/btlescan/activities/DeviceControlActivity.java +++ b/sample_app/src/uk/co/alt236/btlescan/activities/DeviceControlActivity.java @@ -21,6 +21,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import uk.co.alt236.bluetoothlelib.device.BluetoothLeDevice; import uk.co.alt236.bluetoothlelib.resolvers.GattAttributeResolver; import uk.co.alt236.bluetoothlelib.util.ByteUtils; import uk.co.alt236.btlescan.R; @@ -54,9 +55,7 @@ import butterknife.InjectView; */ public class DeviceControlActivity extends Activity { private final static String TAG = DeviceControlActivity.class.getSimpleName(); - - public static final String EXTRAS_DEVICE_NAME = "DEVICE_NAME"; - public static final String EXTRAS_DEVICE_ADDRESS = "DEVICE_ADDRESS"; + public static final String EXTRA_DEVICE = "extra_device"; private static final String LIST_NAME = "NAME"; private static final String LIST_UUID = "UUID"; @@ -76,6 +75,8 @@ public class DeviceControlActivity extends Activity { @InjectView(R.id.data_as_array) TextView mDataAsArray; private boolean mConnected = false; + private String mExportString; + private BluetoothLeDevice mDevice; // Code to manage Service lifecycle. private final ServiceConnection mServiceConnection = new ServiceConnection() { @@ -160,14 +161,61 @@ public class DeviceControlActivity extends Activity { } }; - private void clearUI() { mGattServicesList.setAdapter((SimpleExpandableListAdapter) null); mGattUUID.setText(R.string.no_data); mGattUUIDDesc.setText(R.string.no_data); mDataAsArray.setText(R.string.no_data); mDataAsString.setText(R.string.no_data); + } + private void generateExportString(List gattServices){ + final String unknownServiceString = getResources().getString(R.string.unknown_service); + final String unknownCharaString = getResources().getString(R.string.unknown_characteristic); + final StringBuilder exportBuilder = new StringBuilder(); + + exportBuilder.append("Device Name: "); + exportBuilder.append(mDeviceName); + exportBuilder.append('\n'); + exportBuilder.append("Device Address: "); + exportBuilder.append(mDeviceAddress); + exportBuilder.append('\n'); + exportBuilder.append('\n'); + + exportBuilder.append("Services:"); + exportBuilder.append("--------------------------"); + exportBuilder.append('\n'); + + String uuid = null; + for (BluetoothGattService gattService : gattServices) { + uuid = gattService.getUuid().toString(); + + exportBuilder.append(GattAttributeResolver.getAttributeName(uuid, unknownServiceString)); + exportBuilder.append(" ("); + exportBuilder.append(uuid); + exportBuilder.append(')'); + exportBuilder.append('\n'); + + final List gattCharacteristics = gattService.getCharacteristics(); + for (final BluetoothGattCharacteristic gattCharacteristic : gattCharacteristics) { + uuid = gattCharacteristic.getUuid().toString(); + + exportBuilder.append('\t'); + exportBuilder.append(GattAttributeResolver.getAttributeName(uuid, unknownCharaString)); + exportBuilder.append(" ("); + exportBuilder.append(uuid); + exportBuilder.append(')'); + exportBuilder.append('\n'); + } + + exportBuilder.append('\n'); + exportBuilder.append('\n'); + } + + exportBuilder.append("--------------------------"); + exportBuilder.append('\n'); + + mExportString = exportBuilder.toString(); } // Demonstrates how to iterate through the supported GATT Services/Characteristics. @@ -175,6 +223,8 @@ public class DeviceControlActivity extends Activity { // on the UI. private void displayGattServices(List gattServices) { if (gattServices == null) return; + generateExportString(gattServices); + String uuid = null; final String unknownServiceString = getResources().getString(R.string.unknown_service); final String unknownCharaString = getResources().getString(R.string.unknown_characteristic); @@ -203,6 +253,7 @@ public class DeviceControlActivity extends Activity { currentCharaData.put(LIST_UUID, uuid); gattCharacteristicGroupData.add(currentCharaData); } + mGattCharacteristics.add(charas); gattCharacteristicData.add(gattCharacteristicGroupData); } @@ -218,7 +269,9 @@ public class DeviceControlActivity extends Activity { new String[] {LIST_NAME, LIST_UUID}, new int[] { android.R.id.text1, android.R.id.text2 } ); + mGattServicesList.setAdapter(gattServiceAdapter); + invalidateOptionsMenu(); } @Override @@ -227,8 +280,9 @@ public class DeviceControlActivity extends Activity { setContentView(R.layout.activity_gatt_services); final Intent intent = getIntent(); - mDeviceName = intent.getStringExtra(EXTRAS_DEVICE_NAME); - mDeviceAddress = intent.getStringExtra(EXTRAS_DEVICE_ADDRESS); + mDevice = intent.getParcelableExtra(EXTRA_DEVICE); + mDeviceName = mDevice.getName(); + mDeviceAddress = mDevice.getAddress(); ButterKnife.inject(this); @@ -253,6 +307,13 @@ public class DeviceControlActivity extends Activity { menu.findItem(R.id.menu_connect).setVisible(true); menu.findItem(R.id.menu_disconnect).setVisible(false); } + + if(mExportString == null){ + menu.findItem(R.id.menu_share).setVisible(false); + } else { + menu.findItem(R.id.menu_share).setVisible(true); + } + return true; } @@ -275,6 +336,19 @@ public class DeviceControlActivity extends Activity { case android.R.id.home: onBackPressed(); return true; + case R.id.menu_share: + final Intent intent = new Intent(android.content.Intent.ACTION_SEND); + final String subject = getString(R.string.exporter_email_device_services_subject, mDeviceName, mDeviceAddress); + + intent.setType("text/plain"); + intent.putExtra(android.content.Intent.EXTRA_SUBJECT, subject); + intent.putExtra(android.content.Intent.EXTRA_TEXT, mExportString); + + startActivity(Intent.createChooser( + intent, + getString(R.string.exporter_email_device_list_picker_text))); + + return true; } return super.onOptionsItemSelected(item); } diff --git a/sample_app/src/uk/co/alt236/btlescan/activities/DeviceDetailsActivity.java b/sample_app/src/uk/co/alt236/btlescan/activities/DeviceDetailsActivity.java index 75e91b7..6f0870b 100644 --- a/sample_app/src/uk/co/alt236/btlescan/activities/DeviceDetailsActivity.java +++ b/sample_app/src/uk/co/alt236/btlescan/activities/DeviceDetailsActivity.java @@ -147,8 +147,7 @@ public class DeviceDetailsActivity extends ListActivity{ case R.id.menu_connect: final Intent intent = new Intent(this, DeviceControlActivity.class); - intent.putExtra(DeviceControlActivity.EXTRAS_DEVICE_NAME, mDevice.getName()); - intent.putExtra(DeviceControlActivity.EXTRAS_DEVICE_ADDRESS, mDevice.getAddress()); + intent.putExtra(DeviceControlActivity.EXTRA_DEVICE, mDevice); startActivity(intent); diff --git a/sample_app/src/uk/co/alt236/btlescan/containers/BluetoothLeDeviceStore.java b/sample_app/src/uk/co/alt236/btlescan/containers/BluetoothLeDeviceStore.java index c41c439..147ca27 100644 --- a/sample_app/src/uk/co/alt236/btlescan/containers/BluetoothLeDeviceStore.java +++ b/sample_app/src/uk/co/alt236/btlescan/containers/BluetoothLeDeviceStore.java @@ -157,10 +157,10 @@ public class BluetoothLeDeviceStore { final String to = null; final String subject = context.getString( - R.string.exporter_email_subject, + R.string.exporter_email_device_list_subject, TimeFormatter.getIsoDateTime(timeInMillis)); - final String message = context.getString(R.string.exporter_email_body); + final String message = context.getString(R.string.exporter_email_device_list_body); final Intent i = new Intent(Intent.ACTION_SEND); i.setType("plain/text"); @@ -173,7 +173,7 @@ public class BluetoothLeDeviceStore { 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_picker_text))); + context.startActivity(Intent.createChooser(i, context.getString(R.string.exporter_email_device_list_picker_text))); } catch (IOException e) { e.printStackTrace();