diff --git a/Application/src/main/java/fr/centralesupelec/students/clientble/BluetoothLeService.java b/Application/src/main/java/fr/centralesupelec/students/clientble/BluetoothLeService.java index e5e7e30..02de920 100644 --- a/Application/src/main/java/fr/centralesupelec/students/clientble/BluetoothLeService.java +++ b/Application/src/main/java/fr/centralesupelec/students/clientble/BluetoothLeService.java @@ -36,6 +36,7 @@ import android.util.Log; import java.text.DateFormat; import java.util.Date; import java.util.List; +import java.util.UUID; import static java.lang.Thread.sleep; @@ -62,8 +63,10 @@ public class BluetoothLeService extends Service { "fr.centralesupelec.students.clientble.ACTION_GATT_DISCONNECTED"; public final static String ACTION_GATT_SERVICES_DISCOVERED = "fr.centralesupelec.students.clientble.ACTION_GATT_SERVICES_DISCOVERED"; - public final static String ACTION_DATA_AVAILABLE = - "fr.centralesupelec.students.clientble.ACTION_DATA_AVAILABLE"; + public final static String ACTION_SENSOR_VALUE_AVAILABLE = + "fr.centralesupelec.students.clientble.ACTION_SENSOR_VALUE_AVAILABLE"; + public final static String ACTION_WRITABLE_VALUE_AVAILABLE = + "fr.centralesupelec.students.clientble.ACTION_WRITABLE_VALUE_AVAILABLE"; public final static String EXTRA_DATA = "fr.centralesupelec.students.clientble.EXTRA_DATA"; @@ -104,8 +107,33 @@ public class BluetoothLeService extends Service { public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) { + final UUID uuid = characteristic.getUuid(); + if (status == BluetoothGatt.GATT_SUCCESS) { - broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic); + if (GattConstants.SENSOR_CHARACTERISTIC_UUID.equals(uuid)) { + broadcastUpdate(ACTION_SENSOR_VALUE_AVAILABLE, characteristic); + } else if (GattConstants.WRITABLE_CHARACTERISTIC_UUID.equals(uuid)) { + broadcastUpdate(ACTION_WRITABLE_VALUE_AVAILABLE, characteristic); + } else { + Log.w(TAG, "UUID non reconnue."); + } + } + } + + @Override + public void onCharacteristicWrite(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, + int status) { + final UUID uuid = characteristic.getUuid(); + if (status == BluetoothGatt.GATT_SUCCESS) { + Log.d(TAG, "Réusssite de l’écriture de la caractéristique."); + if (GattConstants.SENSOR_CHARACTERISTIC_UUID.equals(uuid)) { + broadcastUpdate(ACTION_SENSOR_VALUE_AVAILABLE, characteristic); + } else if (GattConstants.WRITABLE_CHARACTERISTIC_UUID.equals(uuid)) { + broadcastUpdate(ACTION_WRITABLE_VALUE_AVAILABLE, characteristic); + } + } else { + Log.w(TAG, "Échec de l’écriture de la caractéristique."); } } @@ -113,7 +141,14 @@ public class BluetoothLeService extends Service { public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) { Log.d(TAG, "onCharacteristicChanged() appelé."); - broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic); + final UUID uuid = characteristic.getUuid(); + if (GattConstants.SENSOR_CHARACTERISTIC_UUID.equals(uuid)) { + broadcastUpdate(ACTION_SENSOR_VALUE_AVAILABLE, characteristic); + } else if (GattConstants.WRITABLE_CHARACTERISTIC_UUID.equals(uuid)) { + broadcastUpdate(ACTION_WRITABLE_VALUE_AVAILABLE, characteristic); + } else { + Log.w(TAG, "UUID non reconnue"); + } } }; @@ -279,6 +314,15 @@ public class BluetoothLeService extends Service { mBluetoothGatt.readCharacteristic(characteristic); } + public void writeCharacterisitic(BluetoothGattCharacteristic characteristic, byte[] data) { + if (mBluetoothAdapter == null || mBluetoothGatt == null) { + Log.w(TAG, "BluetoothAdapter not initialized"); + return; + } + characteristic.setValue(data); + mBluetoothGatt.writeCharacteristic(characteristic); + } + /** * Enables or disables notification on a give characteristic. * diff --git a/Application/src/main/java/fr/centralesupelec/students/clientble/DeviceControlActivity.java b/Application/src/main/java/fr/centralesupelec/students/clientble/DeviceControlActivity.java index 9f1230b..3c9df39 100644 --- a/Application/src/main/java/fr/centralesupelec/students/clientble/DeviceControlActivity.java +++ b/Application/src/main/java/fr/centralesupelec/students/clientble/DeviceControlActivity.java @@ -90,7 +90,7 @@ public class DeviceControlActivity extends Activity { // ACTION_GATT_CONNECTED: connected to a GATT server. // ACTION_GATT_DISCONNECTED: disconnected from a GATT server. // ACTION_GATT_SERVICES_DISCOVERED: discovered GATT services. - // ACTION_DATA_AVAILABLE: received data from the device. This can be a result of read + // ACTION_SENSOR_VALUE_AVAILABLE: received data from the device. This can be a result of read // or notification operations. private final BroadcastReceiver mGattUpdateReceiver = new BroadcastReceiver() { @Override @@ -108,7 +108,7 @@ public class DeviceControlActivity extends Activity { } else if (BluetoothLeService.ACTION_GATT_SERVICES_DISCOVERED.equals(action)) { // Show all the supported services and characteristics on the user interface. displayGattServices(mBluetoothLeService.getSupportedGattServices()); - } else if (BluetoothLeService.ACTION_DATA_AVAILABLE.equals(action)) { + } else if (BluetoothLeService.ACTION_SENSOR_VALUE_AVAILABLE.equals(action)) { displayData(intent.getStringExtra(BluetoothLeService.EXTRA_DATA)); } } @@ -304,7 +304,7 @@ public class DeviceControlActivity extends Activity { intentFilter.addAction(BluetoothLeService.ACTION_GATT_CONNECTED); intentFilter.addAction(BluetoothLeService.ACTION_GATT_DISCONNECTED); intentFilter.addAction(BluetoothLeService.ACTION_GATT_SERVICES_DISCOVERED); - intentFilter.addAction(BluetoothLeService.ACTION_DATA_AVAILABLE); + intentFilter.addAction(BluetoothLeService.ACTION_SENSOR_VALUE_AVAILABLE); return intentFilter; } } diff --git a/Application/src/main/java/fr/centralesupelec/students/clientble/SimpleDetailActivity.java b/Application/src/main/java/fr/centralesupelec/students/clientble/SimpleDetailActivity.java index b2b6803..72fd31e 100644 --- a/Application/src/main/java/fr/centralesupelec/students/clientble/SimpleDetailActivity.java +++ b/Application/src/main/java/fr/centralesupelec/students/clientble/SimpleDetailActivity.java @@ -13,6 +13,7 @@ import android.os.IBinder; import android.os.Bundle; import android.util.Log; import android.view.MenuItem; +import android.view.View; import android.widget.TextView; public class SimpleDetailActivity extends Activity { @@ -24,6 +25,7 @@ public class SimpleDetailActivity extends Activity { private TextView mDeviceAddressView; private TextView mConnectionStateView; private TextView mSensorValueView; + private TextView mWritableValueView; private String mDeviceName; private String mDeviceAddress; @@ -32,6 +34,7 @@ public class SimpleDetailActivity extends Activity { private BluetoothLeService mBluetoothLeService; private boolean mConnected = false; private BluetoothGattCharacteristic mSensorValueCharac; + private BluetoothGattCharacteristic mWritableValueCharac; // Code to manage Service lifecycle. @@ -58,7 +61,7 @@ public class SimpleDetailActivity extends Activity { // ACTION_GATT_CONNECTED: connected to a GATT server. // ACTION_GATT_DISCONNECTED: disconnected from a GATT server. // ACTION_GATT_SERVICES_DISCOVERED: discovered GATT services. - // ACTION_DATA_AVAILABLE: received data from the device. This can be a result of read + // ACTION_SENSOR_VALUE_AVAILABLE: received data from the device. This can be a result of read // or notification operations. private final BroadcastReceiver mGattUpdateReceiver = new BroadcastReceiver() { @Override @@ -76,18 +79,26 @@ public class SimpleDetailActivity extends Activity { } else if (BluetoothLeService.ACTION_GATT_SERVICES_DISCOVERED.equals(action)) { // Show all the supported services and characteristics on the user interface. Log.d(TAG, "ACTION_GATT_SERVICES_DISCOVERED reçu."); - displayValues(); - } else if (BluetoothLeService.ACTION_DATA_AVAILABLE.equals(action)) { - Log.d(TAG, "ACTION_DATA_AVAILABLE reçu."); + requestValues(); + } else if (BluetoothLeService.ACTION_SENSOR_VALUE_AVAILABLE.equals(action)) { + Log.d(TAG, "ACTION_SENSOR_VALUE_AVAILABLE reçu."); final String data = intent.getStringExtra(BluetoothLeService.EXTRA_DATA); Log.d(TAG, data); - displayData(data); + displaySensorValue(data); + } else if (BluetoothLeService.ACTION_WRITABLE_VALUE_AVAILABLE.equals(action)) { + Log.d(TAG, "ACTION_WRITABLE_VALUE_AVAILABLE reçu."); + final String data = intent.getStringExtra(BluetoothLeService.EXTRA_DATA); + Log.d(TAG, data); + displayWritableValue(data); + } else { + Log.w(TAG, "Action non reconnue."); } } }; private void clearUI() { mSensorValueView.setText(R.string.no_data); + mWritableValueView.setText(R.string.no_data); } @Override @@ -96,16 +107,15 @@ public class SimpleDetailActivity extends Activity { setContentView(R.layout.simple_detail_layout); final Intent intent = getIntent(); - mDeviceName = intent.getStringExtra(EXTRAS_DEVICE_NAME); - mDeviceAddress = intent.getStringExtra(EXTRAS_DEVICE_ADDRESS); + mDeviceAddressView = (TextView) findViewById(R.id.device_address); mDeviceAddressView.setText(mDeviceAddress); mConnectionStateView = (TextView) findViewById(R.id.connection_state); - mSensorValueView = (TextView) findViewById(R.id.sensor_value); + mWritableValueView = (TextView) findViewById(R.id.writable_value); getActionBar().setTitle(mDeviceName); getActionBar().setDisplayHomeAsUpEnabled(true); @@ -182,13 +192,39 @@ public class SimpleDetailActivity extends Activity { }); } - private void displayData(String data) { + private void displaySensorValue(String data) { if (data != null) { mSensorValueView.setText(data); } } - private void displayValues() { + private void displayWritableValue(String data) { + if (data != null) { + mWritableValueView.setText(data); + } + } + + public void onRefreshClick(View view) { + Log.d(TAG, "onRefreshClick()"); + requestWritableValue(); + } + + private void requestWritableValue() { + BluetoothGattService privateService = mBluetoothLeService.getPrivateService(); + if (privateService == null) { + Log.w(TAG, "Service Gatt privé non détecté."); + return; + } + mWritableValueCharac = + privateService.getCharacteristic(GattConstants.WRITABLE_CHARACTERISTIC_UUID); + if (mWritableValueCharac != null) { + mBluetoothLeService.readCharacteristic(mWritableValueCharac); + } else { + Log.w(TAG, "WRITABLE_CHARACTERISTIC_UUID non trouvé."); + } + } + + private void requestAndSubsribeSensorValue() { BluetoothGattService privateService = mBluetoothLeService.getPrivateService(); if (privateService == null) { Log.w(TAG, "Service Gatt privé non détecté."); @@ -196,12 +232,23 @@ public class SimpleDetailActivity extends Activity { } mSensorValueCharac = privateService.getCharacteristic(GattConstants.SENSOR_CHARACTERISTIC_UUID); - final int charaProp = mSensorValueCharac.getProperties(); - mBluetoothLeService.readCharacteristic(mSensorValueCharac); - if ((charaProp | BluetoothGattCharacteristic.PROPERTY_NOTIFY) > 0) { - Log.d(TAG, "Demande de notification."); - mBluetoothLeService.setCharacteristicNotification(mSensorValueCharac, true); + if (mSensorValueCharac != null) { + mBluetoothLeService.readCharacteristic(mSensorValueCharac); + final int charaProp = mSensorValueCharac.getProperties(); + mBluetoothLeService.readCharacteristic(mSensorValueCharac); + if ((charaProp | BluetoothGattCharacteristic.PROPERTY_NOTIFY) > 0) { + Log.d(TAG, "Demande de notification."); + mBluetoothLeService.setCharacteristicNotification(mSensorValueCharac, true); + } + } else { + Log.w(TAG, "SENSOR_CHARACTERISTIC_UUID non trouvé"); } + + } + + private void requestValues() { + requestWritableValue(); + requestAndSubsribeSensorValue(); } private static IntentFilter makeGattUpdateIntentFilter() { @@ -209,7 +256,8 @@ public class SimpleDetailActivity extends Activity { intentFilter.addAction(BluetoothLeService.ACTION_GATT_CONNECTED); intentFilter.addAction(BluetoothLeService.ACTION_GATT_DISCONNECTED); intentFilter.addAction(BluetoothLeService.ACTION_GATT_SERVICES_DISCOVERED); - intentFilter.addAction(BluetoothLeService.ACTION_DATA_AVAILABLE); + intentFilter.addAction(BluetoothLeService.ACTION_SENSOR_VALUE_AVAILABLE); + intentFilter.addAction(BluetoothLeService.ACTION_WRITABLE_VALUE_AVAILABLE); return intentFilter; } } diff --git a/Application/src/main/res/layout/simple_detail_layout.xml b/Application/src/main/res/layout/simple_detail_layout.xml index 5511b28..2d74f6b 100644 --- a/Application/src/main/res/layout/simple_detail_layout.xml +++ b/Application/src/main/res/layout/simple_detail_layout.xml @@ -1,5 +1,6 @@ @@ -52,4 +53,30 @@ android:layout_height="wrap_content" android:textSize="18sp" /> + + + + + + + + +