Dar*_*ius 7 android xamarin.android bluetooth-lowenergy
我正在使用 Xamarin.Android 编写一个 Android 应用程序,但是本机 Android 中的答案也将受到赞赏。在我的 Android 应用程序中,我有一个设备可以写入的 BLE 写入特性。它可以工作,但我无法发送超过 20 个字节,其余的会被切断。我用于创建和添加服务/特性的代码:
BluetoothGattService service = new BluetoothGattService(Java.Util.UUID.FromString(MyServiceUuid), GattServiceType.Primary);
// write characteristic (write-only, supports subscriptions)
BluetoothGattCharacteristic writeCharacteristic = new BluetoothGattCharacteristic(Java.Util.UUID.FromString(MyCharacteristicUuid), GattProperty.WriteNoResponse | GattProperty.Notify, GattPermission.Write);
service.AddCharacteristic(writeCharacteristic);
_bluetoothGattServer.AddService(service);
Run Code Online (Sandbox Code Playgroud)
我在写入特征的一侧的代码:
public override void OnServicesDiscovered(BluetoothGatt gatt, [GeneratedEnum] GattStatus status)
{
base.OnServicesDiscovered(gatt, status);
characteristic = gatt.GetService(Java.Util.UUID.FromString(MyServiceUuid))
.GetCharacteristic(Java.Util.UUID.FromString(MyCharacteristicUuid));
if(characteristic.Properties.HasFlag(GattProperty.WriteNoResponse))
{
Log?.Invoke("writing characteristic...");
characteristic.SetValue(MyVeryLongString);
characteristic.WriteType = GattWriteType.NoResponse;
gatt.WriteCharacteristic(characteristic);
}
}
Run Code Online (Sandbox Code Playgroud)
在接受写入请求的一侧:
public override void OnCharacteristicWriteRequest(BluetoothDevice device, int requestId, BluetoothGattCharacteristic characteristic, bool preparedWrite, bool responseNeeded, int offset, byte[] value)
{
base.OnCharacteristicWriteRequest(device, requestId, characteristic, preparedWrite, responseNeeded, offset, value);
Log?.Invoke("OnCharacteristicWriteRequest");
string data = System.Text.Encoding.UTF8.GetString(value);
Log?.Invoke(data);
if(responseNeeded)
{
BluetoothGattServer.SendResponse(device, requestId, GattStatus.Success, 0, Encoding.ASCII.GetBytes("ok"));
}
}
Run Code Online (Sandbox Code Playgroud)
我看到有一个offset,但这个函数只被调用一次。我一定是在一侧遗漏了一些东西?
有趣的是,当我用我的应用程序的 iOS 版本测试这个 Android 应用程序时,我没有遇到这个问题。仅当两台设备都是 Android 时我才会遇到此问题。
编辑
我的新实现OnCharacteristicWriteRequest:
public override void OnCharacteristicWriteRequest(BluetoothDevice device, int requestId, BluetoothGattCharacteristic characteristic, bool preparedWrite, bool responseNeeded, int offset, byte[] value)
{
base.OnCharacteristicWriteRequest(device, requestId, characteristic, preparedWrite, responseNeeded, offset, value);
Log?.Invoke("OnCharacteristicWriteRequest");
string data = System.Text.Encoding.UTF8.GetString(value);
Log?.Invoke(data);
Guid characteristicId = new Guid(characteristic.Uuid.ToString());
var record = _writeCharacteristicsReceived.FirstOrDefault(c => c.DeviceAddress == device.Address && c.CharacteristicId == characteristicId);
if(record != null)
{
record.Data += data;
}
else
{
record = new CharacteristicWriteReceived()
{
CharacteristicId = characteristicId,
DeviceAddress = device.Address,
Data = data
};
_writeCharacteristicsReceived.Add(record);
}
if (record?.Data.EndsWith(Constants.WriteCharacteristicEndDelimiter) == true)
{
_writeCharacteristicsReceived.Remove(record);
record.Data = record.Data.Substring(0, record.Data.Length - Constants.WriteCharacteristicEndDelimiter.Length); // remove the end delimeter
Log?.Invoke(record.Data);
OnCharacteristicWriteReceived?.Invoke(record);
}
if (responseNeeded)
{
BluetoothGattServer.SendResponse(device, requestId, GattStatus.Success, offset, value);
}
}
Run Code Online (Sandbox Code Playgroud)
原因是您使用 GattProperty.WriteNoResponse 而不是 GattProperty.Write。对于无响应属性变体,客户端只能使用“无响应写入”ATT 命令,该命令受 MTU 限制。使用正常的写入属性变体,客户端可以使用“带响应写入”ATT 请求以及执行写入(也称为“长写入”)的多个准备写入序列。对于长写入,客户端(自动)将写入分成带有偏移量的不同块。请注意,由于需要多次往返,长写入比仅增加 MTU 花费的时间要多得多。
| 归档时间: |
|
| 查看次数: |
4870 次 |
| 最近记录: |