Suche…


Einführung

Diese Dokumentation ist als Erweiterung der Originaldokumentation gedacht und konzentriert sich auf die neueste Bluetooth LE-API, die in Android 5.0 (API 21) eingeführt wurde. Es werden sowohl die zentralen als auch die peripheren Rollen behandelt sowie der Start des Scan- und Werbevorgangs.

BLE-Geräte suchen

Die folgenden Berechtigungen sind erforderlich, um die Bluetooth-APIs zu verwenden:

android.permission.BLUETOOTH
android.permission.BLUETOOTH_ADMIN

Wenn Sie auf Geräte mit Android 6.0 ( API Level 23 ) oder höher zielen und Scan- / Werbevorgänge durchführen möchten, benötigen Sie eine Standortberechtigung:

android.permission.ACCESS_FINE_LOCATION

oder

android.permission.ACCESS_COARSE_LOCATION

Hinweis.- Bei Geräten mit Android 6.0 (API Level 23) oder höher müssen auch die Ortungsdienste aktiviert sein.

Zum Starten von Scan- / Werbevorgängen ist ein BluetoothAdapter-Objekt erforderlich:

BluetoothManager bluetoothManager = (BluetoothManager) context.getSystemService(Context.BLUETOOTH_SERVICE);
bluetoothAdapter = bluetoothManager.getAdapter();

Die startScan (ScanCallback callback) Methode startScan (ScanCallback callback) der BluetoothLeScanner-Klasse ist die einfachste Methode, um einen Scanvorgang zu starten. Ein ScanCallback Objekt ist erforderlich, um Ergebnisse zu erhalten:

bluetoothAdapter.getBluetoothLeScanner().startScan(new ScanCallback() {
     @Override
     public void onScanResult(int callbackType, ScanResult result) {
     super.onScanResult(callbackType, result);
     Log.i(TAG, "Remote device name: " + result.getDevice().getName());
       }
    });

Verbindung zu einem GATT-Server

Wenn Sie ein gewünschtes BluetoothDevice-Objekt erkannt haben, können Sie eine Verbindung mit ihm herstellen, indem Sie die Methode connectGatt() verwenden, die als Parameter ein Context-Objekt verwendet. Ein boolescher connectGatt() , der angibt, ob automatisch eine Verbindung zum BLE-Gerät hergestellt werden soll, und eine BluetoothGattCallback-Referenz, bei der Verbindungsereignisse und Clientvorgänge ausgeführt werden Ergebnisse werden geliefert:

 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        device.connectGatt(context, false, bluetoothGattCallback, BluetoothDevice.TRANSPORT_AUTO);
    } else {
        device.connectGatt(context, false, bluetoothGattCallback);
    }

onConnectionStateChange in BluetoothGattCallback, um Verbindungsereignisse und Verbindungsereignisse zu empfangen:

    BluetoothGattCallback bluetoothGattCallback =
        new BluetoothGattCallback() {
    @Override
    public void onConnectionStateChange(BluetoothGatt gatt, int status,
            int newState) {
        if (newState == BluetoothProfile.STATE_CONNECTED) {
            Log.i(TAG, "Connected to GATT server.");

        } else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
            
            Log.i(TAG, "Disconnected from GATT server.");
        }
    }
   };

Schreiben und Lesen aus Merkmalen

Sobald Sie mit einem Gatt-Server verbunden sind, werden Sie mit ihm interagieren, indem Sie von den Eigenschaften des Servers aus schreiben und lesen. Dazu müssen Sie zunächst herausfinden, welche Dienste auf diesem Server verfügbar sind und welche Merkmale in den einzelnen Diensten verfügbar sind:

 @Override
 public void onConnectionStateChange(BluetoothGatt gatt, int status,
        int newState) {
    if (newState == BluetoothProfile.STATE_CONNECTED) {
        Log.i(TAG, "Connected to GATT server.");
        gatt.discoverServices();

    }
. . .

 @Override
    public void onServicesDiscovered(BluetoothGatt gatt, int status) {
        if (status == BluetoothGatt.GATT_SUCCESS) {
             List<BluetoothGattService> services = gatt.getServices();
                for (BluetoothGattService service : services) {
                    List<BluetoothGattCharacteristic> characteristics = service.getCharacteristics();
                    for (BluetoothGattCharacteristic characteristic : characteristics) { 
                        ///Once you have a characteristic object, you can perform read/write
                        //operations with it         
                    }
                 }
              }
            }

Ein grundlegender Schreibvorgang lautet wie folgt:

characteristic.setValue(newValue);
characteristic.setWriteType(BluetoothGattCharacteristic.WRITE_TYPE_DEFAULT);
gatt.writeCharacteristic(characteristic);

Wenn der Schreibvorgang abgeschlossen ist, wird die onCharacteristicWrite Methode Ihres BluetoothGattCallback aufgerufen:

    @Override
    public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
        super.onCharacteristicWrite(gatt, characteristic, status);
        Log.d(TAG, "Characteristic " + characteristic.getUuid() + " written);
    }

Ein grundlegender Schreibvorgang lautet wie folgt:

gatt.readCharacteristic(characteristic);

Wenn der Schreibvorgang abgeschlossen ist, wird die onCharacteristicRead Methode Ihres BluetoothGattCallback aufgerufen:

@Override
public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
  super.onCharacteristicRead(gatt, characteristic, status);
  byte[] value = characteristic.getValue();
  }

