我正在创建一个跨平台的应用程序来与蓝牙 LE 设备连接。该应用程序适用于Android和iOS,但无法在Windows上连接。当我调用pairAsync()
时,"连接"窗口会弹出一会儿,然后更改为"连接失败"。根据 MS 文档,返回的状态为 19,DevicePairingResultStatus.Failed
"发生未知故障"。
我正在使用cordova-plugin-蓝牙来处理跨平台差异。我已经在多台带有内置和USB蓝牙适配器的计算机上尝试过。
连接代码:
connect: function (successCallback, errorCallback, params) {
if (!initialized) {
errorCallback({ error: "connect", message: "Not initialized." });
return;
}
var address = params && params[0] && params[0].address;
if (!address) {
errorCallback({ error: "connect", message: "Device address is not specified" });
return;
}
var DeviceInformation = Windows.Devices.Enumeration.DeviceInformation;
var DeviceInformationKind = Windows.Devices.Enumeration.DeviceInformationKind;
WinJS.Promise.wrap(address)
.then(function (deviceAddress) {
// If we have cached device info return it right now
if (WATCH_CACHE[deviceAddress]) return [WATCH_CACHE[deviceAddress]];
// Otherwise try to search it again
var selector = "System.Devices.Aep.ProtocolId:="{bb7bb05e-5972-42b5-94fc-76eaa7084d49}" AND " +
"System.Devices.Aep.ContainerId:="{" + deviceAddress + "}" AND " +
"(System.Devices.Aep.CanPair:=System.StructuredQueryType.Boolean#True OR " +
"System.Devices.Aep.IsPaired:=System.StructuredQueryType.Boolean#True)";
return DeviceInformation.findAllAsync(selector, ["System.Devices.Aep.ContainerId"], DeviceInformationKind.associationEndpoint);
})
.then(function (devices) {
return Windows.Devices.Bluetooth.BluetoothLEDevice.fromIdAsync(devices[0].id);
})
.then(function (bleDevice) {
var DevicePairingProtectionLevel = Windows.Devices.Enumeration.DevicePairingProtectionLevel;
var DevicePairingResultStatus = Windows.Devices.Enumeration.DevicePairingResultStatus;
var DevicePairingKinds = Windows.Devices.Enumeration.DevicePairingKinds;
if (bleDevice.deviceInformation.pairing.isPaired) {
return bleDevice;
}
if (!bleDevice.deviceInformation.pairing.canPair) {
throw { error: "connect", message: "The device does not support pairing" };
}
// TODO: investigate if it is possible to pair without user prompt
return bleDevice.deviceInformation.pairing.pairAsync(DevicePairingProtectionLevel.none)
.then(function (res) {
if (res.status === DevicePairingResultStatus.paired ||
res.status === DevicePairingResultStatus.alreadyPaired)
return bleDevice;
// I modified these two lines to return the actual error message instead of a generic rejection message
var msg = getDevicePairingResultStatusMessage(res.status);
throw { error: "connect", message: "(" + res.status + ") " + msg };
});
})
.done(function (bleDevice) {
var result = {
name: bleDevice.deviceInformation.name,
address: address,
status: "connected"
};
// Attach listener to device to report disconnected event
bleDevice.addEventListener('connectionstatuschanged', function connectionStatusListener(e) {
if (e.target.connectionStatus === Windows.Devices.Bluetooth.BluetoothConnectionStatus.disconnected) {
result.status = "disconnected";
successCallback(result);
bleDevice.removeEventListener('connectionstatuschanged', connectionStatusListener);
}
});
// Need to use keepCallback to be able to report "disconnect" event
// https://github.com/randdusing/cordova-plugin-bluetoothle#connect
successCallback(result, { keepCallback: true });
}, function (err) {
errorCallback(err);
});
}
bleDevice.deviceInformation.pairing.定制。配对异步
private async void deviceListView_ItemClick(object sender, ItemClickEventArgs e)
{
var item = e.ClickedItem as DeviceInformation;
if (item.Pairing.CanPair)
{
var customPairing = item.Pairing.Custom;
customPairing.PairingRequested += CustomPairing_PairingRequested;
var result = await customPairing.PairAsync(DevicePairingKinds.ProvidePin);
customPairing.PairingRequested -= CustomPairing_PairingRequested;
if ((result.Status == DevicePairingResultStatus.Paired) ||
(result.Status == DevicePairingResultStatus.AlreadyPaired))
{
this.Frame.Navigate(typeof(DevicePage), item);
}
}
else if (item.Pairing.IsPaired == true)
{
this.Frame.Navigate(typeof(DevicePage), item);
}
}
private void CustomPairing_PairingRequested(DeviceInformationCustomPairing sender, DevicePairingRequestedEventArgs args)
{
args.Accept("123456");
}