在Android

时间:2016-10-14 07:20:43

标签: android bluetooth bluetooth-lowenergy

我的设备信息

  1. 北欧董事会:

    • MTU大小:247。
    • 此板在一个连接间隔内发送通知多个数据包(只是计数器值,如1,2,3,4 ...),在#34;心率测量"。
  2. Android设备:

    • 版本5.0和6.0。 (使用两个设备)。
    • 与电路板通信蓝牙低功耗(BLE)。
    • 与我的Android应用程序连接的板MTU设置为244。
    • 应用程序源是Google示例项目BluetoothLeGatt
    • 应用程序发送通知值为"心率服务"特性
    • 在Gattcallback接收通知值" onCharacteristicChanged()"
  3. 问题

    • 我的Android应用程序丢失了一些数据包。
  4. 我读过这篇文章。 Maximizing BLE Throughput on iOS and Android。所以我发送了这封邮件作者的电子邮件,我搜索了Android的其他信息。

    我发现了一些类似的问题。但那个问题的答案并不奏效。然后我发现了一个我想要的问题。但这个问题没有答案。 Android receiving multiple BLE packets per connection interval。不幸的是,我没有回复电子邮件的答案。

    我的问题是如何设置Android BLE通知。 (不是北欧板设置) (我的问题是Android receiving multiple BLE packets per connection interval

    在线下是我的示例代码。在通知。

    @Connect

    public boolean connect(final String address) {
        if (mBluetoothAdapter == null || address == null) {
            Log.w(TAG, "BluetoothAdapter not initialized or unspecified address.");
            return false;
        }
    
        // Previously connected device.  Try to reconnect.
        if (mBluetoothDeviceAddress != null && address.equals(mBluetoothDeviceAddress) && mBluetoothGatt != null) {
            Log.d(TAG, "Trying to use an existing mBluetoothGatt for connection.");
            if (mBluetoothGatt.connect()) {
                mConnectionState = STATE_CONNECTING;
                return true;
            } else {
                return false;
            }
        }
    
        final BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address);
        if (device == null) {
            Log.w(TAG, "Device not found.  Unable to connect.");
            return false;
        }
    
        // We want to directly connect to the device, so we are setting the autoConnect
        // parameter to false.
        mBluetoothGatt = device.connectGatt(this, false, mGattCallback);
    
        Log.d(TAG, "Trying to create a new connection.");
        mBluetoothDeviceAddress = address;
        mConnectionState = STATE_CONNECTING;
        return true;
    }
    

    @GattCallback

      /*broadcastUpdate method is display value*/
     @Override
        public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
    
            if (newState == BluetoothProfile.STATE_CONNECTED) {
                mConnectionState = STATE_CONNECTED;
                // Attempts to discover services after successful connection.
                Log.i(TAG, "Attempting to start service discovery:");
                mBluetoothGatt.discoverServices();
    
            } else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
                Log.i(TAG, "Disconnected from GATT server.");
                mConnectionState = STATE_DISCONNECTED;
                broadcastUpdate(ACTION_GATT_DISCONNECTED);
            }
        }
    
        @Override
        public void onServicesDiscovered(BluetoothGatt gatt, int status) {
            if (status == BluetoothGatt.GATT_SUCCESS) {
                Log.d(TAG, "onServicesDiscovered success: (status)" + status);
                //findServiceOther(gatt);
                broadcastUpdate(ACTION_GATT_SERVICES_DISCOVERED);
                Log.d(TAG, "Request MTU");
                gatt.requestMtu(SET_MTU);
            } else {
                Log.w(TAG, "onServicesDiscovered failed: (status)" + status);
            }
        }
    
        @Override
        public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
            if (status == BluetoothGatt.GATT_SUCCESS) {
                Log.d(TAG, "onCharRead Success");
                broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic);
            } else {
                Log.d(TAG, "OnCharRead Error: " + status);
            }
        }
    
        @Override
        public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
            if (characteristic.getUuid().equals(SampleGattAttributes.UUID_HEART_RATE_MEASUREMENT))
                broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic, FLAG_HEART_RATE);
            else
                broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic);
        }
    
        @Override
        public void onMtuChanged(BluetoothGatt gatt, int mtu, int status) {
            super.onMtuChanged(gatt, mtu, status);
            boolean priority = gatt.requestConnectionPriority(BluetoothGatt.CONNECTION_PRIORITY_HIGH);
            Log.d(TAG, "MTU changed (mtu/status) / Priority : (" + mtu + "/" + status + ") / " + priority);
            changed_MTU_Size = mtu;
            broadcastUpdate(ACTION_DATA_AVAILABLE, changed_MTU_Size, FLAG_MTU);
            broadcastUpdate(ACTION_GATT_CONNECTED);
        }
    

    @set notification

    public void setCharacteristicNotification(BluetoothGattCharacteristic characteristic, boolean enabled) {
        if (mBluetoothAdapter == null || mBluetoothGatt == null) {
            Log.w(TAG, "BluetoothAdapter not initialized");
            return;
        }
    
        mBluetoothGatt.setCharacteristicNotification(characteristic, enabled);
    
        if (SampleGattAttributes.UUID_HEART_RATE_MEASUREMENT.equals(characteristic.getUuid())) {
            // This is specific to Heart Rate Measurement.
            BluetoothGattDescriptor descriptor = characteristic.getDescriptor(SampleGattAttributes.UUID_CLIENT_CHARACTERISTIC_CONFIG);
            descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
            mBluetoothGatt.writeDescriptor(descriptor);
        }
    }
    

    Edit_1

    我在Google Play商店测试Nordic官方应用。 nRF Connect for Mobile 但这个应用程序也错过了包。

    Edit_2

    我也发现了一些问题。

    <北欧板常数设置>

    • HEART_RATE_MEAS_INTERVAL:10
    • MIN_CONN_INTERVAL:MSEC_TO_UNITS(40,UNIT_1_25_MS)
    • MAX_CONN_INTERVAL:MSEC_TO_UNITS(40,UNIT_1_25_MS)
    • SLAVE_LATENCY 0
    • CONN_SUP_TIMEOUT MSEC_TO_UNITS(4000,UNIT_10_MS)

    <在我的Android应用中运行>

    • 跳过requestMTU:成功接收20byte数据包。 (我的应用程序的数据速率平均为2200byte /秒)

    • requestMTU:我尝试了很多MTU大小(例如:23(可以是小尺寸),40,100,255(目标)......)但丢失了一些数据包(数据速率8500~9500字节/秒)我的应用程序)

    我想知道requestMTU和通知会收到相互关系。

1 个答案:

答案 0 :(得分:1)

我已经使用Nordic UART服务在nrf51422和SD310上通过LE实现了文件传输。 Android应用程序是使用Qt和QtBluetooth库在CPP中编写的。因此,这个回答我的确不能帮到你。但是,我已经花了一些钱来获得可用的数据速率。 1,将连接参数设置为7.5ms(min)和15ms(max)。 2,在外围设备端,我发送最多7个数据包(直到缓冲区已满)。因此,外设每个连接事件最多发送7个数据包。 在Android方面,charachteritic更改事件频繁到达我的数据大小为20字节(由于最大MTU大小23,北欧uart服务使用3个字节),我立即读取数据。 也许你的错误是MTU大小为244.默认的BLE MTU大小为23(核心规范4.1)。

此致