BluetoothGatt — bu nədir, metodları və BLE-də GATT-protokolu Android

Müəllif: IT Sectr Dərc olunub: 2026-07-16 Oxuma vaxtı: 10 dəq

BluetoothGatt — BLE bağlantısı üzərində GATT-klientinin (Generic Attribute Profile) işləməsi üçün API təmin edən Android sinfi. BluetoothGatt uzaq GATT-serverinə (periferik BLE cihazı) qoşulmanı kapsullaşdırır və profilin bütün əməliyyatlarını idarə edir: xidmətlərin kəşfi, xarakteristikaların oxunması və yazılması, bildirişlərə və indikasiyalara abunə olma. BluetoothGatt nümunəsi BluetoothDevice.connectGatt() vasitəsilə BluetoothGattCallback ilə alınır. Android Developers, 2026-ya görə, BluetoothGatt ikitərəfli BLE rabitəsi üçün mərkəzi sinifdir, BLE 4.0-dan BLE 5.4-ə qədər GATT əməliyyatlarını dəstəkləyir.

Əsas məqamlar

  • BluetoothGatt — periferik cihazla BLE bağlantısını idarə edən GATT-klienti üçün Android sinfi
  • connectGatt() — BluetoothGatt yaratmaq üçün BluetoothDevice metodu; kontekst, autoConnect, callback və transport qəbul edir
  • discoverServices() — GATT iyerarxiyasını əldə etmək üçün metod: xidmətlər (BluetoothGattService), xarakteristikalar (BluetoothGattCharacteristic)
  • readCharacteristic/writeCharacteristic — BluetoothGattCallback vasitəsilə asinxron nəticə ilə oxu və yazma metodları
  • setCharacteristicNotification — CCCD deskriptorunun məcburi yazılması ilə BLE bildirişlərinə abunə olma metodu

BluetoothGatt nədir: mahiyyəti və bağlantının yaradılması

BluetoothGatt — Android cihazı (mərkəz) ilə BLE periferiyası (server) arasında GATT bağlantısını təmsil edən proksi-obyektdir. Hər BluetoothGatt nümunəsi bir aktiv BLE bağlantısına uyğun gəlir. Onun vasitəsilə bütün GATT profil əməliyyatları yerinə yetirilir: kəşf, oxu, yazma, bildirişlər. BluetoothGatt birbaşa yaradılmır — BluetoothDevice.connectGatt() metodu tərəfindən qaytarılır.

BluetoothGatt-ın yaradılması dörd parametr tələb edir. Context — tətbiq konteksti (Activity və ya Application). autoConnect — false olarsa, Android dərhal birbaşa qoşulmağa başlayır; true olarsa, Android cihaz aşkar edildikdə avtomatik qoşulur (fon bağlantısı üçün faydalıdır). BluetoothGattCallback — bütün GATT hadisələri üçün məcburi callback. transport — BluetoothDevice.TRANSPORT_LE (BLE) və ya TRANSPORT_BREDR (Classic). BLE cihazlarında həmişə TRANSPORT_LE istifadə edin.

BluetoothGatt həyat dövrü beş vəziyyətdən ibarətdir. DISCONNECTED — ilkin vəziyyət. CONNECTING — connectGatt çağırıldıqdan sonra, təsdiqə qədər. CONNECTED — STATE_CONNECTED ilə onConnectionStateChange-dən sonra. Qoşulduqdan sonra GATT iyerarxiyasını əldə etmək üçün discoverServices() çağırılır. İş bitdikdən sonra sistem resurslarını boşaltmaq üçün disconnect() və close(). close() çağırılmazsa, tətbiq Android BLE bağlantı limitini tükədə bilər (adətən 4–8).

kotlin
// BluetoothGatt bağlantısının yaradılması
import android.bluetooth.*

class GattConnector(private val context: Context) {

    private var bluetoothGatt: BluetoothGatt? = null

