2016-03-22 14 views
4

Obwohl ähnliche Fragen gestellt wurden, aber es ist etwas anders. Ich weiß, wie man Daten an ein angeschlossenes BLE-Gerät weitergibt, aber ich denke, dass ich etwas falsch mache, für das ich Hilfe brauche. Der folgende Code enthält alle Methoden aus meiner Klasse, die BroadcastReceiver erweitert.Schreiben von Daten in Bluetooth LE-Eigenschaft in Android

  1. Ich scanne und verbinde mich mit einem durch `PEN_ADDRESS` spezifizierten Gerät.
  2. In 'onServicesDiscovered' Methode suche ich nach einem Dienst, dessen `UUID` `abcd` enthält.
  3. Dann durchschlinge ich die Eigenschaften dieser Dienste und suche nach drei Eigenschaften mit bestimmten Strings in ihrer `UUID`.
  4. Die dritte Eigenschaft ist eine beschreibbare Eigenschaft, in der ich versuche, Daten durch Aufruf der Methode `writeCharac (mGatt, writeChar1,123) zu schreiben;` Die oben angegebenen Daten `123` sind nur Dummy-Daten.

ich meinen Code auf Fehler während dieser Eigenschaft versucht zu schreiben, sondern auf Stützpunkte innerhalb der writeCharac Methode setzen, fand ich, dass der status Wert falsch ist, was darauf hinwies, dass der Schreibvorgang nicht erfolgreich war. Fehle ich hier etwas? Bitte helfen Sie!

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

    }; 

Antwort

-2

Haben Sie überprüfen, ob die 'writechar1' der btcharacteristic Wert, den Sie writeCharac sind vorbei() null?

+0

Ja, ich tat, es ist nicht null. – abhinavDAIICT

+0

Dies liefert keine Antwort auf die Frage. Sobald Sie genügend [Reputation] (// stackoverflow.com/help/whats-reputation) haben, können Sie [jeden Beitrag kommentieren] (// stackoverflow.com/privileges/comment); statt dessen [gibt Antworten, die vom Fragesteller nicht geklärt werden müssen] (http://meta.stackexchange.com/q/214173/165483). –

3

Obwohl die BLE-API asynchron ist, ist die tatsächliche Signalübertragung zwangsläufig synchron. Sie müssen auf den vorherigen Verbindungs-/Schreib-/Leseaufruf warten, bevor Sie einen Verbindungs-/Schreib-/Lesevorgang starten.

In Ihrem Code onServicesDiscovered(BluetoothGatt gatt, int status) Funktion haben Sie zweimal mGatt.writeDescriptor(descriptor) aufgerufen, bevor Sie versuchen, das Merkmal zu schreiben. Die API wird es ablehnen, Ihre Schreibanforderung zu starten, da sie damit beschäftigt ist, den Deskriptor zu schreiben, und für Ihren Aufruf mGatt.writeCharacteristic(charac) den Wert false zurückgibt.

Warten Sie also, bis der WriteDescriptor vor dem Aufruf von writeCharacteristic einen Rückruf ausführt. Diese Art ist nicht gut dokumentiert, aber Sie können einige Quelle here und here finden.

+0

Vielen Dank @reTs. Ich werde es versuchen und aktualisieren, wenn es funktioniert. Nur ein Zweifel, ich beabsichtige auch, zwei Merkmale zu lesen (siehe kommentierte Zeilen - 'gatt.readCharacteristic (readChar1);' und 'gatt.readCharacteristic (readChar2);'). Ich dachte für jedes Merkmal lesen/schreiben, ich muss 'mGatt.writeDescriptor (descriptor)' aufrufen. Ich glaube ich habe es falsch verstanden. – abhinavDAIICT

+0

@abhinavDAIICT Sie versuchen, BluetoothGattDescriptor.ENABLE_INDICATION_VALUE in den Deskriptor zu schreiben, was für den Lese-/Schreibprozess völlig irrelevant ist. Diese Codezeilen werden verwendet, um die Anzeige der Eigenschaft einzuschalten, die eine völlig andere Art der Übertragung ist. – reTs

+0

Das behebt mein Problem, als ich versuchte, alle meine Werte beim Start in der OnServicesDiscovered Callback zu aktualisieren und Merkmal wurde nicht geschrieben, da ich auch in den Deskriptor schrieb. –

0

Danke @reTs und @pooja für Vorschläge. Das Problem war aufgrund dieser beiden Zeilen
mGatt = null
connectBluetooth(mDevice);
in STATE_DISCONNECTED. Ich hatte es herausgefunden, aber ich erinnere mich nicht an den genauen Grund. Für den Fall, dass es hilfreich ist.

Verwandte Themen