GATT (Generic Attribute Profile) — Bluetooth Low Energy (BLE)-profilen som definierar datastrukturen och reglerna för informationsutbyte mellan BLE-enheter. GATT är byggt ovanpå Attribute Protocol (ATT) och organiserar data i en hierarki: tjänster (services), egenskaper (characteristics) och deskriptorer (descriptors). Enligt Bluetooth SIG (2025) används GATT-profilen i 98% av alla BLE-applikationer — från fitnesstrackers till smarta lås och medicinska sensorer.
Huvudpunkter
GATT (Generic Attribute Profile) — är Bluetooth Low Energy (BLE)-profilen som definierar hur två BLE-enheter utbyter data via Attribute Protocol (ATT). GATT standardiserar datastrukturen: all data är organiserad i hierarkin “tjänst → egenskap → deskriptor”. Profilen introducerades i Bluetooth 4.0-specifikationen (2010) tillsammans med BLE och har sedan dess förblivit den huvudsakliga dataöverföringsmekanismen för energieffektiva Bluetooth-enheter. Till skillnad från klassisk Bluetooth, där data överförs via en seriell port (SPP), tillhandahåller GATT strukturerad åtkomst till data via läs-, skriv- och notifieringsoperationer.
BLE-stacken består av flera lager: Physical Layer (radio), Link Layer (anslutningshantering), L2CAP (logisk kanalöverföring), ATT (Attribute Protocol — åtkomst till attribut) och GATT (ATT-baserad profil). GATT är det högsta lagret som applikationsutvecklaren arbetar med. Det underliggande ATT tillhandahåller grundläggande operationer: läsning, skrivning, notifiering och indikering av attribut. GATT lägger till semantik: det definierar vad en tjänst är, vad en egenskap är, hur de grupperas och vilka regler som gäller vid läsning och skrivning. Enligt Bluetooth Core Specification 5.4 (2023) stöder GATT upp till 65 535 attribut (tjänster + egenskaper + deskriptorer) på en enda enhet.
GATT-hierarkin består av tre nivåer. Tjänst (Service) — en logisk grupp av egenskaper som löser en uppgift (till exempel “Batteritjänst” eller “Pulstjänst”). Egenskap (Characteristic) — en dataenhet med känd typ: aktuell batterinivå, sensoravläsningar, strömbrytarens status. Varje egenskap har ett värde (value) och en eller flera deskriptorer (Descriptors) som beskriver metadata: måttenheter, notifieringsinställningar, värdeintervall. UUID (Universally Unique Identifier) identifierar unikt varje tjänst och varje egenskap.
GATT stöder fyra typer av operationer för interaktion med egenskaper. Read — klienten begär det aktuella värdet av egenskapen från servern. Write — klienten skickar ett nytt värde till servern. Notify — servern skickar värdet till klienten utan bekräftelse (snabbare men mindre tillförlitligt). Indicate — servern skickar värdet med kvittens (mer tillförlitligt men långsammare). Utvecklaren väljer typ beroende på scenario: för pulssensoravläsningar räcker Notify, för skrivning av konfiguration av ett smart lås — Write med bekräftelse.
// GATT-datastruktur i Android-kod
data class BleService(
val uuid: UUID,
val characteristics: List<BleCharacteristic>
)
data class BleCharacteristic(
val uuid: UUID,
val properties: Int, // LÄSA, SKRIVA, NOTIFIERA, INDIKERA
val descriptors: List<BleDescriptor>,
var value: ByteArray?
)
I BLE-specifikationen definieras två huvudprofiler: GAP (Generic Access Profile) och GATT (Generic Attribute Profile). GAP ansvarar för enhetsdetektering, anslutningsupprättande och synlighetshantering — detta är “nätverkslagret” för BLE. GATT — för datautbyte efter anslutning, det vill säga “applikationslagret”. Utvecklaren använder GAP för att skanna och ansluta till en enhet, och GATT — för att läsa, skriva och ta emot notifieringar från den anslutna enheten.
| Egenskap | GAP | GATT |
|---|---|---|
| Syfte | Detektering och anslutning | Datautbyte |
| Roller | Central / Peripheral | Client / Server |
| Protokoll | HCI, Link Layer | ATT (Attribute Protocol) |
| Steg | Före anslutning | Efter anslutning |
| Huvudklass | BluetoothAdapter | BluetoothGatt |
GATT definierar två roller: GATT Server och GATT Client. Server — enheten som tillhandahåller data (till exempel en fitnesstracker som skickar pulsavläsningar). Klient — enheten som begär data (till exempel en smartphone som läser mätningar). I de flesta scenarier fungerar Android-appen som GATT Client och BLE-kringutrustningen som GATT Server. Android kan dock också vara GATT Server — till exempel om appen emulerar en BLE-enhet för andra enheter. Rollen bestäms i fasen för att upprätta GATT-anslutningen och ändras inte under sessionen.
Processen för GATT-kommunikation börjar efter att BLE-anslutningen har upprättats mellan enheterna. Först upptäcker GATT Client tjänster på GATT Server via Service Discovery-operationen — Android utför detta automatiskt vid anslutning via BluetoothGatt.discoverServices(). Efter upptäckten får klienten en lista över tillgängliga tjänster, egenskaper och deskriptorer. Sedan kan klienten läsa egenskapsvärden (Read), skriva nya värden (Write) eller prenumerera på notifieringar (Set Notify/Indicate). GATT Server kan skicka Notify/Indicate till klienten när som helst efter att anslutningen har upprättats.
Som standard är storleken på ett GATT-paket (MTU, Maximum Transmission Unit) i BLE 23 byte, varav 3 byte är ATT-huvud och 20 byte är nyttodata. Om applikationen behöver överföra mer data (till exempel OTA firmware-uppdatering), kan man begära en ökning av MTU till 517 byte via requestMtu() i Android. Ökad MTU minskar antalet paket som krävs för att överföra ett datablock — istället för 50 små paket kan 2 stora skickas, vilket minskar energiförbrukningen och påskyndar överföringen. Maximal MTU beror på BLE-versionen och chipets kapacitet — Bluetooth 5.0 stöder upp till 517 byte, äldre versioner upp till 247 byte.
// Prenumerera på egenskapsnotifieringar
fun enableNotifications(gatt: BluetoothGatt, characteristic: BluetoothGattCharacteristic) {
gatt.setCharacteristicNotification(characteristic, true)
// Aktivera CCCD (Client Characteristic Configuration Descriptor)
val cccdUuid = UUID.fromString("00002902-0000-1000-8000-00805f9b34fb")
val descriptor = characteristic.getDescriptor(cccdUuid)
descriptor?.let {
it.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE)
gatt.writeDescriptor(it)
}
}
För att ta emot notifieringar från GATT Server i Android måste man implementera callbacken BluetoothGattCallback.onCharacteristicChanged(). I denna metod får applikationen det uppdaterade värdet av egenskapen varje gång servern skickar Notify eller Indicate. För realtidsdatabehandling, använd en buffert och Kotlin-korutiner — detta förhindrar blockering av UI-tråden vid intensiva notifieringar (till exempel 100+ pulsavläsningar per sekund). Vid indikationer (Indicate) måste du alltid anropa gatt.sendResponse() på serversidan — i Android-klienten hanteras detta automatiskt.
I Android utförs arbete med GATT via klasserna i paketet android.bluetooth: BluetoothGatt (anslutning), BluetoothGattService (tjänst), BluetoothGattCharacteristic (egenskap) och BluetoothGattDescriptor (deskriptor). Anslutning till en BLE-enhet börjar med att anropa BluetoothDevice.connectGatt() — denna metod returnerar BluetoothGatt, genom vilken alla efterföljande operationer utförs. Alla GATT-callbacks kommer i BluetoothGattCallback — detta är ett asynkront gränssnitt som anropas i samma tråd där BluetoothGatt skapades. Viktigt: alla GATT-operationer måste utföras sekventiellt — samtidiga anrop av flera operationer på samma BluetoothGatt leder till fel.
Korrekt hantering av livscykeln för GATT-anslutningen är avgörande för stabiliteten hos BLE-applikationen. Efter anrop av connectGatt() väntar applikationen på callbacken onConnectionStateChange() med status STATE_CONNECTED. Sedan startar systemet automatiskt Service Discovery, efter vars slutförande onServicesDiscovered() anropas. Först efter detta kan läsning, skrivning och prenumeration utföras. Vid slutförandet måste du alltid anropa gatt.close() i onDestroy() eller onPause() — oavslutade GATT-anslutningar förbrukar batteri och kan blockera återanslutning till samma enhet i Android.
// Anslut till BLE-enhet via GATT
private val gattCallback = object : BluetoothGattCallback() {
override fun onConnectionStateChange(
gatt: BluetoothGatt, status: Int, newState: Int
) {
if (newState == BluetoothProfile.STATE_CONNECTED) {
gatt.discoverServices()
}
}
override fun onServicesDiscovered(gatt: BluetoothGatt, status: Int) {
val service = gatt.getService(UUID.fromString("180D"))
val characteristic = service?.getCharacteristic(
UUID.fromString("2A37")
)
characteristic?.let { enableNotifications(gatt, it) }
}
}
Bluetooth SIG (Special Interest Group) definierar dussintals standard GATT-profiler och tjänster med fasta 16-bitars UUID. De vanligaste: tjänsten Battery Service (UUID 180F, egenskapen Battery Level 2A19), tjänsten Heart Rate (UUID 180D, egenskapen Heart Rate Measurement 2A37), tjänsten Device Information (UUID 180A, egenskaperna Manufacturer Name, Serial Number). Användning av standardtjänster garanterar kompatibilitet mellan enheter från olika tillverkare — vilket fitnessarmband som helst med Heart Rate-tjänsten bör fungera med vilken Android-app som helst som stöder den.
Om standardtjänster inte täcker uppgiften kan utvecklaren skapa egna GATT-tjänster med 128-bitars UUID (anpassade UUID). Vid design av en anpassad tjänst måste man: definiera den logiska gruppen av egenskaper (till exempel “Låshanteringstjänst”), ge varje egenskap rätt egenskaper (Read, Write, Notify), bestämma tillåtna värden och måttenheter via deskriptorn Characteristic Presentation Format. För komplexa protokoll rekommenderas att inkludera en Command-egenskap med Write-egenskap och en Status-egenskap med Notify i tjänsten — detta motsvarar Command/Status-mönstret som används i industriella BLE-applikationer.
// Skapa anpassad GATT-tjänst (Android som GATT Server)
private fun createCustomService(): BluetoothGattService {
val serviceUuid = UUID.fromString("12345678-1234-5678-1234-56789abcdef0")
val service = BluetoothGattService(
serviceUuid, BluetoothGattService.SERVICE_TYPE_PRIMARY
)
val charUuid = UUID.fromString("12345678-1234-5678-1234-56789abcdef1")
val characteristic = BluetoothGattCharacteristic(
charUuid,
BluetoothGattCharacteristic.PROPERTY_READ or
BluetoothGattCharacteristic.PROPERTY_NOTIFY,
BluetoothGattCharacteristic.PERMISSION_READ
)
service.addCharacteristic(characteristic)
return service
}
Vanliga frågor
GATT (Generic Attribute Profile) — är Bluetooth Low Energy-profilen som definierar strukturen för datautbyte mellan enheter. Det behövs för standardisering av åtkomst till information: alla BLE-enheter organiserar data i tjänster och egenskaper, vilket gör att alla klienter kan läsa sensoravläsningar, styra enheter och ta emot notifieringar.
GAP ansvarar för detektering och anslutning av BLE-enheter (skanning, annonsering, anslutningsupprättande). GATT — för datautbyte efter anslutning (läsning, skrivning, notifieringar). GAP fungerar före anslutning, GATT — efter. Båda profilerna är obligatoriska för BLE men har olika funktioner: GAP är “nätverkslagret”, GATT är “applikationslagret”.
Standardtjänster inkluderar Battery Service (180F, batterinivå), Heart Rate (180D, puls), Device Information (180A, enhetsdata). Varje tjänst innehåller flera egenskaper med 16-bitars UUID. Utvecklare kan skapa anpassade tjänster med 128-bitars UUID för specifika uppgifter — till exempel för att styra ett smart lås eller överföra data från en fitnesstracker.
I Android implementeras GATT via BluetoothGatt (anslutning), BluetoothGattService (tjänst), BluetoothGattCharacteristic (egenskap) och BluetoothGattDescriptor (deskriptor). Anslutning görs via connectGatt(), varefter händelser kommer i BluetoothGattCallback: onConnectionStateChange, onServicesDiscovered, onCharacteristicChanged (för notifieringar). Alla GATT-operationer måste utföras sekventiellt.
UUID (Universally Unique Identifier) — en 16-bitars eller 128-bitars identifierare som unikt bestämmer en tjänst eller egenskap i GATT. Standard Bluetooth SIG-tjänster använder 16-bitars UUID (till exempel 180D för Heart Rate). Anpassade tjänster från utvecklare — 128-bitars UUID (till exempel 12345678-1234-5678-1234-56789abcdef0). UUID gör det möjligt för klienten att hitta nödvändig data på GATT Server.
Sammanfattning
Vi utvecklar en mobil applikation nyckelfärdigt
IT Sectr skapar iOS- och Android-applikationer för startups och företag sedan 2017. Vi ger dig råd och föreslår den bästa lösningen.
Läs också