    fun connect(device: BluetoothDevice): BluetoothGatt? {
        // Əgər varsa, əvvəlki bağlantını bağla
        close()

        bluetoothGatt = device.connectGatt(
            context,
            false,  // autoConnect = false ( )
            object : BluetoothGattCallback() {
                override fun onConnectionStateChange(
                    gatt: BluetoothGatt, status: Int, newState: Int
                ) {
                    when (newState) {
                        BluetoothProfile.STATE_CONNECTED -> {
                            // 2. Bağlantı quruldu → Kəşf
                            gatt.discoverServices()
                        }
                        BluetoothProfile.STATE_DISCONNECTED -> {
                            // 3. Bağlantı itirildi
                            close()
                        }
                    }
                }

                override fun onServicesDiscovered(
                    gatt: BluetoothGatt, status: Int
                ) {
                    if (status == BluetoothGatt.GATT_SUCCESS) {
                        // 4. GATT iyerarxiyası alındı
                        onGattReady(gatt)
                    }
                }
            },
            BluetoothDevice.TRANSPORT_LE
        )
        return bluetoothGatt
    }

    private fun onGattReady(gatt: BluetoothGatt) {
        // GATT oxu/yazma əməliyyatlarına hazırdır
    }

    fun close() {
        bluetoothGatt?.disconnect()
        bluetoothGatt?.close()
        bluetoothGatt = null
    }
}

GattConnector sinfi BluetoothGatt-ın düzgün yaradılmasını nümayiş etdirir. autoConnect=false parametri — birbaşa qoşulma (skan edilmiş cihazlar üçün). STATE_CONNECTED ilə onConnectionStateChange-də dərhal discoverServices() çağırılır. onServicesDiscovered GATT-ın hazır olduğunu bildirir. close() ardıcıl olaraq disconnect() və close() çağırır — close() olmadan sistem resursları boşalmır, bu da BLE bağlantı sızmasına səbəb olur.

BluetoothGatt vasitəsilə xidmətlərin və xarakteristikaların kəşfi

discoverServices() — qoşulduqdan sonra çağırılan ilk GATT metodu. BLE periferiyasında bütün xidmətlərin asinxron axtarışını başladır. Nəticə onServicesDiscovered() ilə status kodu ilə gəlir: GATT_SUCCESS (0) — uğurlu, 133 — GATT_ERROR, 8 — GATT_CONNECTION_TIMEOUT. Uğurlu kəşfdən sonra BluetoothGatt getServices() vasitəsilə əldə edilə bilən xidmətlər siyahısını doldurur.

Hər BluetoothGattService BluetoothGattCharacteristic siyahısını ehtiva edir. Xarakteristikanın UUID, xassələri (PROPERTY_READ, PROPERTY_WRITE, PROPERTY_NOTIFY) və isteğe bağlı deskriptorları var. Xassələr hansı əməliyyatların icazəli olduğunu müəyyən edir: əgər xarakteristikada PROPERTY_READ yoxdursa, readCharacteristic çağırışı xəta qaytaracaq. Xarakteristikanın deskriptorlarını əldə etmək üçün getDescriptors() istifadə olunur.

kotlin
// Xidmət kəşfi və xarakteristika axtarışı
class GattServiceExplorer {

    // UUID ilə xidməti tap
    fun findService(gatt: BluetoothGatt, uuid: UUID): BluetoothGattService? {
        return gatt.services?.firstOrNull { it.uuid == uuid }
    }

    // Xidmətdə xarakteristikanı tap
    fun findCharacteristic(
        service: BluetoothGattService,
        uuid: UUID
    ): BluetoothGattCharacteristic? {
        return service.characteristics?.firstOrNull { it.uuid == uuid }
    }

    // Bütün dəstəklənən xarakteristika əməliyyatlarını əldə et
    fun getCharacteristicProperties(chars: BluetoothGattCharacteristic): List<String> {
        val props = mutableListOf<String>()
        with(chars.properties) {
            if (and(BluetoothGattCharacteristic.PROPERTY_READ) != 0) props.add("READ")
            if (and(BluetoothGattCharacteristic.PROPERTY_WRITE) != 0) props.add("WRITE")
            if (and(BluetoothGattCharacteristic.PROPERTY_WRITE_NO_RESPONSE) != 0) props.add("WRITE_NO_RESP")
            if (and(BluetoothGattCharacteristic.PROPERTY_NOTIFY) != 0) props.add("NOTIFY")
            if (and(BluetoothGattCharacteristic.PROPERTY_INDICATE) != 0) props.add("INDICATE")
        }
        return props
    }

