写操作不会更新 xamarin 表单中 iOS 的特征值
The write operation doesn't update the characteristic value for iOS in xamarin forms
我正在使用 xamarin 表单创建 BLE 应用程序。 在 Android 中一切正常,我能够读写 GATT 特性。在 iOS 中,我能够成功读取,但 写入操作不会更新特征值 。 写操作没有错误,它也在执行,但特征值没有改变。我尝试了 iOS 名为 light blue 的本机应用程序,它工作正常,特征值已更新 我只在 Xamarin 表单应用程序中遇到问题。这是我的代码
private async Task<string> ProcessDeviceInformationService(IService deviceInfoService)
{
try
{
await adapter.ConnectToDeviceAsync(device);
var sb = new StringBuilder("Getting information from Device Information service: \n");
var characteristics = deviceInfoService.GetCharacteristicsAsync();
var characteristic = await deviceInfoService.GetCharacteristicAsync(Guid.Parse("00002a2b-0000-1000-8000-00805F9B34FB"));
try
{
if (characteristic != null)
{
var sbnew = new StringBuilder("BLE Characteristics\n");
byte[] senddata = Encoding.UTF8.GetBytes(string.IsNullOrEmpty(SendMessageLabel.Text) ? "12" : SendMessageLabel.Text);
characteristic.ValueUpdated += (o, args) =>
{
var bytes = characteristic.Value;
};
await characteristic.WriteAsync(senddata);
string str = Encoding.UTF8.GetString(senddata);
sbnew.AppendLine($"Characteristics found on this device: {string.Join(", ", str.ToString())}");
CharactericsLabel.Text = sbnew.ToString();
}
}
catch (Exception ex)
{
//return ex.Message;
DisplayAlert("Notice", ex.Message.ToString(), "OK");
}
我试过延迟,我也试过在没有外围设备响应的情况下写入,但它不起作用。这是我的外设代码
// Current Time characteristic
BluetoothGattCharacteristic currentTime = new BluetoothGattCharacteristic(CURRENT_TIME,
//Read-only characteristic, supports notifications
BluetoothGattCharacteristic.PROPERTY_READ | BluetoothGattCharacteristic.PROPERTY_NOTIFY | BluetoothGattCharacteristic.PROPERTY_WRITE_NO_RESPONSE,
BluetoothGattCharacteristic.PERMISSION_READ | BluetoothGattCharacteristic.PROPERTY_WRITE);
BluetoothGattDescriptor configDescriptor = new BluetoothGattDescriptor(CLIENT_CONFIG,
//Read/write descriptor
BluetoothGattDescriptor.PERMISSION_READ | BluetoothGattDescriptor.PERMISSION_WRITE);
currentTime.addDescriptor(configDescriptor);
// Local Time Information characteristic
BluetoothGattCharacteristic localTime = new BluetoothGattCharacteristic(LOCAL_TIME_INFO,
//Read-only characteristic
BluetoothGattCharacteristic.PROPERTY_READ,
BluetoothGattCharacteristic.PERMISSION_READ);
BluetoothGattCharacteristic sampleText = new BluetoothGattCharacteristic sampleText = new BluetoothGattCharacteristic(SAMPLE_TEXT,
//Read-only characteristic
BluetoothGattCharacteristic.PROPERTY_WRITE_NO_RESPONSE | BluetoothGattCharacteristic.PROPERTY_READ | BluetoothGattCharacteristic.PROPERTY_NOTIFY,
BluetoothGattCharacteristic.PERMISSION_WRITE | BluetoothGattCharacteristic.PERMISSION_READ);
我不知道如何解决这个问题 suggestions.I 甚至 Semaphore 都试过了,但它没有帮助,正如您在我的代码中看到的那样
private static async Task<string> WriteAndWaitForResponseAsync(
ICharacteristic characteristic,
byte[] senddata)
{
var semaphore = new SemaphoreSlim(0, 1);
string result = null;
characteristic.ValueUpdated += (o, args) =>
{
var bytes = characteristic.Value;
result = Encoding.UTF8.GetString(bytes); // Note I don't know if this is your intended behaviour with the values you get back, you can decide what to actually do with the response.
// Notify a value has been received.
semaphore.Release();
};
await characteristic.WriteAsync(senddata,new CancellationToken(true)).ConfigureAwait(false);
// Wait until we receive a notification.
await semaphore.WaitAsync(); // I strongly suggest you look in to CancellationTokens but I am not going in to that now.
return result;
}
我怀疑线程是这里问题的一部分,您订阅了事件,调用了 WriteAsync
,但最终在收到 data/event 之前就离开了该方法。我建议您需要在收到数据之前尝试阻止该方法离开。
试试这样的东西:
private static async Task<string> WriteAndWaitForResponseAsync(
ICharacteristic characteristic,
byte[] senddata)
{
var semaphore = new SemaphoreSlim(0, 1);
string result = null;
characteristic.ValueUpdated += (o, args) =>
{
// Make sure you read from the new value in event not the existing characteristic.
var bytes = args.Characteristic.Value;
result = Encoding.UTF8.GetString(bytes); // Note I don't know if this is your intended behaviour with the values you get back, you can decide what to actually do with the response.
// Notify a value has been received.
semaphore.Release();
};
await characteristic.WriteAsync(senddata);
// Wait until we receive a notification.
await semaphore.WaitAsync(); // I strongly suggest you look in to CancellationTokens but I am not going in to that now.
return result;
}
然后您可以从当前方法中调用此方法,例如:
string str = await WriteAndWaitForResponseAsync(characteristic, senddata);
我正在使用 xamarin 表单创建 BLE 应用程序。 在 Android 中一切正常,我能够读写 GATT 特性。在 iOS 中,我能够成功读取,但 写入操作不会更新特征值 。 写操作没有错误,它也在执行,但特征值没有改变。我尝试了 iOS 名为 light blue 的本机应用程序,它工作正常,特征值已更新 我只在 Xamarin 表单应用程序中遇到问题。这是我的代码
private async Task<string> ProcessDeviceInformationService(IService deviceInfoService)
{
try
{
await adapter.ConnectToDeviceAsync(device);
var sb = new StringBuilder("Getting information from Device Information service: \n");
var characteristics = deviceInfoService.GetCharacteristicsAsync();
var characteristic = await deviceInfoService.GetCharacteristicAsync(Guid.Parse("00002a2b-0000-1000-8000-00805F9B34FB"));
try
{
if (characteristic != null)
{
var sbnew = new StringBuilder("BLE Characteristics\n");
byte[] senddata = Encoding.UTF8.GetBytes(string.IsNullOrEmpty(SendMessageLabel.Text) ? "12" : SendMessageLabel.Text);
characteristic.ValueUpdated += (o, args) =>
{
var bytes = characteristic.Value;
};
await characteristic.WriteAsync(senddata);
string str = Encoding.UTF8.GetString(senddata);
sbnew.AppendLine($"Characteristics found on this device: {string.Join(", ", str.ToString())}");
CharactericsLabel.Text = sbnew.ToString();
}
}
catch (Exception ex)
{
//return ex.Message;
DisplayAlert("Notice", ex.Message.ToString(), "OK");
}
我试过延迟,我也试过在没有外围设备响应的情况下写入,但它不起作用。这是我的外设代码
// Current Time characteristic
BluetoothGattCharacteristic currentTime = new BluetoothGattCharacteristic(CURRENT_TIME,
//Read-only characteristic, supports notifications
BluetoothGattCharacteristic.PROPERTY_READ | BluetoothGattCharacteristic.PROPERTY_NOTIFY | BluetoothGattCharacteristic.PROPERTY_WRITE_NO_RESPONSE,
BluetoothGattCharacteristic.PERMISSION_READ | BluetoothGattCharacteristic.PROPERTY_WRITE);
BluetoothGattDescriptor configDescriptor = new BluetoothGattDescriptor(CLIENT_CONFIG,
//Read/write descriptor
BluetoothGattDescriptor.PERMISSION_READ | BluetoothGattDescriptor.PERMISSION_WRITE);
currentTime.addDescriptor(configDescriptor);
// Local Time Information characteristic
BluetoothGattCharacteristic localTime = new BluetoothGattCharacteristic(LOCAL_TIME_INFO,
//Read-only characteristic
BluetoothGattCharacteristic.PROPERTY_READ,
BluetoothGattCharacteristic.PERMISSION_READ);
BluetoothGattCharacteristic sampleText = new BluetoothGattCharacteristic sampleText = new BluetoothGattCharacteristic(SAMPLE_TEXT,
//Read-only characteristic
BluetoothGattCharacteristic.PROPERTY_WRITE_NO_RESPONSE | BluetoothGattCharacteristic.PROPERTY_READ | BluetoothGattCharacteristic.PROPERTY_NOTIFY,
BluetoothGattCharacteristic.PERMISSION_WRITE | BluetoothGattCharacteristic.PERMISSION_READ);
我不知道如何解决这个问题 suggestions.I 甚至 Semaphore 都试过了,但它没有帮助,正如您在我的代码中看到的那样
private static async Task<string> WriteAndWaitForResponseAsync(
ICharacteristic characteristic,
byte[] senddata)
{
var semaphore = new SemaphoreSlim(0, 1);
string result = null;
characteristic.ValueUpdated += (o, args) =>
{
var bytes = characteristic.Value;
result = Encoding.UTF8.GetString(bytes); // Note I don't know if this is your intended behaviour with the values you get back, you can decide what to actually do with the response.
// Notify a value has been received.
semaphore.Release();
};
await characteristic.WriteAsync(senddata,new CancellationToken(true)).ConfigureAwait(false);
// Wait until we receive a notification.
await semaphore.WaitAsync(); // I strongly suggest you look in to CancellationTokens but I am not going in to that now.
return result;
}
我怀疑线程是这里问题的一部分,您订阅了事件,调用了 WriteAsync
,但最终在收到 data/event 之前就离开了该方法。我建议您需要在收到数据之前尝试阻止该方法离开。
试试这样的东西:
private static async Task<string> WriteAndWaitForResponseAsync(
ICharacteristic characteristic,
byte[] senddata)
{
var semaphore = new SemaphoreSlim(0, 1);
string result = null;
characteristic.ValueUpdated += (o, args) =>
{
// Make sure you read from the new value in event not the existing characteristic.
var bytes = args.Characteristic.Value;
result = Encoding.UTF8.GetString(bytes); // Note I don't know if this is your intended behaviour with the values you get back, you can decide what to actually do with the response.
// Notify a value has been received.
semaphore.Release();
};
await characteristic.WriteAsync(senddata);
// Wait until we receive a notification.
await semaphore.WaitAsync(); // I strongly suggest you look in to CancellationTokens but I am not going in to that now.
return result;
}
然后您可以从当前方法中调用此方法,例如:
string str = await WriteAndWaitForResponseAsync(characteristic, senddata);