问题
I am developing a UWP app that is using bluetooth to connect to different devices.
My problem is that some devices that has been paired or previously discovered is showing up in my device list even though they are turned off or not in range.
As of my understanding the property System.Devices.Aep.IsPresent can be used to filter out cached devices that are not available at the time but I always get "True" for that property even though I know the device is not reachable.
Any ideas on how this can be solved?
Setup
string[] requestedProperties = { "System.Devices.Aep.DeviceAddress", "System.Devices.Aep.IsConnected", "System.Devices.Aep.IsPresent", "System.Devices.Aep.ContainerId", "System.Devices.Aep.DeviceAddress", "System.Devices.Aep.Manufacturer", "System.Devices.Aep.ModelId", "System.Devices.Aep.ProtocolId", "System.Devices.Aep.SignalStrength"};
_deviceWatcher = DeviceInformation.CreateWatcher("{REMOVED, NOT IMPORTANT}", requestedProperties, DeviceInformationKind.AssociationEndpoint);
_deviceWatcher.Added += DeviceAdded;
_deviceWatcher.Updated += DeviceUpdated;
_deviceWatcher.Removed += DeviceRemoved;
_deviceWatcher.EnumerationCompleted += DeviceEnumerationCompleted;
Callback for when device is added
Here isPresent is always true
private void DeviceAdded(DeviceWatcher sender, DeviceInformation deviceInfo)
{
Device device = new Device(deviceInfo);
bool isPresent = (bool)deviceInfo.Properties.Single(p => p.Key == "System.Devices.Aep.IsPresent").Value;
Debug.WriteLine("*** Found device " + deviceInfo.Id + " / " + device.Id + ", " + "name: " + deviceInfo.Name + " ***");
Debug.WriteLine("RSSI = " + deviceInfo.Properties.Single(d => d.Key == "System.Devices.Aep.SignalStrength").Value);
Debug.WriteLine("Present: " + isPresent);
var rssi = deviceInfo.Properties.Single(d => d.Key == "System.Devices.Aep.SignalStrength").Value;
if (rssi != null)
device.Rssi = int.Parse(rssi.ToString());
if (DiscoveredDevices.All(x => x.Id != device.Id) && isPresent)
{
DiscoveredDevices.Add(device);
DeviceDiscovered(this, new DeviceDiscoveredEventArgs(device));
}
}
回答1:
Look into the Microsoft Bluetooth LE Explorer source code of GattSampleContext. You need to get properties: System.Devices.Aep.IsConnected, System.Devices.Aep.Bluetooth.Le.IsConnectable
and filter only devices, which are connectable. Take care, that the device may become connectable after the DeviceWatcher.Updated
event is called. So you have to keep some track of unusedDevices
.
E.g. my IsConnactable filter method is:
private static bool IsConnectable(DeviceInformation deviceInformation)
{
if (string.IsNullOrEmpty(deviceInformation.Name))
return false;
// Let's make it connectable by default, we have error handles in case it doesn't work
bool isConnectable = (bool?)deviceInformation.Properties["System.Devices.Aep.Bluetooth.Le.IsConnectable"] == true;
bool isConnected = (bool?)deviceInformation.Properties["System.Devices.Aep.IsConnected"] == true;
return isConnectable || isConnected;
}
回答2:
It is a little hard to specifically answer your question because you can use Bluetooth in several ways to connect to a device. For instance, some devices need to be paired to be usable. Some devices can't be discovered unless the Bluetooth stack is issuing an enquiry.
There are a few things to do though to get this pointed in the right direction.
- The first thing you want to do is use an AQS selector string to constrain what you are discovering. The selector should also constrain the protocol because you don't want the PC discovering WiFiDirect devices and network devices. Post filtering is not good for performance.
- Next look at the Bluetooth samples. They have many get selector type methods for different scenarios that you can use to pass into create watcher. Either one of those will do what you want, or you can look at their AQS string to get an idea of what your filter should look like.
In terms of properties you can use for your AQS selector, I am not sure if is present will be effective, but here are some other properties you might consider for constructing your selector/filter. Like I said, the scenario makes a big difference; like a headset must be paired, whereas some LE device can't be paired and are just connectable.
System.Devices.Aep.Bluetooth.IssueInquiry
System.Devices.Aep.Bluetooth.LastSeenTime
System.Devices.Aep.Bluetooth.Le.IsConnectable
System.Devices.Aep.IsPaired
System.Devices.Aep.CanPair
System.Devices.Aep.IsConnected
System.Devices.Aep.IsPresent
System.Devices.Aep.ProtocolId
A selector could look like this to enumerate Bluetooth BR devices that are paired:
System.Devices.Aep.ProtocolId:="{e0cbf06c-cd8b-4647-bb8a-263b43f0f974}" AND System.Devices.Aep.IsPaired:=System.StructuredQueryType.Boolean#True";
If you have a more specific device scenario, I can elaborate with a more specific answer.
来源:https://stackoverflow.com/questions/45568345/windows-uwp-bluetooth-app-devices-showing-up-when-scanning-even-when-they-are-p