Signatur
Beschreibung
Die Methode getPrimaryServices() des BluetoothRemoteGATTServer-Interfaces fragt beim verbundenen Bluetooth-Low-Energy-Gerät die primären GATT-Services ab. Das Ergebnis ist ein Promise, das mit einem Array von BluetoothRemoteGATTService-Objekten erfüllt wird. Über diese Objekte kommt man anschließend an die Characteristics und kann Werte lesen, schreiben oder Benachrichtigungen abonnieren.
Ohne Argument werden alle primären Services zurückgegeben, auf die die Seite zugreifen darf. Mit einer UUID werden nur Services dieses Typs geliefert. Das ist nützlich, wenn ein Gerät denselben Service mehrfach anbietet, etwa mehrere Batterie-Services. Braucht man nur genau einen Service, reicht meist getPrimaryService() (Einzahl).
Wichtig: Man bekommt nur Services, die beim Aufruf von navigator.bluetooth.requestDevice() über filters[].services oder optionalServices angegeben wurden. Außerdem muss der GATT-Server verbunden sein, also server.connected === true (vorher device.gatt.connect() aufrufen).
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $service | string|number | Optionale BluetoothServiceUUID: eine 128-Bit-UUID als String (z. B. '0000180f-0000-1000-8000-00805f9b34fb'), ein 16-/32-Bit-Alias als Zahl (z. B. 0x180F) oder ein standardisierter Name wie 'battery_service'. Fehlt der Parameter, werden alle erlaubten primären Services geliefert. |
Rückgabewert
NotFoundError abgelehnt.Beispiele
Alle erlaubten primären Services auflisten
const button = document.querySelector('#scan');
button.addEventListener('click', async () => {
try {
// Muss durch eine Nutzeraktion ausgelöst werden
const device = await navigator.bluetooth.requestDevice({
acceptAllDevices: true,
optionalServices: ['battery_service', 'device_information']
});
const server = await device.gatt.connect();
const services = await server.getPrimaryServices();
for (const service of services) {
console.log(`Service: ${service.uuid}, primär: ${service.isPrimary}`);
}
} catch (err) {
console.error(`${err.name}: ${err.message}`);
}
});
Nach UUID filtern und Batteriestand lesen
const readAllBatteryLevels = async () => {
const device = await navigator.bluetooth.requestDevice({
filters: [{ services: ['battery_service'] }]
});
const server = await device.gatt.connect();
// Ein Gerät kann mehrere Batterie-Services haben (z. B. linker/rechter Ohrhörer)
const services = await server.getPrimaryServices('battery_service');
const levels = await Promise.all(services.map(async (service) => {
const characteristic = await service.getCharacteristic('battery_level');
const value = await characteristic.readValue();
return value.getUint8(0);
}));
console.log('Batteriestände:', levels.map((l) => `${l} %`).join(', '));
device.gatt.disconnect();
};
document.querySelector('#battery').addEventListener('click', readAllBatteryLevels);
Fehlende Services abfangen
const findHeartRateServices = async (server) => {
if (!server.connected) {
await server.connect();
}
try {
return await server.getPrimaryServices(0x180D); // Herzfrequenz-Service
} catch (err) {
if (err.name === 'NotFoundError') {
console.warn('Gerät bietet keinen Herzfrequenz-Service an.');
return [];
}
if (err.name === 'SecurityError') {
console.warn('Service nicht in optionalServices angefordert.');
return [];
}
throw err;
}
};
// Wichtig · Fallstricke
- Kompatibilität: Web Bluetooth ist experimentell und nur in Chromium-Browsern verfügbar (Chrome, Edge, Opera; unter Linux teils hinter einem Flag). Firefox und Safari (auch iOS) unterstützen es nicht. Vorher mit
'bluetooth' in navigatorprüfen. - Sicherer Kontext: Funktioniert nur über HTTPS bzw.
localhost. In Cross-Origin-iframes ist es nur mit passender Permissions Policy (bluetooth) erlaubt. - Berechtigungen: Services, die bei
requestDevice()weder infiltersnoch inoptionalServicesstehen, werden nicht geliefert. Fragt man sie gezielt ab, gibt es einenSecurityError. Manche Services stehen auf einer Blockliste und sind grundsätzlich gesperrt (z. B. Human Interface Device,0x1812). - Fehler:
NetworkError, wenn der Server nicht verbunden ist;NotFoundError, wenn kein passender Service existiert;InvalidStateErrorbzw.NetworkError, wenn die Verbindung während der Abfrage abbricht. - Namen wie
'battery_service'müssen den GATT-Namen aus der Bluetooth-Spezifikation exakt entsprechen, sonst wirft der Aufruf einenTypeError. MitBluetoothUUID.getService()lässt sich ein Name vorab prüfen. - Die Abfrage aller Services kann bei Geräten mit vielen Services spürbar dauern. Wer gezielt filtert, spart Zeit und Energie.