Kommentar
Åtkomst till den här sidan kräver auktorisering. Du kan prova att logga in eller ändra kataloger.
Åtkomst till den här sidan kräver auktorisering. Du kan prova att ändra kataloger.
Den här artikeln visar hur du använder GATT-klient-API:er (Bluetooth Generic Attribute) för Windows appar.
Important
Du måste deklarera funktionen "bluetooth" i Package.appxmanifest.
<Capabilities> <DeviceCapability Name="bluetooth" /> </Capabilities>
- Importerande API:Windows. Devices.Bluetooth, Windows. Devices.Bluetooth.GenericAttributeProfile
Overview
Du kan använda API:erna i Windows. Devices.Bluetooth.GenericAttributeProfile för att få åtkomst till Bluetooth LE-enheter. Bluetooth LE-enheter exponerar sina funktioner genom en samling av:
- Services
- Egenskaper
- Beskrivningar
Tjänster definierar le-enhetens funktionella kontrakt och innehåller en samling egenskaper som definierar tjänsten. Dessa egenskaper innehåller i sin tur deskriptorer som beskriver egenskaperna. Dessa tre termer kallas allmänt attribut för en enhet.
Bluetooth LE GATT-API:er exponerar objekt och funktioner i stället för åtkomst till råtransporten. Med GATT-API:erna kan du också arbeta med Bluetooth LE-enheter med möjlighet att utföra följande uppgifter:
- Utför attributidentifiering
- Läs- och skriv-attributvärden
- Registrera ett återanrop för characteristic ValueChanged-händelse
För att skapa en användbar implementering måste du ha förkunskaper om de GATT-tjänster och egenskaper som programmet avser att använda och bearbeta de specifika karakteristiska värdena så att de binära data som tillhandahålls av API:et omvandlas till användbara data innan de presenteras för användaren. Bluetooth GATT-API:erna exponerar endast de grundläggande primitiver som krävs för att kommunicera med en Bluetooth LE-enhet. För att tolka data måste en programprofil definieras, antingen av en Bluetooth SIG-standardprofil eller en anpassad profil som implementeras av en enhetsleverantör. En profil skapar ett bindningskontrakt mellan programmet och enheten, vad utväxlade data representerar och hur du tolkar dem.
För enkelhetens skull har Bluetooth SIG en lista över tillgängliga offentliga profiler .
Fråga efter närliggande enheter
Det finns två huvudsakliga metoder för att fråga efter närliggande enheter:
- DeviceWatcher i Windows. Devices.Enumeration
- BluetoothLEAdvertisementWatcher i Windows.Devices.Bluetooth.Advertisement
Den andra metoden diskuteras länge i reklamdokumentationen så det kommer inte att diskuteras mycket här men den grundläggande idén är att hitta Bluetooth-adressen för närliggande enheter som uppfyller det specifika annonsfiltret. När du har adressen kan du anropa BluetoothLEDevice.FromBluetoothAddressAsync för att hämta en referens till enheten.
Gå nu tillbaka till devicewatcher-metoden. En Bluetooth LE-enhet är precis som alla andra enheter i Windows och kan efterfrågas med hjälp av api:erna Enumeration. Använd klassen DeviceWatcher och skicka en frågesträng som anger vilka enheter som ska söka efter:
// Query for extra properties you want returned
string[] requestedProperties = { "System.Devices.Aep.DeviceAddress", "System.Devices.Aep.IsConnected" };
DeviceWatcher deviceWatcher =
DeviceInformation.CreateWatcher(
BluetoothLEDevice.GetDeviceSelectorFromPairingState(false),
requestedProperties,
DeviceInformationKind.AssociationEndpoint);
// Register event handlers before starting the watcher.
// Added, Updated and Removed are required to get all nearby devices
deviceWatcher.Added += DeviceWatcher_Added;
deviceWatcher.Updated += DeviceWatcher_Updated;
deviceWatcher.Removed += DeviceWatcher_Removed;
// EnumerationCompleted and Stopped are optional to implement.
deviceWatcher.EnumerationCompleted += DeviceWatcher_EnumerationCompleted;
deviceWatcher.Stopped += DeviceWatcher_Stopped;
// Start the watcher.
deviceWatcher.Start();
När du har startat DeviceWatcher får du Enhetsinformation för varje enhet som uppfyller frågan i hanteraren för händelsen Lägg till för enheterna i fråga. En mer detaljerad titt på DeviceWatcher finns i det fullständiga exemplet på Github.
Ansluta till enheten
När en önskad enhet har hittats använder du DeviceInformation.Id för att hämta objektet Bluetooth LE Device för enheten i fråga:
private async Task ConnectDevice(DeviceInformation deviceInfo)
{
// Note: BluetoothLEDevice.FromIdAsync must be called from a UI thread because it may prompt for consent.
BluetoothLEDevice bluetoothLeDevice = await BluetoothLEDevice.FromIdAsync(deviceInfo.Id);
// ...
}
Å andra sidan utlöser bortskaffande av alla referenser till ett BluetoothLEEnhetsobjekt för en enhet (och om ingen annan app i systemet har en referens till enheten) en automatisk frånkoppling efter en liten tidsgräns.
bluetoothLeDevice.Dispose();
Om appen behöver få åtkomst till enheten igen räcker det att skapa enhetsobjektet på nytt och få åtkomst till en karakteristik (som beskrivs i nästa avsnitt), så gör operativsystemet att enheten återansluts vid behov. Om enheten finns i närheten får du åtkomst till enheten, annars returneras den med ett DeviceUnreachable-fel.
Note
Att skapa ett BluetoothLEDevice-objekt genom att anropa den här metoden ensam initierar inte (nödvändigtvis) en anslutning. För att initiera en anslutning ställer du in GattSession.MaintainConnection på true, eller anropar en metod för tjänstidentifiering utan cache på BluetoothLEDevice, eller utför en läs-/skrivåtgärd på enheten.
- Om GattSession.MaintainConnection är inställt på sant väntar systemet på obestämd tid på en anslutning och ansluter när enheten är tillgänglig. Det finns inget för ditt program att vänta på, eftersom GattSession.MaintainConnection är en egenskap.
- För tjänstidentifiering och läs-/skrivåtgärder i GATT väntar systemet en begränsad men variabel tid. Allt från ögonblickligt till några minuter. Faktorerna omfattar trafiken på stacken och hur länge begäran har stått i kö. Om det inte finns någon annan väntande begäran och fjärrenheten inte kan nås väntar systemet i sju (7) sekunder innan tidsgränsen uppnås. Om det finns andra väntande begäranden kan var och en av begäranden i kön ta sju (7) sekunder att bearbeta, så ju längre din begäran är längst bak i kön, desto längre väntar du.
För närvarande kan du inte avbryta anslutningsprocessen.
Räkna upp tjänster och egenskaper som stöds
Nu när du har ett BluetoothLEDevice-objekt är nästa steg att identifiera vilka data som enheten exponerar. Det första steget för att göra detta är att fråga efter tjänster:
GattDeviceServicesResult result = await bluetoothLeDevice.GetGattServicesAsync();
if (result.Status == GattCommunicationStatus.Success)
{
var services = result.Services;
// ...
}
När tjänsten av intresse har identifierats är nästa steg att fråga efter egenskaper.
GattCharacteristicsResult result = await service.GetCharacteristicsAsync();
if (result.Status == GattCommunicationStatus.Success)
{
var characteristics = result.Characteristics;
// ...
}
Operativsystemet returnerar en ReadOnly-lista över GattCharacteristic-objekt som du sedan kan utföra åtgärder på.
Utför läs- och skrivåtgärder på en karakteristik
Egenskapen är den grundläggande enheten för GATT-baserad kommunikation. Den innehåller ett värde som representerar en distinkt datamängd på enheten. Batterinivåegenskaperna har till exempel ett värde som representerar enhetens batterinivå.
Läs de karakteristiska egenskaperna för att avgöra vilka åtgärder som stöds:
GattCharacteristicProperties properties = characteristic.CharacteristicProperties;
if(properties.HasFlag(GattCharacteristicProperties.Read))
{
// This characteristic supports reading from it.
}
if(properties.HasFlag(GattCharacteristicProperties.Write))
{
// This characteristic supports writing to it.
}
if(properties.HasFlag(GattCharacteristicProperties.Notify))
{
// This characteristic supports subscribing to notifications.
}
Om läsning stöds kan du läsa värdet:
GattReadResult result = await selectedCharacteristic.ReadValueAsync();
if (result.Status == GattCommunicationStatus.Success)
{
var reader = DataReader.FromBuffer(result.Value);
byte[] input = new byte[reader.UnconsumedBufferLength];
reader.ReadBytes(input);
// Utilize the data as needed
}
Att skriva till en egenskap följer ett liknande mönster:
var writer = new DataWriter();
// WriteByte used for simplicity. Other common functions - WriteInt16 and WriteSingle
writer.WriteByte(0x01);
GattCommunicationStatus result = await selectedCharacteristic.WriteValueAsync(writer.DetachBuffer());
if (result == GattCommunicationStatus.Success)
{
// Successfully wrote to device
}
Tip
DataReader och DataWriter är oumbärliga när du arbetar med de rådatabuffertar som du får från många av Bluetooth-API:erna.
Prenumerera på meddelanden
Kontrollera att egenskapen stöder antingen Indicate eller Notify (kontrollera egenskaperna för egenskapen för att vara säker).
Indicate anses vara mer tillförlitligt eftersom varje ändrad värdehändelse kombineras med en bekräftelse från klientenheten.
Notify är vanligare eftersom de flesta GATT-transaktioner hellre sparar ström i stället för att vara extremt tillförlitliga. I vilket fall som helst hanteras allt detta på kontrollantlagret så att appen inte engagerar sig. Vi refererar tillsammans till dem som "meddelanden".
Det finns två saker att ta hand om innan du får meddelanden:
- Skriv till CCCD (Client Characteristic Configuration Descriptor)
- Hantera händelsen Characteristic.ValueChanged
Att skriva till CCCD talar om för serverenheten att den här klienten vill veta varje gång det specifika egenskapsvärdet ändras. Så här gör du:
GattCommunicationStatus status = await selectedCharacteristic.WriteClientCharacteristicConfigurationDescriptorAsync(
GattClientCharacteristicConfigurationDescriptorValue.Notify);
if(status == GattCommunicationStatus.Success)
{
// Server has been informed of clients interest.
}
Nu anropas GattCharacteristics ValueChanged-händelse varje gång värdet ändras på fjärrenheten. Allt som återstår är att implementera hanteraren:
characteristic.ValueChanged += Characteristic_ValueChanged;
...
void Characteristic_ValueChanged(GattCharacteristic sender,
GattValueChangedEventArgs args)
{
// An Indicate or Notify reported that the value has changed.
var reader = DataReader.FromBuffer(args.CharacteristicValue);
// Parse the data however required.
}
Examples
Ett fullständigt exempel finns i Bluetooth Low Energy sample.
Windows developer