android - 文字量大如何写出特色

标签 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);

我在写入特性的一侧的代码:

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);
    }
}

在接受写入请求的一侧:

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"));
    }
}

我看到有一个 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);
    }
}

最佳答案

原因是您使用 GattProperty.WriteNoResponse 而不是 GattProperty.Write。对于无响应属性变体,客户端只能使用受 MTU 限制的“Write without response”ATT 命令。对于正常的 Write 属性变体,客户端可以使用“Write with response”ATT 请求以及多个准备写入和执行写入的序列,也称为“长写入”。对于长写入,客户端(自动)将写入拆分为具有偏移量的不同 block 。请注意,由于需要多次往返,长写入比仅增加 MTU 花费的时间要多得多。

关于android - 文字量大如何写出特色,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55749934/

相关文章:

android - 如何从android中的视频中获取帧数?

android - 无法删除 CardView 项目之间的额外空间 - 可滚动的 RecyclerView

xamarin.android - 我需要在每个 Activity 的 OnCreate 中启动 AppCenter 还是仅在第一个?

ios - 如何在后台定期将数据发送到 IOS (swift) 应用程序上的 BLE 外围设备?

android - StickNFind 蓝牙 GATT 配置文件

android - 无法通过低功耗蓝牙发现服务和特征 - BLE

android - Firebase 动态链接生成器中的 DFL 参数

java - RecyclerView水平滚动到左侧

android - 将 View 添加到不带 XML 的 View

android - Webview 显示 Assets 中的图像