Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/188.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在android中通过ble发送超过20字节的数据?_Android_Bluetooth - Fatal编程技术网

如何在android中通过ble发送超过20字节的数据?

如何在android中通过ble发送超过20字节的数据?,android,bluetooth,Android,Bluetooth,我正在尝试使用简单循环发送超过33字节的数据,有人知道如何通过android ble发送超过20字节的数据吗 if(!mConnected) return; for (int i = 0; i<str.length;i++) { if(str[i] == str[str.length -1]){ val = str[i]+"\n"; }else { val =

我正在尝试使用简单循环发送超过33字节的数据,有人知道如何通过android ble发送超过20字节的数据吗

if(!mConnected) return;
        for (int i = 0; i<str.length;i++) {
            if(str[i] == str[str.length -1]){
                 val = str[i]+"\n";
            }else {
                val = str[i] + "_";
            }
            System.out.println(val);
            mBluetoothLeService.WriteValue(val);
        }
如果(!mConnected)返回;

对于(int i=0;i通过BLE发送超过20个字节的数据很容易实现,方法是将数据拆分为20个字节的数据包,并在发送每个数据包之间实现一个短延迟(即使用
sleep()

下面是我正在处理的一个项目中的一小段代码,它以
字节[]
的形式获取数据,并将其拆分为相同的数组(
字节[][]
),分成20个字节块,然后将其发送到另一个方法,该方法逐个传输每个数据包

    int chunksize = 20;
    byte[][] packets = new byte[packetsToSend][chunksize]; 
    int packetsToSend = (int) Math.ceil( byteCount / chunksize);

    for(int i = 0; i < packets.length; i++) {
        packets[i] = Arrays.copyOfRange(source,start, start + chunksize);
        start += chunksize;
    }

    sendSplitPackets(packets);
int chunksize=20;
字节[][]数据包=新字节[packetsToSend][chunksize];
int packetsToSend=(int)Math.ceil(字节数/chunksize);
对于(int i=0;i
以下是关于如何实现这一点的另外两个非常好的解释:


一些嵌入式蓝牙LE实现将特征的大小限制为20字节。我知道Laird BL600系列会这样做。这是Laird模块的限制,即使BLE规范要求最大长度更长。其他嵌入式BLE解决方案也有类似的限制。我怀疑这就是您所面临的限制遇到。

我没有对每个块使用睡眠,而是找到了一种更好、更有效的方法,让我的应用程序发送超过20位的数据

数据包将在触发onCharacteristicWrite()后发送。我刚刚发现此方法将在外围设备(BluetoothGattServer)发送sendResponse()方法后自动触发

首先,我们必须使用此功能将数据包数据转换为数据块:

public void sendData(byte [] data){
    int chunksize = 20; //20 byte chunk
    packetSize = (int) Math.ceil( data.length / (double)chunksize); //make this variable public so we can access it on the other function

    //this is use as header, so peripheral device know ho much packet will be received.
    characteristicData.setValue(packetSize.toString().getBytes());
    mGatt.writeCharacteristic(characteristicData);
    mGatt.executeReliableWrite();

    packets = new byte[packetSize][chunksize];
    packetInteration =0;
    Integer start = 0;
    for(int i = 0; i < packets.length; i++) {
        int end = start+chunksize;
        if(end>data.length){end = data.length;}
        packets[i] = Arrays.copyOfRange(data,start, end);
        start += chunksize;
    }
@Override
    public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
        if(packetInteration<packetSize){
        characteristicData.setValue(packets[packetInteration]);
        mGatt.writeCharacteristic(characteristicData);
            packetInteration++;
        }
    }
public void sendData(字节[]数据){
int chunksize=20;//20字节块
packetSize=(int)Math.ceil(data.length/(double)chunksize);//将此变量公开,以便我们可以在另一个函数上访问它
//这被用作报头,所以外围设备知道将接收多少数据包。
characteristicData.setValue(packetSize.toString().getBytes());
mGatt.writeCharacteristic(特征数据);
mGatt.executeLabelWrite();
packets=新字节[packetSize][chunksize];
packetinteraction=0;
整数起始=0;
对于(int i=0;idata.length){end=data.length;}
packets[i]=Arrays.copyOfRange(数据、开始、结束);
开始+=块大小;
}
数据准备好后,我将迭代放在这个函数上:

public void sendData(byte [] data){
    int chunksize = 20; //20 byte chunk
    packetSize = (int) Math.ceil( data.length / (double)chunksize); //make this variable public so we can access it on the other function

    //this is use as header, so peripheral device know ho much packet will be received.
    characteristicData.setValue(packetSize.toString().getBytes());
    mGatt.writeCharacteristic(characteristicData);
    mGatt.executeReliableWrite();

    packets = new byte[packetSize][chunksize];
    packetInteration =0;
    Integer start = 0;
    for(int i = 0; i < packets.length; i++) {
        int end = start+chunksize;
        if(end>data.length){end = data.length;}
        packets[i] = Arrays.copyOfRange(data,start, end);
        start += chunksize;
    }
@Override
    public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
        if(packetInteration<packetSize){
        characteristicData.setValue(packets[packetInteration]);
        mGatt.writeCharacteristic(characteristicData);
            packetInteration++;
        }
    }
@覆盖
特征写入的公共无效(蓝牙gatt、蓝牙gatt特征特征、int状态){

如果(packetinteraction,您可以发送超过20字节的数据,而无需分块并包含延迟。您尝试写入的每个特征都有一个MTU值。它是您一次可以写入的字节数。 在连接过程中,MTU值被交换,您可以一次写入这么多字节。您可以在服务器端增加MTU值(最大512字节),然后一次性发送这么多字节

对于Android,您可能希望在使用连接服务器后手动请求mtu

请求mtu(int mtu)

这是根据您发送的mtu值返回true或false。它将向ONMTU发出回调,其中Android设备和服务器协商最大可能mtu值

ONMTU变更(蓝牙gatt、国际mtu、国际状态)


你可以在这个函数中设置MTU值,一次可以发送超过20个字节。

活动启动后,我必须重复发送数据。如果有更改或没有更改,我必须发送。因此,有时我的数据相互重叠,破坏了我的功能。我不完全理解你遇到的问题,但我会怎么做ld建议确保(1)在数据包之间实现短延迟,(2)发送初始“头”数据包,告诉您的方法预期的总数据包数,并使用递增计数器确保收到正确的数据包数。如果您能进一步解释一下您的用例,我可能会提供更详细的建议。您是否知道如何在整个android应用程序中维护已建立的蓝牙连接。现在我是estab在应用程序的每个活动中建立新的连接。如果我发送多个20字节的数据块,我会收到timedout错误。我最多可以发送30-35字节。请帮助。数据的目的地也是Android设备吗?不是,它是自定义的BLE外围设备。好的。在我的测试中,Android会向iOS外围设备发送超过20字节的数据,所以可能这取决于外围设备的类型。但是,默认情况下,它将仅从iOS外围设备接收20个字节。