Sök…


Introduktion

Denna dokumentation är tänkt som en förbättring jämfört med den ursprungliga dokumentationen och den kommer att fokusera på den senaste Bluetooth LE API introducerad i Android 5.0 (API 21). Både centrala och perifera roller kommer att täckas såväl som hur man börjar skanna och annonsera.

Hitta BLE-enheter

Följande behörigheter krävs för att använda Bluetooth-API: er:

android.permission.BLUETOOTH
android.permission.BLUETOOTH_ADMIN

Om du inriktar dig på enheter med Android 6.0 ( API-nivå 23 ) eller högre och vill utföra skannings- / reklamoperationer kräver du en platstillstånd:

android.permission.ACCESS_FINE_LOCATION

eller

android.permission.ACCESS_COARSE_LOCATION

Obs.- Enheter med Android 6.0 (API-nivå 23) eller högre måste också ha Location Services aktiverade.

Ett BluetoothAdapter-objekt krävs för att starta skannings- / reklamoperationer:

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

startScan (ScanCallback callback) i klassen BluetoothLeScanner är det mest grundläggande sättet att starta en skanningsoperation. Ett ScanCallback objekt krävs för att få resultat:

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

Ansluter till en GATT-server

När du har upptäckt ett önskat BluetoothDevice-objekt kan du ansluta till det genom att använda dess connectGatt() -metod som tar som parametrar ett Context-objekt, ett boolean som anger om du automatiskt ska ansluta till BLE-enheten och en BluetoothGattCallback-referens där anslutningshändelser och klientoperationer resultaten kommer att levereras:

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

onConnectionStateChange i BluetoothGattCallback för att ta emot anslutningar och avkopplingshändelser:

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

Skriva och läsa från egenskaper

När du är ansluten till en Gatt-server kommer du att interagera med den genom att skriva och läsa från serverns egenskaper. För att göra detta måste du först ta reda på vilka tjänster som finns tillgängliga på denna server och vilka egenskaper som är tillgängliga i varje tjänst:

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

En grundläggande skrivoperation går så här:

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

När skrivprocessen är klar kommer onCharacteristicWrite metoden för din BluetoothGattCallback att kallas:

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

En grundläggande skrivoperation går så här:

gatt.readCharacteristic(characteristic);

När skrivprocessen är klar kommer onCharacteristicRead metoden för din BluetoothGattCallback att kallas:

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

Prenumerera på aviseringar från Gatt-servern

Du kan begära att bli meddelad från Gatt-servern när värdet på en karakteristik har ändrats:

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

Alla aviseringar från servern kommer att tas emot i metoden onCharacteristicChanged på din BluetoothGattCallback:

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

Annonsera en BLE-enhet

Du kan använda Bluetooth LE Advertising för att sända datapaket till alla enheter i närheten utan att behöva upprätta en anslutning först. Tänk på att det finns en strikt gräns på 31 byte av annonsdata. Reklam för din enhet är också det första steget mot att låta andra användare ansluta till dig.

Eftersom inte alla enheter stöder Bluetooth LE Advertising är det första steget att kontrollera att din enhet har alla nödvändiga krav för att stödja den. Efteråt kan du initiera ett BluetoothLeAdvertiser objekt och med det kan du starta annonsering:

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

Använda en Gatt-server

För att din enhet ska fungera som en kringutrustning måste du först öppna en BluetoothGattServer och fylla den med minst en BluetoothGattService och en BluetoothGattCharacteristic :

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

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

Detta är ett exempel på en BluetoothGattCharacteristic med fullständig skrivning, läsning och anmälan behörigheter. Enligt dina behov kanske du vill finjustera behörigheterna som du ger denna egenskap:

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

BluetoothGattServerCallback ansvarar för att ta emot alla händelser relaterade till din 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);
                }

När du får en begäran om att skriva / läsa till en egenskap eller deskriptor måste du skicka ett svar på det för att begäran ska kunna slutföras:

@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
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow