BluetoothGatt — ما هو، طرقه وبروتوكول GATT BLE في Android

المؤلف: IT Sectr نُشر: 2026-07-16 وقت القراءة: 10 دق

BluetoothGatt — فئة Android توفر API لعمل عميل GATT (Generic Attribute Profile) عبر اتصال BLE. يغلف BluetoothGatt الاتصال بخادم GATT بعيد (جهاز BLE طرفي) ويدير جميع عمليات الملف الشخصي: اكتشاف الخدمات، قراءة وكتابة الخصائص، الاشتراك في الإشعارات والتأشيرات. يتم الحصول على مثيل BluetoothGatt عبر BluetoothDevice.connectGatt() مع BluetoothGattCallback. وفقًا لـ Android Developers, 2026، BluetoothGatt هي الفئة المركزية للاتصال الثنائي BLE، وتدعم عمليات GATT من BLE 4.0 إلى BLE 5.4.

أهم النقاط

  • BluetoothGatt — فئة Android لعميل GATT تدير اتصال BLE مع جهاز طرفي
  • connectGatt() — طريقة BluetoothDevice لإنشاء BluetoothGatt؛ تقبل السياق، autoConnect، callback والنقل
  • discoverServices() — طريقة للحصول على التسلسل الهرمي GATT: الخدمات (BluetoothGattService)، الخصائص (BluetoothGattCharacteristic)
  • readCharacteristic/writeCharacteristic — طرق القراءة والكتابة بنتائج غير متزامنة عبر BluetoothGattCallback
  • setCharacteristicNotification — طريقة للاشتراك في إشعارات BLE مع كتابة إلزامية لواصف CCCD

ما هو BluetoothGatt: الجوهر وإنشاء الاتصال

BluetoothGatt — كائن وكيل يمثل اتصال GATT بين جهاز Android (مركزي) وجهاز BLE طرفي (خادم). كل مثيل BluetoothGatt يتوافق مع اتصال BLE نشط واحد. يتم من خلاله تنفيذ جميع عمليات ملف GATT: الاكتشاف، القراءة، الكتابة، الإشعارات. لا يتم إنشاء BluetoothGatt مباشرة — بل يتم إرجاعه بواسطة طريقة BluetoothDevice.connectGatt().

يتطلب إنشاء BluetoothGatt أربع معاملات. Context — سياق التطبيق (Activity أو Application). autoConnect — إذا كان خطأ، يبدأ Android فورًا اتصالًا مباشرًا؛ إذا كان صحيحًا، يتصل Android تلقائيًا عند اكتشاف الجهاز (مفيد للاتصال في الخلفية). BluetoothGattCallback — رد اتصال إلزامي لجميع أحداث GATT. transport — BluetoothDevice.TRANSPORT_LE (BLE) أو TRANSPORT_BREDR (Classic). على أجهزة BLE، استخدم دائمًا TRANSPORT_LE.

دورة حياة BluetoothGatt تتكون من خمس حالات. DISCONNECTED — الحالة الأولية. CONNECTING — بعد استدعاء connectGatt، قبل التأكيد. CONNECTED — بعد onConnectionStateChange مع STATE_CONNECTED. بعد الاتصال، يتم استدعاء discoverServices() للحصول على التسلسل الهرمي GATT. بعد الانتهاء من العمل — disconnect() و close() لتحرير موارد النظام. بدون استدعاء close()، قد يستنفد التطبيق حد اتصالات BLE في Android (عادة 4–8).

kotlin
// إنشاء اتصال BluetoothGatt
import android.bluetooth.*

class GattConnector(private val context: Context) {

    private var bluetoothGatt: BluetoothGatt? = null

    fun connect(device: BluetoothDevice): BluetoothGatt? {
        // إغلاق الاتصال السابق إذا وجد
        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. تم إنشاء الاتصال ← اكتشاف
                            gatt.discoverServices()
                        }
                        BluetoothProfile.STATE_DISCONNECTED -> {
                            // 3. فقدان الاتصال
                            close()
                        }
                    }
                }

                override fun onServicesDiscovered(
                    gatt: BluetoothGatt, status: Int
                ) {
                    if (status == BluetoothGatt.GATT_SUCCESS) {
                        // 4. تم استلام التسلسل الهرمي GATT
                        onGattReady(gatt)
                    }
                }
            },
            BluetoothDevice.TRANSPORT_LE
        )
        return bluetoothGatt
    }

    private fun onGattReady(gatt: BluetoothGatt) {
        // GATT جاهز لعمليات القراءة/الكتابة
    }

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