Abonnieren von Benachrichtigungen vom Gatt-Server

Sie können anfordern, vom Gatt-Server benachrichtigt zu werden, wenn der Wert eines Merkmals geändert wurde:

gatt.setCharacteristicNotification(characteristic, true);
BluetoothGattDescriptor descriptor = characteristic.getDescriptor(
    UUID.fromString("00002902-0000-1000-8000-00805f9b34fb");
descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
mBluetoothGatt.writeDescriptor(descriptor);

Alle Benachrichtigungen vom Server werden in der onCharacteristicChanged Methode Ihres BluetoothGattCallbacks empfangen:

    @Override
    public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
        super.onCharacteristicChanged(gatt, characteristic);
        byte[] newValue = characteristic.getValue();
}

Werbung für ein BLE-Gerät

Sie können Bluetooth LE Advertising verwenden, um Datenpakete an alle in der Nähe befindlichen Geräte zu senden, ohne zuerst eine Verbindung herstellen zu müssen. Beachten Sie, dass die Ankündigungsdaten auf 31 Bytes begrenzt sind. Werbung für Ihr Gerät ist auch der erste Schritt, um anderen Benutzern die Verbindung zu Ihnen zu ermöglichen.

Da nicht alle Geräte Bluetooth LE Advertising unterstützen, müssen Sie zunächst prüfen, ob Ihr Gerät über alle erforderlichen Voraussetzungen verfügt, um dies zu unterstützen. Anschließend können Sie ein BluetoothLeAdvertiser Objekt initialisieren und damit den Werbevorgang starten:

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && bluetoothAdapter.isMultipleAdvertisementSupported())
        {
            BluetoothLeAdvertiser advertiser = bluetoothAdapter.getBluetoothLeAdvertiser();

            AdvertiseData.Builder dataBuilder = new AdvertiseData.Builder();
           //Define a service UUID according to your needs                
           dataBuilder.addServiceUuid(SERVICE_UUID);
            dataBuilder.setIncludeDeviceName(true);


             AdvertiseSettings.Builder settingsBuilder = new AdvertiseSettings.Builder();
             settingsBuilder.setAdvertiseMode(AdvertiseSettings.ADVERTISE_MODE_LOW_POWER);
             settingsBuilder.setTimeout(0);

             //Use the connectable flag if you intend on opening a Gatt Server
             //to allow remote connections to your device.
             settingsBuilder.setConnectable(true);

            AdvertiseCallback advertiseCallback=new AdvertiseCallback() {
            @Override
            public void onStartSuccess(AdvertiseSettings settingsInEffect) {
                super.onStartSuccess(settingsInEffect);
                Log.i(TAG, "onStartSuccess: ");
            }

            @Override
            public void onStartFailure(int errorCode) {
                super.onStartFailure(errorCode);
                Log.e(TAG, "onStartFailure: "+errorCode );
            }
          };
advertising.startAdvertising(settingsBuilder.build(),dataBuilder.build(),advertiseCallback);
        }

Verwendung eines Gatt-Servers

Damit Ihr Gerät als Peripheriegerät fungieren kann, müssen Sie zuerst einen BluetoothGattServer öffnen und mit mindestens einem BluetoothGattService und einer BluetoothGattCharacteristic .

BluetoothGattServer server=bluetoothManager.openGattServer(context, bluetoothGattServerCallback);

BluetoothGattService service = new BluetoothGattService(SERVICE_UUID, BluetoothGattService.SERVICE_TYPE_PRIMARY);

Dies ist ein Beispiel für eine BluetoothGattCharacteristic mit vollständigen Schreib-, Lese- und Benachrichtigungsberechtigungen. Je nach Ihren Anforderungen möchten Sie möglicherweise die Berechtigungen, die Sie dieses Merkmal gewähren, genau einstellen:

BluetoothGattCharacteristic characteristic = new BluetoothGattCharacteristic(CHARACTERISTIC_UUID,
                    BluetoothGattCharacteristic.PROPERTY_READ | BluetoothGattCharacteristic.PROPERTY_WRITE |
                            BluetoothGattCharacteristic.PROPERTY_NOTIFY,
                    BluetoothGattCharacteristic.PERMISSION_READ | BluetoothGattCharacteristic.PERMISSION_WRITE);

characteristic.addDescriptor(new BluetoothGattDescriptor(UUID.fromString("00002902-0000-1000-8000-00805f9b34fb"), BluetoothGattCharacteristic.PERMISSION_WRITE));

service.addCharacteristic(characteristic);

server.addService(service);

Der BluetoothGattServerCallback ist für den Empfang aller Ereignisse im Zusammenhang mit Ihrem BluetoothGattServer :

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

                @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 onDescriptorReadRequest(BluetoothDevice device, int requestId, int offset, BluetoothGattDescriptor descriptor) {
                    super.onDescriptorReadRequest(device, requestId, offset, descriptor);
                }

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

Wenn Sie eine Anforderung zum Schreiben / Lesen eines Merkmals oder eines Deskriptors erhalten, müssen Sie eine Antwort senden, damit die Anforderung erfolgreich abgeschlossen werden kann:

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


Modified text is an extract of the original Stack Overflow Documentation
Lizenziert unter CC BY-SA 3.0
Nicht angeschlossen an Stack Overflow