    // Bütün GATT iyerarxiyasını loga yaz
    fun dumpGattTree(gatt: BluetoothGatt) {
        gatt.services?.forEach { service ->
            print("Service: ${service.uuid}")
            service.characteristics?.forEach { char ->
                print("  Characteristic: ${char.uuid}, properties: ${char.properties}")
                char.descriptors?.forEach { desc ->
                    print("    Descriptor: ${desc.uuid}")
                }
            }
        }
    }
}

GattServiceExplorer sinfi GATT iyerarxiyasında naviqasiya üçün alətlər təqdim edir. findService və findCharacteristic UUID ilə xidmətləri və xarakteristikaları axtarır. getCharacteristicProperties and() vasitəsilə bit maskalarını yoxlayır. dumpGattTree tam iyerarxiyanı loga çıxarır — BLE cihazlarının debug edilməsi zamanı faydalıdır. BluetoothGatt üzərində bütün əməliyyatlar uğurlu onServicesDiscovered-dən sonra yerinə yetirilməlidir, əks halda getServices() boş siyahı qaytaracaq.

BLE xarakteristikalarının oxunması: readCharacteristic və readDescriptor

readCharacteristic() — uzaq BLE cihazından xarakteristikanın dəyərini oxumaq üçün BluetoothGatt-ın asinxron metodu. Nəticə BluetoothGattCallback-in onCharacteristicRead() funksiyasında gəlir. Cihazda 2+ uyğun xarakteristika varsa (az ehtimal, lakin mümkündür), readCharacteristic() hədəf olmayanı oxuya bilər — UUID ilə deyil, BluetoothGattCharacteristic nümunəsində readCharacteristic() çağırmaq daha təhlükəsizdir.

readDescriptor() — xarakteristikanın deskriptorunun dəyərini oxumaq üçün metod. Tipik deskriptor — bildirişlərin aktiv olub-olmadığını müəyyən edən CCCD (Client Characteristic Configuration Descriptor, UUID 0x2902). Nəticə onDescriptorRead() funksiyasında. Praktikada deskriptorların oxunması nadir hallarda tələb olunur — CCCD setCharacteristicNotification() tərəfindən idarə olunur, lakin fərdi deskriptorlar üçün (User Description 0x2901, Presentation Format 0x2904) readDescriptor() metadata əldə etməyin yeganə yoludur.

MTU və böyük məlumatların oxunması — xarakteristikanın dəyəri MTU-dan (BLE 4.0 üçün 23 bayt) böyükdürsə, Android avtomatik olaraq BLE stack vasitəsilə ardıcıl oxu sorğuları ilə məlumatı fragmentləşdirir və yığır. BLE 5.0+ üçün genişləndirilmiş MTU (251 bayta qədər) ilə fragmentasiya tələb olunmur — bir oxu tam məlumatı qaytarır. Oxumadan əvvəl maksimum MTU-nu razılaşdırmaq üçün requestMtu() çağırıla bilər.

kotlin
// BluetoothGatt vasitəsilə xarakteristikanın və deskriptorun oxunması
class GattReader {

    fun readHeartRate(gatt: BluetoothGatt) {
        // Heart Rate xidmət UUID = 0x180D
        val service = gatt.getService(UUID.fromString("0000180D-0000-1000-8000-00805F9B34FB"))
            ?: return
        // Heart Rate ölçmə UUID = 0x2A37
        val characteristic = service.getCharacteristic(
            UUID.fromString("00002A37-0000-1000-8000-00805F9B34FB")
        ) ?: return

        if (hasProperty(characteristic, BluetoothGattCharacteristic.PROPERTY_READ)) {
            gatt.readCharacteristic(characteristic)
        }
    }