توضح فئة GattConnector الإنشاء الصحيح لـ BluetoothGatt. المعامل autoConnect=false يعني اتصالًا مباشرًا (للأجهزة الممسوحة ضوئيًا). عند onConnectionStateChange مع STATE_CONNECTED، يتم استدعاء discoverServices() فورًا. تشير onServicesDiscovered إلى أن GATT جاهز. تستدعي close() بشكل تسلسلي disconnect() و close() — بدون close() لا يتم تحرير موارد النظام، مما يؤدي إلى تسرب اتصالات BLE.

اكتشاف الخدمات والخصائص عبر BluetoothGatt

discoverServices() — أول طريقة GATT يتم استدعاؤها بعد الاتصال. تبدأ بحثًا غير متزامن عن جميع الخدمات على جهاز BLE الطرفي. تصل النتيجة في onServicesDiscovered() مع رمز الحالة: GATT_SUCCESS (0) — نجاح، 133 — GATT_ERROR، 8 — GATT_CONNECTION_TIMEOUT. بعد الاكتشاف الناجح، يملأ BluetoothGatt قائمة الخدمات المتاحة عبر getServices().

كل BluetoothGattService يحتوي على قائمة BluetoothGattCharacteristic. الخاصية لها UUID، خصائص (PROPERTY_READ، PROPERTY_WRITE، PROPERTY_NOTIFY) وواصفات اختيارية. تحدد الخصائص العمليات المسموح بها: إذا لم يكن للخاصية PROPERTY_READ، فإن استدعاء readCharacteristic سيعيد خطأ. استخدم getDescriptors() للحصول على واصفات الخاصية.

kotlin
// اكتشاف الخدمات والبحث عن الخصائص
class GattServiceExplorer {

    // البحث عن خدمة بواسطة UUID
    fun findService(gatt: BluetoothGatt, uuid: UUID): BluetoothGattService? {
        return gatt.services?.firstOrNull { it.uuid == uuid }
    }

    // البحث عن خاصية في الخدمة
    fun findCharacteristic(
        service: BluetoothGattService,
        uuid: UUID
    ): BluetoothGattCharacteristic? {
        return service.characteristics?.firstOrNull { it.uuid == uuid }
    }

    // الحصول على جميع عمليات الخاصية المدعومة
    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("كتابة")
            if (and(BluetoothGattCharacteristic.PROPERTY_WRITE_NO_RESPONSE) != 0) props.add("كتابة_بدون_رد")
            if (and(BluetoothGattCharacteristic.PROPERTY_NOTIFY) != 0) props.add("NOTIFY")
            if (and(BluetoothGattCharacteristic.PROPERTY_INDICATE) != 0) props.add("INDICATE")
        }
        return props
    }

    // تسجيل التسلسل الهرمي GATT بالكامل
    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 أدوات للتنقل في التسلسل الهرمي GATT. تبحث findService و findCharacteristic عن الخدمات والخصائص بواسطة UUID. تتحقق getCharacteristicProperties من أقنعة البت للخصائص عبر and(). تطبع dumpGattTree التسلسل الهرمي الكامل في السجل — مفيدة عند تصحيح أخطاء أجهزة BLE. يجب تنفيذ جميع العمليات على BluetoothGatt بعد onServicesDiscovered ناجح، وإلا ستعيد getServices() قائمة فارغة.

قراءة خصائص BLE: readCharacteristic و readDescriptor

readCharacteristic() — طريقة غير متزامنة من BluetoothGatt لقراءة قيمة خاصية من جهاز BLE بعيد. تصل النتيجة في onCharacteristicRead() من BluetoothGattCallback. إذا كان الجهاز يحتوي على 2+ خصائص متطابقة (غير محتمل لكن ممكن)، قد تقرأ readCharacteristic() خاصية غير مستهدفة — من الأكثر أمانًا استدعاء readCharacteristic() على مثيل BluetoothGattCharacteristic بدلاً من UUID.

