Documente BluetoothLeService
This commit is contained in:
parent
9bdd404fc6
commit
3e78c1e9b0
4 changed files with 88 additions and 10 deletions
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright (C) 2013 The Android Open Source Project
|
||||
* Copyright (C) 2017 Louis-Guillaume Dubois
|
||||
* Copyright (C) 2017 CentraleSupélec
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -57,6 +57,7 @@ public class BluetoothLeService extends Service {
|
|||
private static final int STATE_CONNECTING = 1;
|
||||
private static final int STATE_CONNECTED = 2;
|
||||
|
||||
// Nom des actions envoyées lors des Intents broadcastés
|
||||
public final static String ACTION_GATT_CONNECTED =
|
||||
"fr.cenralesupelec.students.clientble.ACTION_GATT_CONNECTED";
|
||||
public final static String ACTION_GATT_DISCONNECTED =
|
||||
|
@ -73,6 +74,8 @@ public class BluetoothLeService extends Service {
|
|||
|
||||
// Implements callback methods for GATT events that the app cares about. For example,
|
||||
// connection change and services discovered.
|
||||
// Envoie des Intents broadcastés pour permettre à SimpleDetailActivity de récupérer
|
||||
// les valeurs reçues de l’appareil BLE.
|
||||
private final BluetoothGattCallback mGattCallback = new BluetoothGattCallback() {
|
||||
@Override
|
||||
public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
|
||||
|
@ -103,6 +106,13 @@ public class BluetoothLeService extends Service {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Renvoie dans une Intent broadcastée la valeur lue de la caractéristique
|
||||
* demandée.
|
||||
* @param gatt
|
||||
* @param characteristic
|
||||
* @param status
|
||||
*/
|
||||
@Override
|
||||
public void onCharacteristicRead(BluetoothGatt gatt,
|
||||
BluetoothGattCharacteristic characteristic,
|
||||
|
@ -111,8 +121,10 @@ public class BluetoothLeService extends Service {
|
|||
|
||||
if (status == BluetoothGatt.GATT_SUCCESS) {
|
||||
if (GattConstants.SENSOR_CHARACTERISTIC_UUID.equals(uuid)) {
|
||||
// Valeur du potentiomètre.
|
||||
broadcastUpdate(ACTION_SENSOR_VALUE_AVAILABLE, characteristic);
|
||||
} else if (GattConstants.WRITABLE_CHARACTERISTIC_UUID.equals(uuid)) {
|
||||
// Valeur de la caractéristique longue.
|
||||
broadcastUpdate(ACTION_WRITABLE_VALUE_AVAILABLE, characteristic);
|
||||
} else {
|
||||
Log.w(TAG, "UUID non reconnue.");
|
||||
|
@ -120,6 +132,13 @@ public class BluetoothLeService extends Service {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Renvoie dans une Intent broadcastée la valeur écrite de la caractéristique
|
||||
* demandée.
|
||||
* @param gatt
|
||||
* @param characteristic
|
||||
* @param status
|
||||
*/
|
||||
@Override
|
||||
public void onCharacteristicWrite(BluetoothGatt gatt,
|
||||
BluetoothGattCharacteristic characteristic,
|
||||
|
@ -128,8 +147,10 @@ public class BluetoothLeService extends Service {
|
|||
if (status == BluetoothGatt.GATT_SUCCESS) {
|
||||
Log.d(TAG, "Réusssite de l’écriture de la caractéristique.");
|
||||
if (GattConstants.SENSOR_CHARACTERISTIC_UUID.equals(uuid)) {
|
||||
// Valeur du potentiomètre – ne devrait pas se produire (lecture seule.)
|
||||
broadcastUpdate(ACTION_SENSOR_VALUE_AVAILABLE, characteristic);
|
||||
} else if (GattConstants.WRITABLE_CHARACTERISTIC_UUID.equals(uuid)) {
|
||||
// Valeur de la caractéristique longue et éditable.
|
||||
broadcastUpdate(ACTION_WRITABLE_VALUE_AVAILABLE, characteristic);
|
||||
}
|
||||
} else {
|
||||
|
@ -137,6 +158,12 @@ public class BluetoothLeService extends Service {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Renvoie dans une Intent broadcastée la valeur mise à jour d’une caractéristique
|
||||
* (en cas de notification par exemple.)
|
||||
* @param gatt
|
||||
* @param characteristic
|
||||
*/
|
||||
@Override
|
||||
public void onCharacteristicChanged(BluetoothGatt gatt,
|
||||
BluetoothGattCharacteristic characteristic) {
|
||||
|
@ -152,50 +179,81 @@ public class BluetoothLeService extends Service {
|
|||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Méthode d’envoi d’une Intent broadcastée.
|
||||
* @param action nom de l’action
|
||||
*/
|
||||
private void broadcastUpdate(final String action) {
|
||||
Log.d(TAG, "broadcastUpdate(String) appelé.");
|
||||
final Intent intent = new Intent(action);
|
||||
sendBroadcast(intent);
|
||||
}
|
||||
|
||||
/**
|
||||
* Méthode d’envoi d’une Intent broadcastée, avec la valeur d’une caractéristique.
|
||||
* @param action nom de l’action
|
||||
* @param characteristic caractéristique lue, écrite ou mise à jour (notifiée)
|
||||
*/
|
||||
private void broadcastUpdate(final String action,
|
||||
final BluetoothGattCharacteristic characteristic) {
|
||||
|
||||
final Intent intent = new Intent(action);
|
||||
Log.d(TAG, "broadcastUpdate(String, BluetoothGattChar.) appelé.");
|
||||
|
||||
// Valeur brute de la caractéristique.
|
||||
final byte[] data = characteristic.getValue();
|
||||
|
||||
if (data != null && data.length > 0) {
|
||||
// Si c’est la valeur du potentiomètre
|
||||
if (GattConstants.SENSOR_CHARACTERISTIC_UUID.equals(characteristic.getUuid())) {
|
||||
// Lecture de l’entier non signé, d’un ou deux octets (lecture par le CAN sur 16 bits.)
|
||||
final long value =
|
||||
(data.length == 2) ? (data[0] << 8) & 0x0000ff00 | (data[1] << 0) & 0x000000ff
|
||||
: (data[0] << 0) & 0x000000ff;
|
||||
final long max = 65535; // 2^16 - 1
|
||||
final long max = 65535; // 2^16 - 1 : valeur maximale (16 bits)
|
||||
// Envoi d’un pourcentage
|
||||
final double percent = ((double) (100 * value)) / ((double) max);
|
||||
// Envoi sous forme d’une chaîne de caractère, avec la date, pour affichage direct.
|
||||
final String date = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.LONG).format(new Date());
|
||||
intent.putExtra(EXTRA_DATA, String.format("%.3f %%\n(%s)", percent, date));
|
||||
} else {
|
||||
// Sinon, caractéristique longue éditable.
|
||||
final StringBuilder stringBuilder = new StringBuilder(data.length);
|
||||
//stringBuilder.append(String.format("%d", data));/
|
||||
//stringBuilder.append(" --- ");
|
||||
// Représentation au format hexadécimal.
|
||||
for (byte byteChar : data)
|
||||
stringBuilder.append(String.format("%02X ", byteChar));
|
||||
Log.d(TAG, String.format(stringBuilder.toString()));
|
||||
// Envoi de la représentation ASCII puis sur une autre ligne, en hexadécimal.
|
||||
intent.putExtra(EXTRA_DATA, new String(data) + "\n" + stringBuilder.toString());
|
||||
}
|
||||
}
|
||||
sendBroadcast(intent);
|
||||
}
|
||||
|
||||
/**
|
||||
* Classe permettant à une activité d’appeler les méthodes du service.
|
||||
*/
|
||||
public class LocalBinder extends Binder {
|
||||
BluetoothLeService getService() {
|
||||
return BluetoothLeService.this;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Demande de lien à une activité.
|
||||
* @param intent
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public IBinder onBind(Intent intent) {
|
||||
return mBinder;
|
||||
}
|
||||
|
||||
/**
|
||||
* Arrêt du lien avec une activité.
|
||||
* @param intent
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public boolean onUnbind(Intent intent) {
|
||||
// After using a given device, you should make sure that BluetoothGatt.close() is called
|
||||
|
@ -205,6 +263,9 @@ public class BluetoothLeService extends Service {
|
|||
return super.onUnbind(intent);
|
||||
}
|
||||
|
||||
/**
|
||||
* Instance de la classe de liaison avec une activité.
|
||||
*/
|
||||
private final IBinder mBinder = new LocalBinder();
|
||||
|
||||
/**
|
||||
|
@ -314,6 +375,11 @@ public class BluetoothLeService extends Service {
|
|||
mBluetoothGatt.readCharacteristic(characteristic);
|
||||
}
|
||||
|
||||
/**
|
||||
* Écriture d’une caractéristique sur le serveur BLE de l’appareil connecté.
|
||||
* @param characteristic caractéristique où écrire
|
||||
* @param data données brutes à envoyer pour écriture
|
||||
*/
|
||||
public void writeCharacterisitic(BluetoothGattCharacteristic characteristic, byte[] data) {
|
||||
if (mBluetoothAdapter == null || mBluetoothGatt == null) {
|
||||
Log.w(TAG, "BluetoothAdapter not initialized");
|
||||
|
@ -335,7 +401,9 @@ public class BluetoothLeService extends Service {
|
|||
Log.w(TAG, "BluetoothAdapter not initialized");
|
||||
return;
|
||||
}
|
||||
Log.d(TAG, "setChar.Notification() appelé");
|
||||
Log.d(TAG, "setCharacteristicNotification() appelé");
|
||||
// Ne pas oublier d’écrire le descripteur de la caractéristique pour que les serveur
|
||||
// BLE de l’appareil connecté envoie les notifications.
|
||||
if (GattConstants.SENSOR_CHARACTERISTIC_UUID.equals(characteristic.getUuid())) {
|
||||
BluetoothGattDescriptor descriptor = characteristic.getDescriptor(GattConstants.CHARACTERISTIC_CONFIG_UUID);
|
||||
descriptor.setValue(
|
||||
|
@ -343,12 +411,16 @@ public class BluetoothLeService extends Service {
|
|||
: BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE
|
||||
);
|
||||
try {
|
||||
// Parfois plusieurs essais sont nécessaires (l’interface BLE peut être
|
||||
// occupée avec d’autres opérations.)
|
||||
while (!mBluetoothGatt.writeDescriptor(descriptor))
|
||||
sleep(500);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
// Demande à l’appareil Android d’écouter et de prendre en compte les notifications
|
||||
// envoyées par l’appareil connecté.
|
||||
mBluetoothGatt.setCharacteristicNotification(characteristic, enabled);
|
||||
}
|
||||
|
||||
|
@ -363,6 +435,10 @@ public class BluetoothLeService extends Service {
|
|||
return mBluetoothGatt.getServices();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retourne notre service privé.
|
||||
* @return
|
||||
*/
|
||||
public BluetoothGattService getPrivateService() {
|
||||
if (mBluetoothGatt == null) return null;
|
||||
return mBluetoothGatt.getService(GattConstants.PRIVATE_SERVICE_UUID);
|
||||
|
|
|
@ -41,6 +41,8 @@ import java.util.HashMap;
|
|||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Activité proposée dans l’application de démonstration, non utilisée dans notre application.
|
||||
*
|
||||
* For a given BLE device, this Activity provides the user interface to connect, display data,
|
||||
* and display GATT services and characteristics supported by the device. The Activity
|
||||
* communicates with {@code BluetoothLeService}, which in turn interacts with the
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright (C) 2013 The Android Open Source Project
|
||||
* Copyright (C) 2017 Louis-Guillaume Dubois
|
||||
* Copyright (C) 2017 CentraleSupélec
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
|
|
@ -21,7 +21,7 @@ import java.util.HashMap;
|
|||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* This class includes a small subset of standard GATT attributes for demonstration purposes.
|
||||
* Stockage des UUID des services et caractéristiques BLE interrogées.
|
||||
*/
|
||||
public class GattConstants {
|
||||
private static HashMap<String, String> attributes = new HashMap();
|
||||
|
@ -40,7 +40,7 @@ public class GattConstants {
|
|||
UUID.fromString(SENSOR_CHARACTERISTIC_UUID_STRING);
|
||||
|
||||
// UUID (v4, cf. supra) de notre caractéristiuqe privée, lisible, éditable et notifiable,
|
||||
// de trois octets.
|
||||
// de vingt octets.
|
||||
public static final String WRITABLE_CHARACTERISTIC_UUID_STRING =
|
||||
"c093685d-005f-4d3c-8240-6d3020a2c608";
|
||||
public static final UUID WRITABLE_CHARACTERISTIC_UUID =
|
||||
|
@ -54,7 +54,7 @@ public class GattConstants {
|
|||
public static final UUID CHARACTERISTIC_CONFIG_UUID =
|
||||
UUID.fromString(CHARACTERISTIC_CONFIG_UUID_STRING);
|
||||
|
||||
// UUID de services connus — utilisés dans DeviceControlActivity
|
||||
// UUID de services connus — utilisés dans DeviceControlActivity uniquement
|
||||
static {
|
||||
// Sample Services.
|
||||
attributes.put("0000180a-0000-1000-8000-00805f9b34fb", "Device Information");
|
||||
|
@ -73,7 +73,7 @@ public class GattConstants {
|
|||
attributes.put(WRITABLE_CHARACTERISTIC_UUID_STRING, "3-byte rw notif. char.");
|
||||
}
|
||||
|
||||
// recherche du nom de services connus — utilisé dans DeviceControlActivity
|
||||
// recherche du nom de services connus — utilisé dans DeviceControlActivity uniquement
|
||||
public static String lookup(String uuid, String defaultName) {
|
||||
String name = attributes.get(uuid);
|
||||
return name == null ? defaultName : name;
|
||||
|
|
Loading…
Reference in a new issue