    fun readDescriptor(gatt: BluetoothGatt, characteristic: BluetoothGattCharacteristic) {
        // CCCD (0x2902)
        val cccd = characteristic.getDescriptor(
            UUID.fromString("00002902-0000-1000-8000-00805F9B34FB")
        )
        cccd?.let { gatt.readDescriptor(it) }
    }

    // Məlumatı onCharacteristicRead callbackində emal et:
    fun parseHeartRate(value: ByteArray): Int {
        // BLE Heart Rate: baytlar = flaglar, ikinci = bpm
        return if (value.isNotEmpty()) value[1].toInt() and 0xFF else 0
    }

    private fun hasProperty(char: BluetoothGattCharacteristic, prop: Int): Boolean {
        return char.properties and prop != 0
    }
}

GattReader sinfi Heart Rate xarakteristikasının oxunmasını nümayiş etdirir. 0x180D xidməti 0x2A37 (Heart Rate Measurement) xarakteristikasını ehtiva edir — Bluetooth SIG-nin standart BLE profili. Oxumadan əvvəl hasProperty vasitəsilə PROPERTY_READ xassəsi yoxlanılır. parseHeartRate BLE ürək döyüntü formatını təhlil edir: ilk bayt — flaglar (məlumat formatı), ikinci — bpm dəyəri. CCCD deskriptoru (0x2902) bildiriş statusunu yoxlamaq üçün oxunur.

Xarakteristikaların yazılması: writeCharacteristic WriteType ilə

writeCharacteristic() — BLE periferiyasına məlumat yazmaq üçün BluetoothGatt metodu. Android API 33+-da writeCharacteristic() writeCharacteristic(request) ilə əvəz edilmişdir, burada BluetoothGattCharacteristicWriteRequest xarakteristika, bayt massivi və WriteType ehtiva edən sorğu obyektidir. setValue() ilə köhnə writeCharacteristic(characteristic) metodu deprecate edilmişdir. WriteType sorğunun davranışını müəyyən edir: WRITE_TYPE_DEFAULT (xarakteristikanın xassələrindən asılıdır), WRITE_TYPE_NO_RESPONSE (withoutResponse) və WRITE_TYPE_SIGNED (avtorizasiya).

WriteType seçimi sürətə və etibarlılığa təsir edir. WRITE_TYPE_DEFAULT adətən withResponse (əgər xarakteristikada PROPERTY_WRITE varsa) və ya withoutResponse (əgər PROPERTY_WRITE_NO_RESPONSE varsa) uyğun gəlir. Axın məlumatları üçün (OTA yeniləmələr, loglar) WRITE_TYPE_NO_RESPONSE istifadə edin — maksimum ötürmə qabiliyyəti. Çatdırılma zəmanəti olan əmrlər üçün (aktivləşdirmə, konfiqurasiya) — onCharacteristicWrite vasitəsilə təsdiqləmə ilə WRITE_TYPE_DEFAULT.

kotlin
// Android API 33+-da BLE xarakteristika yazması
class GattWriter {

    // Cavabla yazma (withResponse)
    fun writeWithResponse(gatt: BluetoothGatt, characteristic: BluetoothGattCharacteristic, data: ByteArray) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
            // API 33+: writeCharacteristic
            val request = BluetoothGattCharacteristicWriteRequest(
                characteristic,
                data,
                BluetoothGattCharacteristicWriteRequest.WRITE_TYPE_DEFAULT,
                @android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
            )
            gatt.writeCharacteristic(request)
        } else {
            // API < 33:   (deprecated)
            characteristic.setValue(data)
            gatt.writeCharacteristic(characteristic)
        }
    }

    // Cavabsız yazma (max sürət)
    fun writeWithoutResponse(gatt: BluetoothGatt, characteristic: BluetoothGattCharacteristic, data: ByteArray) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
            val request = BluetoothGattCharacteristicWriteRequest(
                characteristic,
                data,
                BluetoothGattCharacteristicWriteRequest.WRITE_TYPE_NO_RESPONSE,
                @android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
            )
            gatt.writeCharacteristic(request)
        } else {
            characteristic.setValue(data)
            characteristic.writeType = BluetoothGattCharacteristic.WRITE_TYPE_NO_RESPONSE
            gatt.writeCharacteristic(characteristic)
        }
    }

    // onCharacteristicWrite callbacki (API 33+)
    private val writeCallback = object : BluetoothGattCallback() {
        override fun onCharacteristicWrite(
            gatt: BluetoothGatt,
            characteristic: BluetoothGattCharacteristic,
            value: ByteArray,
            status: Int,
            callbackType: Int
        ) {
            if (status == BluetoothGatt.GATT_SUCCESS) {
                print("Write success: ${value.size} bytes")
            }
        }
    }
}