readDescriptor() — طريقة لقراءة قيمة واصف الخاصية. الواصف النموذجي هو CCCD (Client Characteristic Configuration Descriptor، UUID 0x2902)، الذي يحدد ما إذا كانت الإشعارات مفعلة. النتيجة في onDescriptorRead(). نادرًا ما تكون قراءة الواصفات ضرورية عمليًا — تتم إدارة CCCD بواسطة setCharacteristicNotification()، لكن للواصفات المخصصة (User Description 0x2901، Presentation Format 0x2904) readDescriptor() هي الطريقة الوحيدة للحصول على البيانات الوصفية.

MTU وقراءة البيانات الكبيرة — إذا تجاوزت قيمة الخاصية MTU (23 بايت لـ BLE 4.0)، يقوم Android تلقائيًا بتجزئة وإعادة تجميع البيانات عبر سلسلة من طلبات القراءة عبر مكدس BLE. بالنسبة لـ BLE 5.0+ مع MTU موسع (حتى 251 بايت)، لا يلزم التجزئة — قراءة واحدة تعيد البيانات كاملة. قبل القراءة، يمكنك استدعاء requestMtu() للتفاوض على أقصى MTU.

kotlin
// قراءة الخاصية والواصف عبر BluetoothGatt
class GattReader {

    fun readHeartRate(gatt: BluetoothGatt) {
        // UUID لخدمة معدل ضربات القلب = 0x180D
        val service = gatt.getService(UUID.fromString("0000180D-0000-1000-8000-00805F9B34FB"))
            ?: return
        // 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) }
    }

    // معالجة البيانات في callback onCharacteristicRead:
    fun parseHeartRate(value: ByteArray): Int {
        // معدل ضربات القلب BLE: bytes = flags, second = 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 قراءة خاصية معدل ضربات القلب. الخدمة 0x180D تحتوي على الخاصية 0x2A37 (Heart Rate Measurement) — ملف BLE قياسي من Bluetooth SIG. قبل القراءة، يتم التحقق من خاصية PROPERTY_READ عبر hasProperty. يحلل parseHeartRate تنسيق BLE للنبض: البايت الأول — flags (تنسيق البيانات)، الثاني — قيمة bpm. تتم قراءة واصف CCCD (0x2902) للتحقق من حالة الإشعارات.

كتابة الخصائص: writeCharacteristic مع WriteType

writeCharacteristic() — طريقة BluetoothGatt لكتابة البيانات على جهاز BLE طرفي. في Android API 33+، تم استبدال writeCharacteristic() بـ writeCharacteristic(request)، حيث BluetoothGattCharacteristicWriteRequest هو كائن طلب يحتوي على الخاصية، مصفوفة البايت و WriteType. الطريقة القديمة writeCharacteristic(characteristic) مع setValue() مهملة. يحدد WriteType سلوك الطلب: WRITE_TYPE_DEFAULT (يعتمد على خصائص الخاصية)، WRITE_TYPE_NO_RESPONSE (بدون استجابة) و WRITE_TYPE_SIGNED (تفويض).

يؤثر اختيار WriteType على السرعة والموثوقية. WRITE_TYPE_DEFAULT عادة ما يتوافق withResponse (إذا كانت الخاصية تحتوي على PROPERTY_WRITE) أو withoutResponse (إذا كانت تحتوي على PROPERTY_WRITE_NO_RESPONSE). للبيانات المتدفقة (تحديثات OTA، السجلات)، استخدم WRITE_TYPE_NO_RESPONSE — أقصى إنتاجية. للأوامر مع ضمان التسليم (تمكين، تكوين) — WRITE_TYPE_DEFAULT مع تأكيد عبر onCharacteristicWrite.

kotlin
// كتابة خاصية BLE على Android API 33+
class GattWriter {

    // الكتابة مع استجابة (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)
        }
    }

    // الكتابة بدون استجابة (أقصى سرعة)
    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)
        }
    }

    // Callback onCharacteristicWrite (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 كلا WriteTypes لمستويات API المختلفة. يستخدم writeWithResponse WRITE_TYPE_DEFAULT — يؤكد جهاز BLE الكتابة عبر onCharacteristicWrite. يستخدم writeWithoutResponse WRITE_TYPE_NO_RESPONSE — يتم إرسال البيانات بدون تأكيد، أقصى إنتاجية. في API 33+، يتم استخدام writeCharacteristic(request) الجديد مع BluetoothGattCharacteristicWriteRequest. في API < 33 — القديم setValue() + writeCharacteristic().

