2016-05-12 11 views
0

Für eine Anwendung muss ich für ein Android-Gerät sowohl ein Ble Gatt-Peripheriegerät und Server, um eingehende und senden ausgehende Nachrichten zu akzeptieren; Es scheint jedoch, dass ich nicht viele Informationen finden kann, die sich auf die Einrichtung und Wartung des Servers beziehen, außer auf Projekte von anderen in github. Kann mir jemand die richtige Lösung zeigen oder mich zu mehr Informationen bezüglich der Einrichtung von BluetoothGattServer führen.Android mit BluetoothGattServer

Antwort

6

Ich möchte schnell erwähnen, dass die meisten Android-Geräte den BluetoothGattServer nicht unterstützen. Neuere Modelle haben diese Fähigkeit jedoch mehr und mehr.

Zunächst möchten Sie wahrscheinlich Ihren Dienst ankündigen, damit andere Geräte über den Server wissen. Dazu müssen wir die AdvertSettings, die AdvertiseData und die AdvertiseData für ScanResponses erstellen.

AdvertiseSettings settings = new AdvertiseSettings.Builder() 
       .setConnectable(true) 
       .build(); 

AdvertiseData advertiseData = new AdvertiseData.Builder() 
        .setIncludeDeviceName(true) 
        .setIncludeTxPowerLevel(true) 
        .build(); 

AdvertiseData scanResponseData = new AdvertiseData.Builder() 
        .addServiceUuid(new ParcelUuid(your_service_uuid)) 
        .setIncludeTxPowerLevel(true) 
        .build(); 

Danach benötigen Sie einen Rückruf für die Werbestatus zu erstellen:

AdvertiseCallback callback = new AdvertiseCallback() { 
       @Override 
       public void onStartSuccess(AdvertiseSettings settingsInEffect) { 
        Log.d(TAG, "BLE advertisement added successfully"); 
       } 

       @Override 
       public void onStartFailure(int errorCode) { 
        Log.e(TAG, "Failed to add BLE advertisement, reason: " + errorCode); 
       } 
      }; 

Jetzt können Sie Ihren Dienst starten Werbung:

BluetoothLeAdvertiser bluetoothLeAdvertiser = mBluetoothAdapter.getBluetoothLeAdvertiser(); 
bluetoothLeAdvertiser.startAdvertising(settings, advertiseData, scanResponseData, callback); 

Für die BluetoothGattServer müssen wir zuerst erstellen ein BluetoothGattServerCallback:

BluetoothGattServerCallback callback = new BluetoothGattServerCallback() { 
      @Override 
      public void onConnectionStateChange(BluetoothDevice device, int status, int newState) { 
       super.onConnectionStateChange(device, status, newState); 
      } 

      @Override 
      public void onServiceAdded(int status, BluetoothGattService service) { 
       super.onServiceAdded(status, service); 
      } 

      @Override 
      public void onCharacteristicReadRequest(BluetoothDevice device, int requestId, int offset, BluetoothGattCharacteristic characteristic) { 
       super.onCharacteristicReadRequest(device, requestId, offset, characteristic); 
      } 

      @Override 
      public void onCharacteristicWriteRequest(BluetoothDevice device, int requestId, BluetoothGattCharacteristic characteristic, boolean preparedWrite, boolean responseNeeded, int offset, byte[] value) { 
       super.onCharacteristicWriteRequest(device, requestId, characteristic, preparedWrite, responseNeeded, offset, value); 
      } 

      @Override 
      public void onDescriptorWriteRequest(BluetoothDevice device, int requestId, BluetoothGattDescriptor descriptor, boolean preparedWrite, boolean responseNeeded, int offset, byte[] value) { 
       super.onDescriptorWriteRequest(device, requestId, descriptor, preparedWrite, responseNeeded, offset, value); 
      } 

      @Override 
      public void onDescriptorReadRequest(BluetoothDevice device, int requestId, int offset, BluetoothGattDescriptor descriptor) { 
       super.onDescriptorReadRequest(device, requestId, offset, descriptor); 
      } 

      @Override 
      public void onNotificationSent(BluetoothDevice device, int status) { 
       super.onNotificationSent(device, status); 
      } 

      @Override 
      public void onMtuChanged(BluetoothDevice device, int mtu) { 
       super.onMtuChanged(device, mtu); 
      } 

      @Override 
      public void onExecuteWrite(BluetoothDevice device, int requestId, boolean execute) { 
       super.onExecuteWrite(device, requestId, execute); 
      } 
     }; 

Sie müssen nicht alle diese Methoden implementieren, nur diejenigen, an denen Sie interessiert sind. Beispielsweise könnten Sie die Methode onCharacteristicReadRequest (...) implementieren, um Daten an ein Gerät zurückzugeben, das die Eigenschaft auf Ihrem BluetoothGattServer liest.

Danach können Sie einen GattServer öffnen, Ihren Dienst erstellen und den Dienst an den Server hinzufügen:

BluetoothGattServer bluetoothGattServer = mBluetoothManager.openGattServer(Context, callback); 
BluetoothGattService service = new BluetoothGattService(your_service_uuid, BluetoothGattService.SERVICE_TYPE_PRIMARY); 

//add a read characteristic. 
BluetoothGattCharacteristic characteristic = new BluetoothGattCharacteristic(your_characteristic_uuid, BluetoothGattCharacteristic.PROPERTY_READ, BluetoothGattCharacteristic.PERMISSION_READ); 

service.addCharacteristic(characteristic) 

bluetoothGattServer.addService(service); 

Nun haben Sie Ihre BluetoothGattServer mit einem Lese Merkmal, von dem anderen Geräten gelesen werden können. Ich hoffe, diese kurze Zusammenfassung hilft Ihnen, sonst werde ich versuchen, Ihnen zu helfen, die unklaren Dinge zu klären.

+0

Kann ein Server auch ein Gatt-Client sein? Ich habe anscheinend ein Problem, seit ich den Server mit dem Gatt-Client verbunden habe. Ich gehe jedoch davon aus, dass das Problem auftritt, wenn das Telefon versucht, sich mit einem anderen Gerät zu verbinden, mit dem es bereits verbunden ist. Wiederum gibt es keine Möglichkeit, ein ble-Gerät zu identifizieren, da sich die Schnittstellen ändern und die equals-Methode nur auf der Adresse basiert, die sich ändert, und auch in api23 gibt sie die falsche Adresse zurück. – kdgwill

+0

Ja, ein Gerät kann gleichzeitig als Peripheriegerät und Zentralgerät fungieren. Was das Problem angeht, bin ich mir nicht ganz sicher, aber soweit ich weiß, sollte es funktionieren. Beachten Sie, dass der ble Stack von Android sehr instabil ist. – p2pkit

+0

Für die Identifizierung gibt es eine Möglichkeit, ein Gerät zu identifizieren. Im Advertisement-Setup können Sie einer Dienst-UUID zusätzliche Daten hinzufügen, fügen Sie einfach einen Aufruf von addServiceData (...) im Gebäude der ScanResponseData hinzu. Die Größe der ScanResponseData darf jedoch 31 Bytes nicht überschreiten. Ein weiterer Nachteil ist, dass auf der Empfangsseite der serviceData-Schlüssel eine 32-Bit-UUID anstelle von 128Bit ist. – p2pkit