GattWriter sinfi müxtəlif API səviyyələri üçün hər iki WriteType-ı dəstəkləyir. writeWithResponse WRITE_TYPE_DEFAULT istifadə edir — BLE cihazı onCharacteristicWrite vasitəsilə yazmanı təsdiqləyir. writeWithoutResponse WRITE_TYPE_NO_RESPONSE istifadə edir — məlumatlar təsdiqləmədən göndərilir, maksimum ötürmə qabiliyyəti. API 33+-da BluetoothGattCharacteristicWriteRequest ilə yeni writeCharacteristic(request) istifadə olunur. API < 33-də — köhnə setValue() + writeCharacteristic().

Bildirişlərə abunə: setCharacteristicNotification və CCCD

setCharacteristicNotification() — periferiyada xarakteristikanın dəyişməsi barədə bildirişlərə abunə olmaq üçün BluetoothGatt metodu. Abunə aktivləşdirildikdən sonra BLE cihazı onCharacteristicChanged() vasitəsilə yeni dəyərlər göndərir. Lakin setCharacteristicNotification() yalnız Android-in lokal bildirişini aktivləşdirir — BLE cihazının özündə bildirişləri aktivləşdirmək üçün CCCD deskriptoruna (0x2902) 0x0100 dəyərini də yazmaq lazımdır.

CCCD (Client Characteristic Configuration Descriptor) — BLE periferiyasından bildirişlərin göndərilməsini idarə edən deskriptor. Dəyər 0x0000 — bildirişlər söndürülüb, 0x0100 — bildirişlər aktivdir (notifications), 0x0200 — indikasiyalar aktivdir (indications). CCCD-yə yazma setCharacteristicNotification() çağırıldıqdan sonra BluetoothGatt-da writeDescriptor() vasitəsilə yerinə yetirilir. Android CCCD-ni avtomatik yazmır — bu məsuliyyət tərtibatçının üzərindədir.

kotlin
// Düzgün BLE bildiriş abunəsi
class GattNotificationManager {

    // 1. Bildirişləri aktivləşdir
    fun enableNotification(gatt: BluetoothGatt, characteristic: BluetoothGattCharacteristic) {
        // Addım 1: lokal Android abunəsi
        val success = gatt.setCharacteristicNotification(characteristic, true)
        if (!success) {
            print("Abunə olmaq mümkün olmadı")
            return
        }

        // Addım 2: BLE cihazında CCCD (0x2902) yaz
        val cccdDescriptor = characteristic.getDescriptor(
            UUID.fromString("00002902-0000-1000-8000-00805F9B34FB")
        ) ?: return

        // 0x0100 = bildiriş, 0x0200 = indikasiya
        val cccdValue = if (characteristic.properties
            and BluetoothGattCharacteristic.PROPERTY_NOTIFY != 0) {
            BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE  // [0x01, 0x00]
        } else {
            BluetoothGattDescriptor.ENABLE_INDICATION_VALUE     // [0x02, 0x00]
        }

        cccdDescriptor.setValue(cccdValue)
        gatt.writeDescriptor(cccdDescriptor)
    }