الاشتراك في الإشعارات: setCharacteristicNotification و CCCD

setCharacteristicNotification() — طريقة BluetoothGatt للاشتراك في إشعارات تغيير الخاصية على الجهاز الطرفي. بعد تنشيط الاشتراك، يرسل جهاز BLE قيمًا جديدة عبر onCharacteristicChanged(). ومع ذلك، setCharacteristicNotification() تنشط فقط الإشعار المحلي لـ Android — لتمكين الإشعارات على جهاز BLE نفسه، يجب أيضًا كتابة القيمة 0x0100 في واصف CCCD (0x2902).

CCCD (Client Characteristic Configuration Descriptor) — واصف يتحكم في إرسال الإشعارات من جهاز BLE الطرفي. القيمة 0x0000 — الإشعارات معطلة، 0x0100 — الإشعارات مفعلة، 0x0200 — التأشيرات مفعلة. تتم الكتابة في CCCD عبر writeDescriptor() على BluetoothGatt بعد استدعاء setCharacteristicNotification(). لا يكتب Android CCCD تلقائيًا — هذه المسؤولية تقع على المطور.

kotlin
// الاشتراك الصحيح في إشعارات BLE
class GattNotificationManager {

    // 1. تفعيل الإشعارات
    fun enableNotification(gatt: BluetoothGatt, characteristic: BluetoothGattCharacteristic) {
        // الخطوة 1: الاشتراك المحلي في Android
        val success = gatt.setCharacteristicNotification(characteristic, true)
        if (!success) {
            print("فشل الاشتراك")
            return
        }

        // الخطوة 2: كتابة CCCD (0x2902) على جهاز BLE
        val cccdDescriptor = characteristic.getDescriptor(
            UUID.fromString("00002902-0000-1000-8000-00805F9B34FB")
        ) ?: return

        // 0x0100 = إشعار، 0x0200 = تأشير
        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. اكتشاف الخصائص
    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. Callback الإشعار
    private val notificationCallback = object : BluetoothGattCallback() {
        override fun onCharacteristicChanged(
            gatt: BluetoothGatt,
            characteristic: BluetoothGattCharacteristic,
            value: ByteArray,
            callbackType: Int
        ) {
            // قيمة جديدة من جهاز BLE الطرفي
            print("Notification: ${value.size} bytes")
        }
    }
}

تنفذ فئة GattNotificationManager بروتوكول الاشتراك الصحيح المكون من خطوتين لإشعارات BLE. يستدعي enableNotification أولاً setCharacteristicNotification(true) على Android، ثم يكتب 0x0100 في واصف CCCD عبر writeDescriptor. ينفذ disableNotification العمليات العكسية. بدون كتابة CCCD، لا يرسل جهاز BLE الإشعارات — وهذا هو الخطأ الأكثر شيوعًا بين مطوري BLE على Android.

مثال عميل GATT بلغة Kotlin مع BluetoothGattCallback

مثال كامل لعميل GATT بلغة Kotlin يجمع إنشاء BluetoothGatt والاكتشاف والقراءة والاشتراك في الإشعارات في مدير واحد باستخدام coroutines للمعالجة غير المتزامنة.

kotlin
// عميل GATT كامل مع coroutines في Kotlin
class GattClient(context: Context) {

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

    // الاتصال مع coroutine
    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
            )
        }

    // قراءة الخاصية عبر coroutine
    suspend fun readCharacteristicValue(char: BluetoothGattCharacteristic): ByteArray? =
        suspendCoroutine { continuation ->
            gatt?.let { gatt ->
                // حفظ علامة الخاصية لتحديد callback
                gatt.setCharacteristic(char, null)  // لـ API < 33
                gatt.readCharacteristic(char)
            }
        }

    // إغلاق الاتصال
    fun release() {
        gatt?.disconnect()
        gatt?.close()
        gatt = null
    }
}

يستخدم عميل GATT GattClient coroutines (suspendCoroutine) لتحويل API BluetoothGatt القائمة على callback إلى استدعاءات تسلسلية. ينتظر connect() onServicesDiscovered، وبعد ذلك يصبح التسلسل الهرمي GATT متاحًا. ينتظر readCharacteristicValue() onCharacteristicRead. هذا النهج يلغي تداخل callbacks ويجعل كود BLE خطيًا. يضمن release() تحرير الموارد — استدعاء إلزامي في onDestroy لـ Activity أو ViewModel.onCleared.

