Affiche la caractéristique éditable

This commit is contained in:
Louis-Guillaume DUBOIS 2017-06-06 18:28:11 +02:00
parent 3bc79cf416
commit 51aa931b68
5 changed files with 146 additions and 24 deletions

View file

@ -36,6 +36,7 @@ import android.util.Log;
import java.text.DateFormat; import java.text.DateFormat;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import java.util.UUID;
import static java.lang.Thread.sleep; import static java.lang.Thread.sleep;
@ -62,8 +63,10 @@ public class BluetoothLeService extends Service {
"fr.centralesupelec.students.clientble.ACTION_GATT_DISCONNECTED"; "fr.centralesupelec.students.clientble.ACTION_GATT_DISCONNECTED";
public final static String ACTION_GATT_SERVICES_DISCOVERED = public final static String ACTION_GATT_SERVICES_DISCOVERED =
"fr.centralesupelec.students.clientble.ACTION_GATT_SERVICES_DISCOVERED"; "fr.centralesupelec.students.clientble.ACTION_GATT_SERVICES_DISCOVERED";
public final static String ACTION_DATA_AVAILABLE = public final static String ACTION_SENSOR_VALUE_AVAILABLE =
"fr.centralesupelec.students.clientble.ACTION_DATA_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 = public final static String EXTRA_DATA =
"fr.centralesupelec.students.clientble.EXTRA_DATA"; "fr.centralesupelec.students.clientble.EXTRA_DATA";
@ -104,8 +107,33 @@ public class BluetoothLeService extends Service {
public void onCharacteristicRead(BluetoothGatt gatt, public void onCharacteristicRead(BluetoothGatt gatt,
BluetoothGattCharacteristic characteristic, BluetoothGattCharacteristic characteristic,
int status) { int status) {
final UUID uuid = characteristic.getUuid();
if (status == BluetoothGatt.GATT_SUCCESS) { 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, public void onCharacteristicChanged(BluetoothGatt gatt,
BluetoothGattCharacteristic characteristic) { BluetoothGattCharacteristic characteristic) {
Log.d(TAG, "onCharacteristicChanged() appelé."); 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); 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. * Enables or disables notification on a give characteristic.
* *

View file

@ -90,7 +90,7 @@ public class DeviceControlActivity extends Activity {
// ACTION_GATT_CONNECTED: connected to a GATT server. // ACTION_GATT_CONNECTED: connected to a GATT server.
// ACTION_GATT_DISCONNECTED: disconnected from a GATT server. // ACTION_GATT_DISCONNECTED: disconnected from a GATT server.
// ACTION_GATT_SERVICES_DISCOVERED: discovered GATT services. // 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. // or notification operations.
private final BroadcastReceiver mGattUpdateReceiver = new BroadcastReceiver() { private final BroadcastReceiver mGattUpdateReceiver = new BroadcastReceiver() {
@Override @Override
@ -108,7 +108,7 @@ public class DeviceControlActivity extends Activity {
} else if (BluetoothLeService.ACTION_GATT_SERVICES_DISCOVERED.equals(action)) { } else if (BluetoothLeService.ACTION_GATT_SERVICES_DISCOVERED.equals(action)) {
// Show all the supported services and characteristics on the user interface. // Show all the supported services and characteristics on the user interface.
displayGattServices(mBluetoothLeService.getSupportedGattServices()); 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)); 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_CONNECTED);
intentFilter.addAction(BluetoothLeService.ACTION_GATT_DISCONNECTED); intentFilter.addAction(BluetoothLeService.ACTION_GATT_DISCONNECTED);
intentFilter.addAction(BluetoothLeService.ACTION_GATT_SERVICES_DISCOVERED); intentFilter.addAction(BluetoothLeService.ACTION_GATT_SERVICES_DISCOVERED);
intentFilter.addAction(BluetoothLeService.ACTION_DATA_AVAILABLE); intentFilter.addAction(BluetoothLeService.ACTION_SENSOR_VALUE_AVAILABLE);
return intentFilter; return intentFilter;
} }
} }

View file

@ -13,6 +13,7 @@ import android.os.IBinder;
import android.os.Bundle; import android.os.Bundle;
import android.util.Log; import android.util.Log;
import android.view.MenuItem; import android.view.MenuItem;
import android.view.View;
import android.widget.TextView; import android.widget.TextView;
public class SimpleDetailActivity extends Activity { public class SimpleDetailActivity extends Activity {
@ -24,6 +25,7 @@ public class SimpleDetailActivity extends Activity {
private TextView mDeviceAddressView; private TextView mDeviceAddressView;
private TextView mConnectionStateView; private TextView mConnectionStateView;
private TextView mSensorValueView; private TextView mSensorValueView;
private TextView mWritableValueView;
private String mDeviceName; private String mDeviceName;
private String mDeviceAddress; private String mDeviceAddress;
@ -32,6 +34,7 @@ public class SimpleDetailActivity extends Activity {
private BluetoothLeService mBluetoothLeService; private BluetoothLeService mBluetoothLeService;
private boolean mConnected = false; private boolean mConnected = false;
private BluetoothGattCharacteristic mSensorValueCharac; private BluetoothGattCharacteristic mSensorValueCharac;
private BluetoothGattCharacteristic mWritableValueCharac;
// Code to manage Service lifecycle. // Code to manage Service lifecycle.
@ -58,7 +61,7 @@ public class SimpleDetailActivity extends Activity {
// ACTION_GATT_CONNECTED: connected to a GATT server. // ACTION_GATT_CONNECTED: connected to a GATT server.
// ACTION_GATT_DISCONNECTED: disconnected from a GATT server. // ACTION_GATT_DISCONNECTED: disconnected from a GATT server.
// ACTION_GATT_SERVICES_DISCOVERED: discovered GATT services. // 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. // or notification operations.
private final BroadcastReceiver mGattUpdateReceiver = new BroadcastReceiver() { private final BroadcastReceiver mGattUpdateReceiver = new BroadcastReceiver() {
@Override @Override
@ -76,18 +79,26 @@ public class SimpleDetailActivity extends Activity {
} else if (BluetoothLeService.ACTION_GATT_SERVICES_DISCOVERED.equals(action)) { } else if (BluetoothLeService.ACTION_GATT_SERVICES_DISCOVERED.equals(action)) {
// Show all the supported services and characteristics on the user interface. // Show all the supported services and characteristics on the user interface.
Log.d(TAG, "ACTION_GATT_SERVICES_DISCOVERED reçu."); Log.d(TAG, "ACTION_GATT_SERVICES_DISCOVERED reçu.");
displayValues(); requestValues();
} else if (BluetoothLeService.ACTION_DATA_AVAILABLE.equals(action)) { } else if (BluetoothLeService.ACTION_SENSOR_VALUE_AVAILABLE.equals(action)) {
Log.d(TAG, "ACTION_DATA_AVAILABLE reçu."); Log.d(TAG, "ACTION_SENSOR_VALUE_AVAILABLE reçu.");
final String data = intent.getStringExtra(BluetoothLeService.EXTRA_DATA); final String data = intent.getStringExtra(BluetoothLeService.EXTRA_DATA);
Log.d(TAG, 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() { private void clearUI() {
mSensorValueView.setText(R.string.no_data); mSensorValueView.setText(R.string.no_data);
mWritableValueView.setText(R.string.no_data);
} }
@Override @Override
@ -96,16 +107,15 @@ public class SimpleDetailActivity extends Activity {
setContentView(R.layout.simple_detail_layout); setContentView(R.layout.simple_detail_layout);
final Intent intent = getIntent(); final Intent intent = getIntent();
mDeviceName = intent.getStringExtra(EXTRAS_DEVICE_NAME); mDeviceName = intent.getStringExtra(EXTRAS_DEVICE_NAME);
mDeviceAddress = intent.getStringExtra(EXTRAS_DEVICE_ADDRESS); mDeviceAddress = intent.getStringExtra(EXTRAS_DEVICE_ADDRESS);
mDeviceAddressView = (TextView) findViewById(R.id.device_address); mDeviceAddressView = (TextView) findViewById(R.id.device_address);
mDeviceAddressView.setText(mDeviceAddress); mDeviceAddressView.setText(mDeviceAddress);
mConnectionStateView = (TextView) findViewById(R.id.connection_state); mConnectionStateView = (TextView) findViewById(R.id.connection_state);
mSensorValueView = (TextView) findViewById(R.id.sensor_value); mSensorValueView = (TextView) findViewById(R.id.sensor_value);
mWritableValueView = (TextView) findViewById(R.id.writable_value);
getActionBar().setTitle(mDeviceName); getActionBar().setTitle(mDeviceName);
getActionBar().setDisplayHomeAsUpEnabled(true); 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) { if (data != null) {
mSensorValueView.setText(data); 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(); BluetoothGattService privateService = mBluetoothLeService.getPrivateService();
if (privateService == null) { if (privateService == null) {
Log.w(TAG, "Service Gatt privé non détecté."); Log.w(TAG, "Service Gatt privé non détecté.");
@ -196,12 +232,23 @@ public class SimpleDetailActivity extends Activity {
} }
mSensorValueCharac = mSensorValueCharac =
privateService.getCharacteristic(GattConstants.SENSOR_CHARACTERISTIC_UUID); privateService.getCharacteristic(GattConstants.SENSOR_CHARACTERISTIC_UUID);
if (mSensorValueCharac != null) {
mBluetoothLeService.readCharacteristic(mSensorValueCharac);
final int charaProp = mSensorValueCharac.getProperties(); final int charaProp = mSensorValueCharac.getProperties();
mBluetoothLeService.readCharacteristic(mSensorValueCharac); mBluetoothLeService.readCharacteristic(mSensorValueCharac);
if ((charaProp | BluetoothGattCharacteristic.PROPERTY_NOTIFY) > 0) { if ((charaProp | BluetoothGattCharacteristic.PROPERTY_NOTIFY) > 0) {
Log.d(TAG, "Demande de notification."); Log.d(TAG, "Demande de notification.");
mBluetoothLeService.setCharacteristicNotification(mSensorValueCharac, true); mBluetoothLeService.setCharacteristicNotification(mSensorValueCharac, true);
} }
} else {
Log.w(TAG, "SENSOR_CHARACTERISTIC_UUID non trouvé");
}
}
private void requestValues() {
requestWritableValue();
requestAndSubsribeSensorValue();
} }
private static IntentFilter makeGattUpdateIntentFilter() { private static IntentFilter makeGattUpdateIntentFilter() {
@ -209,7 +256,8 @@ public class SimpleDetailActivity extends Activity {
intentFilter.addAction(BluetoothLeService.ACTION_GATT_CONNECTED); intentFilter.addAction(BluetoothLeService.ACTION_GATT_CONNECTED);
intentFilter.addAction(BluetoothLeService.ACTION_GATT_DISCONNECTED); intentFilter.addAction(BluetoothLeService.ACTION_GATT_DISCONNECTED);
intentFilter.addAction(BluetoothLeService.ACTION_GATT_SERVICES_DISCOVERED); 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; return intentFilter;
} }
} }

View file

@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical" android:layout_width="match_parent" android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="match_parent">
<LinearLayout android:orientation="horizontal" <LinearLayout android:orientation="horizontal"
@ -41,7 +42,7 @@
<TextView <TextView
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/label_data" android:text="@string/label_sensor_value"
android:textSize="18sp" /> android:textSize="18sp" />
<Space android:layout_width="5dp" <Space android:layout_width="5dp"
android:layout_height="wrap_content"/> android:layout_height="wrap_content"/>
@ -52,4 +53,30 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:textSize="18sp" /> android:textSize="18sp" />
</LinearLayout> </LinearLayout>
<LinearLayout android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/label_writable_value"
android:textSize="18sp" />
<Space android:layout_width="5dp"
android:layout_height="wrap_content"/>
<TextView
android:id="@+id/writable_value"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="18sp" />
</LinearLayout>
<Button
android:id="@+id/button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="onRefreshClick"
android:text="@string/label_refresh" />
</LinearLayout> </LinearLayout>

View file

@ -14,7 +14,9 @@
--> -->
<resources> <resources>
<string name="ble_not_supported">BLE is not supported</string> <string name="ble_not_supported">BLE is not supported</string>
<string name="label_sensor_value">Sensor value:</string>
<string name="label_data">Data:</string> <string name="label_data">Data:</string>
<string name="label_writable_value">Writable value:</string>
<string name="label_device_address">Device address:</string> <string name="label_device_address">Device address:</string>
<string name="label_state">State:</string> <string name="label_state">State:</string>
<string name="no_data">No data</string> <string name="no_data">No data</string>
@ -32,4 +34,5 @@
<string name="menu_disconnect">Disconnect</string> <string name="menu_disconnect">Disconnect</string>
<string name="menu_scan">Scan</string> <string name="menu_scan">Scan</string>
<string name="menu_stop">Stop</string> <string name="menu_stop">Stop</string>
<string name="label_refresh">Update</string>
</resources> </resources>