    // 2. Xarakteristika kəşfi
    fun disableNotification(gatt: BluetoothGatt, characteristic: BluetoothGattCharacteristic) {
        gatt.setCharacteristicNotification(characteristic, false)
        val cccdDescriptor = characteristic.getDescriptor(
            UUID.fromString("00002902-0000-1000-8000-00805F9B34FB")
        ) ?: return
        cccdDescriptor.setValue(BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE)
        gatt.writeDescriptor(cccdDescriptor)
    }

    // 3. Bildiriş callbacki
    private val notificationCallback = object : BluetoothGattCallback() {
        override fun onCharacteristicChanged(
            gatt: BluetoothGatt,
            characteristic: BluetoothGattCharacteristic,
            value: ByteArray,
            callbackType: Int
        ) {
            // BLE periferiyasından yeni dəyər
            print("Notification: ${value.size} bytes")
        }
    }
}

GattNotificationManager sinfi BLE bildirişlərinə abunə üçün düzgün iki addımlı protokolu tətbiq edir. enableNotification əvvəlcə Android-də setCharacteristicNotification(true) çağırır, sonra writeDescriptor vasitəsilə CCCD deskriptoruna 0x0100 yazır. disableNotification əks əməliyyatları yerinə yetirir. CCCD yazılmazsa, BLE cihazı bildiriş göndərmir — bu Android-də BLE tərtibatçılarının ən çox yayılmış səhvidir.

Kotlin-də BluetoothGattCallback ilə GATT-klienti nümunəsi

Tam nümunə — BluetoothGatt yaradılması, kəşf, oxu və bildirişlərə abunəni asinxron emal üçün korutinlərdən istifadə edərək vahid menecerdə birləşdirən Kotlin GATT-klienti.

kotlin
// Kotlin-də korutinlərlə tam GATT klienti
class GattClient(context: Context) {

    private val context = context.applicationContext
    private var gatt: BluetoothGatt? = null

    // Korutinlə qoşul
    suspend fun connect(device: BluetoothDevice): Boolean =
        suspendCoroutine { continuation ->
            gatt = device.connectGatt(
                context, false,
                object : BluetoothGattCallback() {
                    override fun onConnectionStateChange(
                        gatt: BluetoothGatt, status: Int, newState: Int
                    ) {
                        if (newState == BluetoothProfile.STATE_CONNECTED) {
                            gatt.discoverServices()
                        } else {
                            continuation.resume(false)
                        }
                    }

                    override fun onServicesDiscovered(gatt: BluetoothGatt, status: Int) {
                        continuation.resume(status == BluetoothGatt.GATT_SUCCESS)
                    }
                },
                BluetoothDevice.TRANSPORT_LE
            )
        }

    // Korutin vasitəsilə xarakteristikanı oxu
    suspend fun readCharacteristicValue(char: BluetoothGattCharacteristic): ByteArray? =
        suspendCoroutine { continuation ->
            gatt?.let { gatt ->
                // Callback identifikasiyası üçün xarakteristika teqini saxla
                gatt.setCharacteristic(char, null)  // API üçün < 33
                gatt.readCharacteristic(char)
            }
        }

    // Bağlantını bağla
    fun release() {
        gatt?.disconnect()
        gatt?.close()
        gatt = null
    }
}

GattClient GATT-klienti callback-based BluetoothGatt API-ni ardıcıl çağırışlara çevirmək üçün korutinlərdən (suspendCoroutine) istifadə edir. connect() onServicesDiscovered-i gözləyir, bundan sonra GATT iyerarxiyası əlçatan olur. readCharacteristicValue() onCharacteristicRead-i gözləyir. Bu yanaşma callback-lərin iç-içə yerləşməsini aradan qaldırır və BLE kodunu xətti edir. release() resursların boşaldılmasını təmin edir — Activity-nin onDestroy və ya ViewModel.onCleared-də məcburi çağırış.

Tez-tez verilən suallar

Android-də BluetoothGatt nədir?

BluetoothGatt — periferik cihazla BLE bağlantısını idarə edən Android GATT-klienti sinfi. BluetoothDevice.connectGatt() vasitəsilə yaradılır, discoverServices(), readCharacteristic(), writeCharacteristic(), setCharacteristicNotification() metodlarını təqdim edir. Bütün əməliyyatların nəticələri asinxron olaraq BluetoothGattCallback vasitəsilə gəlir. BluetoothGatt olmadan Android-də ikitərəfli BLE rabitəsi mümkün deyil.

