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.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.
*

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<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:layout_height="match_parent">
<LinearLayout android:orientation="horizontal"
@ -41,7 +42,7 @@
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/label_data"
android:text="@string/label_sensor_value"
android:textSize="18sp" />
<Space android:layout_width="5dp"
android:layout_height="wrap_content"/>
@ -52,4 +53,30 @@
android:layout_height="wrap_content"
android:textSize="18sp" />
</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>

View file

@ -14,7 +14,9 @@
-->
<resources>
<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_writable_value">Writable value:</string>
<string name="label_device_address">Device address:</string>
<string name="label_state">State:</string>
<string name="no_data">No data</string>
@ -32,4 +34,5 @@
<string name="menu_disconnect">Disconnect</string>
<string name="menu_scan">Scan</string>
<string name="menu_stop">Stop</string>
<string name="label_refresh">Update</string>
</resources>