L'écriture des données en Bluetooth LE la caractéristique de l'Android
Bien que des questions similaires ont été posées, mais c'est légèrement différent. Je sais comment passer des données à un connecté BLE appareil, mais je pense que je suis en train de faire quelque chose de mal pour laquelle j'ai besoin d'aide.
Le code ci-dessous contient toutes les méthodes de ma classe qui est l'extension de BroadcastReceiver.
- Je rechercher et de se connecter à un périphérique spécifié par `PEN_ADDRESS`.
- Dans `onServicesDiscovered` méthode que j'ai regarder pour un service dont le "UUID" contient " abcd`.
- Puis je boucle à travers les caractéristiques de ces services et par les trois caractéristiques spécifiques des chaînes dans leur " UUID`.
- La troisième caractéristique est une écriture caractère par lequel je suis en train d'écrire des données en appelant la méthode " writeCharac(mGatt,writeChar1,123);`
Les données `123` passaient au-dessus est juste un mannequin de données.
J'ai débogué mon code, tout en essayant de l'écriture de cette caractéristique, mais à mettre des points d'arrêt à l'intérieur de la writeCharac
méthode, j'ai trouvé que le status
valeur est false, indiquant que l'écriture n'a pas été couronnée de succès.
Suis-je manqué quelque chose? Svp aider!
public class BackgroundReceiverFire extends BroadcastReceiver {
Context context;
private BluetoothAdapter mBluetoothAdapter;
private BluetoothGatt mGatt;
private BluetoothLeService mBluetoothLeService;
private boolean mScanning;
private final String TAG = "READING: ";
private BluetoothDevice mDevice;
private Handler mHandler;
private static final int REQUEST_ENABLE_BT = 1;
private final String PEN_ADDRESS = "FB:23:AF:42:5C:56";
//Stops scanning after 10 seconds.
private static final long SCAN_PERIOD = 10000;
public void onReceive(Context context, Intent intent) {
this.context = context;
Toast.makeText(context, "Started Scanning", LENGTH_SHORT).show();
initializeBluetooth();
startScan();
}
private void initializeBluetooth() {
mHandler = new Handler();
//Use this check to determine whether BLE is supported on the device. Then you can
//selectively disable BLE-related features.
//Initializes a Bluetooth adapter. For API level 18 and above, get a reference to
//BluetoothAdapter through BluetoothManager.
final BluetoothManager bluetoothManager =
(BluetoothManager) context.getSystemService(Context.BLUETOOTH_SERVICE);
mBluetoothAdapter = bluetoothManager.getAdapter();
//Checks if Bluetooth is supported on the device.
if (mBluetoothAdapter == null) {
Toast.makeText(this.context, "No Bluetooth", LENGTH_SHORT).show();
return;
}
}
private void startScan() {
scanLeDevice(true);
}
private void stopScan() {
scanLeDevice(false);
}
private void scanLeDevice(final boolean enable) {
if (enable) {
//Stops scanning after a pre-defined scan period.
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
mScanning = false;
mBluetoothAdapter.stopLeScan(mLeScanCallback);
}
}, SCAN_PERIOD);
mScanning = true;
//Scanning for the device
mBluetoothAdapter.startLeScan(mLeScanCallback);
} else {
mScanning = false;
mBluetoothAdapter.stopLeScan(mLeScanCallback);
}
}
private BluetoothAdapter.LeScanCallback mLeScanCallback =
new BluetoothAdapter.LeScanCallback() {
@Override
public void onLeScan(final BluetoothDevice device, int rssi, byte[] scanRecord) {
if (device.getAddress().matches(PEN_ADDRESS)) {
connectBluetooth(device);
Toast.makeText(context, "Device Found: " + device.getAddress(), Toast.LENGTH_LONG).show();
}
}
};
private void connectBluetooth(BluetoothDevice insulinPen) {
if (mGatt == null) {
Log.d("connectToDevice", "connecting to device: " + insulinPen.toString());
mDevice = insulinPen;
mGatt = insulinPen.connectGatt(context, true, gattCallback);
scanLeDevice(false);//will stop after first device detection
}
}
private void enableBluetooth() {
if (!mBluetoothAdapter.isEnabled()) {
mBluetoothAdapter.enable();
}
scanLeDevice(true);
}
private void disableBluetooth() {
if (mBluetoothAdapter.isEnabled()) {
mBluetoothAdapter.disable();
}
}
private final BluetoothGattCallback gattCallback = new BluetoothGattCallback() {
@Override
public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
Log.i("onConnectionStateChange", "Status: " + status);
switch (newState) {
case BluetoothProfile.STATE_CONNECTED:
gatt.discoverServices();
break;
case BluetoothProfile.STATE_DISCONNECTED:
Log.e("gattCallback", "STATE_DISCONNECTED");
Log.i("gattCallback", "reconnecting...");
BluetoothDevice mDevice = gatt.getDevice();
mGatt = null;
connectBluetooth(mDevice);
break;
default:
Log.e("gattCallback", "STATE_OTHER");
break;
}
}
public void onServicesDiscovered(BluetoothGatt gatt, int status) {
mGatt = gatt;
List<BluetoothGattService> services = mGatt.getServices();
Log.i("onServicesDiscovered", services.toString());
Iterator<BluetoothGattService> serviceIterator = services.iterator();
while(serviceIterator.hasNext()){
BluetoothGattService bleService = serviceIterator.next();
if(bleService.getUuid().toString().contains("abcd")){
//Toast.makeText(context,"Got the service",Toast.LENGTH_SHORT);
BluetoothGattCharacteristic readChar1 = bleService.getCharacteristics().get(0);
for (BluetoothGattDescriptor descriptor : readChar1.getDescriptors()) {
descriptor.setValue(BluetoothGattDescriptor.ENABLE_INDICATION_VALUE);
mGatt.writeDescriptor(descriptor);
mGatt.setCharacteristicNotification(readChar1, true);
}
//mGatt.readCharacteristic(readChar1);
BluetoothGattCharacteristic readChar2 = bleService.getCharacteristics().get(1);
for (BluetoothGattDescriptor descriptor : readChar2.getDescriptors()) {
descriptor.setValue(BluetoothGattDescriptor.ENABLE_INDICATION_VALUE);
mGatt.writeDescriptor(descriptor);
mGatt.setCharacteristicNotification(readChar2, true);
}
//mGatt.readCharacteristic(readChar2);
BluetoothGattCharacteristic writeChar1 = bleService.getCharacteristics().get(2);
for (BluetoothGattDescriptor descriptor : writeChar1.getDescriptors()) {
descriptor.setValue( BluetoothGattDescriptor.ENABLE_INDICATION_VALUE);
mGatt.writeDescriptor(descriptor);
mGatt.setCharacteristicNotification(writeChar1, true);
}
writeCharac(mGatt,writeChar1,123);
}
}
//gatt.readCharacteristic(therm_char);
}
public void writeCharac(BluetoothGatt gatt, BluetoothGattCharacteristic charac, int value ){
if (mBluetoothAdapter == null || gatt == null) {
Log.w(TAG, "BluetoothAdapter not initialized");
return;
}
/*
BluetoothGattCharacteristic charac = gattService
.getCharacteristic(uuid);
*/
if (charac == null) {
Log.e(TAG, "char not found!");
}
int unixTime = value;
String unixTimeString = Integer.toHexString(unixTime);
byte[] byteArray = hexStringToByteArray(unixTimeString);
charac.setValue(byteArray);
boolean status = mGatt.writeCharacteristic(charac);
if(status){
Toast.makeText(context,"Written Successfully",Toast.LENGTH_SHORT).show();
}else{
Toast.makeText(context,"Error writing characteristic",Toast.LENGTH_SHORT).show();
}
}
public byte[] hexStringToByteArray(String s) {
int len = s.length();
byte[] data = new byte[len/2];
for(int i = 0; i < len; i+=2){
data[i/2] = (byte) ((Character.digit(s.charAt(i), 16) << 4) + Character.digit(s.charAt(i+1), 16));
}
return data;
}
public void onCharacteristicRead(BluetoothGatt gatt,
BluetoothGattCharacteristic
characteristic, int status) {
Log.i("onCharacteristicRead", characteristic.toString());
String characteristicValue = characteristic.getValue().toString();
Log.d("CHARACTERISTIC VALUE: ", characteristicValue);
gatt.disconnect();
}
public void onCharacteristicChanged(BluetoothGatt gatt,
BluetoothGattCharacteristic
characteristic) {
String value = characteristic.getValue().toString();
Log.d(TAG,value);
}
};
OriginalL'auteur abhinavDAIICT | 2016-03-22
Vous devez vous connecter pour publier un commentaire.
Bien que le BLE API asynchrone dans la nature, la transmission du signal est inévitablement synchrone. Vous devez attendre pour la précédente se connecter/écrire/lire l'appel de rappel avant de commencer toute connexion/écriture/lecture de fonctionnement.
Dans votre code
onServicesDiscovered(BluetoothGatt gatt, int status)
fonction, vous avez appelémGatt.writeDescriptor(descriptor)
deux fois avant d'essayer d'écrire de la caractéristique. L'API refusera de démarrer votre demande d'écriture tel qu'il est occupé à écrire le descripteur, et retourne la valeur false pour votremGatt.writeCharacteristic(charac)
appel.Attendez-vous donc pour la writeDescriptor pour rappel, avant d'appeler writeCharacteristic. Cette nature n'est pas bien documenté, mais vous pouvez trouver des sources ici et ici.
gatt.readCharacteristic(readChar1);
etgatt.readCharacteristic(readChar2);
). Je pensais que pour chaque caractéristique de lire/écrire, j'ai besoin d'appelermGatt.writeDescriptor(descriptor)
. Je crois que j'ai compris de façon incorrecte.Vous essayez d'écrire BluetoothGattDescriptor.ENABLE_INDICATION_VALUE le descripteur, qui est totalement hors de propos d'processus de lecture/écriture. Ces lignes de codes sont utilisés pour activer l'indication de caractéristique, qui est complètement un autre type de transmission.
Cela a réglé mon problème quand j'ai essayé de mettre à jour tous mes valeurs, à commencer dans le onServicesDiscovered de rappel et caractéristique n'a pas été écrit, depuis que j'ai également écrit pour le descripteur.
OriginalL'auteur reTs
Merci @technologies des énergies renouvelables et @pooja pour des suggestions. Le problème était dû à ces deux lignes
mGatt = null
connectBluetooth(mDevice);
dans STATE_DISCONNECTED. J'avais pensé à elle, mais ne me souviens pas de la raison exacte. Le poster juste au cas où il est utile.
OriginalL'auteur abhinavDAIICT
Avez-vous vérifié si le "writechar1" le btcharacteristic valeur que vous êtes de passage à writeCharac (le) null?
Ce n'est pas de fournir une réponse à la question. Une fois que vous avez suffisamment de réputation vous serez en mesure de commentaire sur post; fournir des réponses qui ne nécessitent pas de clarification de la asker.
OriginalL'auteur pooja