الأسئلة الشائعة

ما هو BluetoothGatt في Android؟

BluetoothGatt — فئة Android لعميل GATT تدير اتصال BLE مع جهاز طرفي. يتم إنشاؤها عبر BluetoothDevice.connectGatt()، وتوفر طرق discoverServices()، readCharacteristic()، writeCharacteristic()، setCharacteristicNotification(). نتائج جميع العمليات تصل بشكل غير متزامن عبر BluetoothGattCallback. بدون BluetoothGatt، الاتصال الثنائي BLE على Android مستحيل.

لماذا يعيد onServicesDiscovered الحالة 133؟

الحالة 133 (GATT_ERROR) تعني خطأ داخلي في مكدس BLE في Android. الأسباب: انفصال الجهاز أثناء الاكتشاف، MTU أقل من الحد الأدنى (23 بايت)، أو مكدس BLE محمل زائدًا. الحل: أعد discoverServices() بتأخير 500 مللي ثانية، تحقق من RSSI للجهاز وتأكد من أن الجهاز الطرفي يدعم اكتشاف GATT في حالته الحالية.

كيف أكتب خاصية مع تأكيد بشكل صحيح؟

للكتابة مع تأكيد، استدع writeCharacteristic() مع WRITE_TYPE_DEFAULT (API 33+: BluetoothGattCharacteristicWriteRequest). عند النجاح، يرسل جهاز BLE تأكيدًا ويستدعي Android onCharacteristicWrite مع GATT_SUCCESS. إذا لم يستجب الجهاز خلال 30 ثانية (مهلة المكدس)، يعيد callback حالة خطأ. لـ watchdog، استخدم Handler مع postDelayed.

كيف أعمل مع BLE على Android 33+؟

في Android 13+ (API 33)، تغيرت طرق BluetoothGatt: writeCharacteristic() الآن تقبل BluetoothGattCharacteristicWriteRequest، readCharacteristic() — BluetoothGattCharacteristicReadRequest. الطرق القديمة setValue()/writeCharacteristic() مهملة. كما تغير BluetoothGattCallback: onCharacteristicRead()، onCharacteristicWrite()، onCharacteristicChanged() تستقبل ByteArray value و callbackType. استخدم Build.VERSION.SDK_INT للتفرع.

كم عدد اتصالات BLE التي يدعمها Android؟

يدعم Android 4–8 اتصالات BLE GATT متزامنة (يختلف حسب الشركة المصنعة وإصدار Android). Pixel/Google: حتى 7، Samsung: حتى 5، Xiaomi: حتى 4. عند تجاوز الحد، يعيد connectGatt قيمة null أو onConnectionStateChange مع خطأ. للعمل مع عدد كبير من الأجهزة، استخدم الاتصال الدوري أو Bluetooth Mesh.

الخلاصة

  • BluetoothGatt — عميل GATT في Android لاتصال BLE، يتم إنشاؤه عبر BluetoothDevice.connectGatt() مع BluetoothGattCallback
  • discoverServices() — خطوة إلزامية بعد الاتصال للحصول على خدمات الجهاز BLE وخصائصه وواصفاته
  • القراءة — readCharacteristic() بنتيجة غير متزامنة في onCharacteristicRead()؛ للبيانات الكبيرة يلزم التفاوض على MTU
  • الكتابة — writeCharacteristic() مع WriteType: DEFAULT (withResponse) أو NO_RESPONSE (بدون تأكيد)
  • الإشعارات — تنشيط من خطوتين: setCharacteristicNotification() + كتابة CCCD (0x2902) بقيمة 0x0100
  • API 33+ — طرق جديدة writeCharacteristic(request) و readCharacteristic(request) مع كائنات طلب
  • تحرير الموارد — استدعاء إلزامي لـ disconnect() و close() لمنع تسرب اتصالات BLE

سنقوم بتطوير تطبيق جوال جاهز

تقدم IT Sectr تطبيقات iOS وAndroid للشركات الناشئة والشركات منذ عام 2017. سوف نقدم لك النصح ونقترح أفضل حل.

مناقشة المشروع

اقرأ أيضًا