Niyə onServicesDiscovered 133 statusunu qaytarır?

133 statusu (GATT_ERROR) Android BLE stackinin daxili xətası deməkdir. Səbəblər: kəşf zamanı cihazın ayrılması, MTU-nun minimaldan (23 bayt) kiçik olması və ya BLE stackinin həddən artıq yüklənməsi. Həll yolu: discoverServices()-i 500 ms gecikmə ilə təkrarlayın, cihazın RSSI-sini yoxlayın və periferiyanın cari vəziyyətdə GATT kəşfini dəstəklədiyinə əmin olun.

Xarakteristikanı təsdiqləmə ilə necə düzgün yazmaq olar?

Təsdiqləmə ilə yazmaq üçün writeCharacteristic() WRITE_TYPE_DEFAULT ilə çağırın (API 33+: BluetoothGattCharacteristicWriteRequest). Uğur olduqda BLE cihazı təsdiq göndərir və Android onCharacteristicWrite-i GATT_SUCCESS ilə çağırır. Cihaz 30 saniyə ərzində cavab verməzsə (stack timeout), callback xəta statusu qaytarır. Watchdog üçün postDelayed ilə Handler istifadə edin.

Android 33+-da BLE ilə necə işləmək olar?

Android 13+-da (API 33) BluetoothGatt metodları dəyişdirilib: writeCharacteristic() indi BluetoothGattCharacteristicWriteRequest qəbul edir, readCharacteristic() — BluetoothGattCharacteristicReadRequest. Köhnə setValue()/writeCharacteristic() deprecate edilib. BluetoothGattCallback də dəyişdirilib: onCharacteristicRead(), onCharacteristicWrite(), onCharacteristicChanged() ByteArray value və callbackType alır. Budaqlanma üçün Build.VERSION.SDK_INT istifadə edin.

Android neçə BLE bağlantısını dəstəkləyir?

Android 4–8 eyni vaxtda BLE-GATT bağlantısını dəstəkləyir (istehsalçıdan və Android versiyasından asılıdır). Pixel/Google: 7-yə qədər, Samsung: 5-ə qədər, Xiaomi: 4-ə qədər. Limit aşıldıqda connectGatt null qaytarır və ya onConnectionStateChange xəta ilə çağırılır. Çox sayda cihazla işləmək üçün dövri qoşulma və ya Bluetooth Mesh istifadə edin.

Nəticə

  • BluetoothGatt — BLE bağlantısı üçün Android GATT-klienti, BluetoothDevice.connectGatt() ilə BluetoothGattCallback ilə yaradılır
  • discoverServices() — BLE cihazının xidmətlərini, xarakteristikalarını və deskriptorlarını əldə etmək üçün qoşulduqdan sonra məcburi addım
  • Oxu — readCharacteristic() onCharacteristicRead-də asinxron nəticə ilə; böyük məlumatlar üçün MTU razılaşdırılması tələb olunur
  • Yazma — writeCharacteristic() WriteType ilə: DEFAULT (withResponse) və ya NO_RESPONSE (təsdiqləməsiz)
  • Bildirişlər — iki addımlı aktivləşdirmə: setCharacteristicNotification() + CCCD (0x2902) 0x0100 dəyəri ilə yazma
  • API 33+ — sorğu obyektləri ilə yeni writeCharacteristic(request) və readCharacteristic(request) metodları
  • Resursların boşaldılması — BLE bağlantı sızmalarının qarşısını almaq üçün disconnect() və close()-un məcburi çağırışı

Açar təslim mobil tətbiq hazırlayacağıq

IT Sectr 2017-ci ildən startaplar və bizneslər üçün iOS və Android tətbiqləri yaradır. Sizə məsləhət verəcəyik və ən yaxşı həlli təklif edəcəyik.

Layihəni müzakirə et

Həm də oxuyun