Android BLE - 阅读Characaricts

时间:2014-03-17 18:05:50

标签: android bluetooth bluetooth-lowenergy android-4.3-jelly-bean

我建立一个连接到cutom硬件的BLE ap。 我正在使用三星Galaxy S3,Android版本4.3进行测试。 我已成功连接到远程设备,并能够列出所有设备的服务。 问题是我似乎无法阅读任何服务的Characaricts。 这是displayGattServices函数的代码(直接取自Google的示例代码) -

// Demonstrates how to iterate through the supported GATT Services/Characteristics.
// In this sample, we populate the data structure that is bound to the ExpandableListView
// on the UI.
private void displayGattServices(List<BluetoothGattService> gattServices) {
    if (gattServices == null) return;
    String uuid = null;
    String unknownServiceString = getResources().getString(R.string.unknown_service);
    String unknownCharaString = getResources().getString(R.string.unknown_characteristic);
    ArrayList<HashMap<String, String>> gattServiceData = new ArrayList<HashMap<String, String>>();
    ArrayList<ArrayList<HashMap<String, String>>> gattCharacteristicData
            = new ArrayList<ArrayList<HashMap<String, String>>>();
    mGattCharacteristics = new ArrayList<ArrayList<BluetoothGattCharacteristic>>();

    // Loops through available GATT Services.
    for (BluetoothGattService gattService : gattServices) {
        HashMap<String, String> currentServiceData = new HashMap<String, String>();
        uuid = gattService.getUuid().toString();
        currentServiceData.put(
                LIST_NAME, SampleGattAttributes.lookup(uuid, unknownServiceString));
        currentServiceData.put(LIST_UUID, uuid);
        gattServiceData.add(currentServiceData);

        ArrayList<HashMap<String, String>> gattCharacteristicGroupData =
                new ArrayList<HashMap<String, String>>();
        List<BluetoothGattCharacteristic> gattCharacteristics =
                gattService.getCharacteristics();
        ArrayList<BluetoothGattCharacteristic> charas =
                new ArrayList<BluetoothGattCharacteristic>();

        // Loops through available Characteristics.
 for (BluetoothGattCharacteristic gattCharacteristic : gattCharacteristics) {
            charas.add(gattCharacteristic);
            HashMap<String, String> currentCharaData = new HashMap<String, String>();
            uuid = gattCharacteristic.getUuid().toString();
            currentCharaData.put(
                    LIST_NAME, SampleGattAttributes.lookup(uuid, unknownCharaString));
            currentCharaData.put(LIST_UUID, uuid);
            gattCharacteristicGroupData.add(currentCharaData);
        }
        mGattCharacteristics.add(charas);
        gattCharacteristicData.add(gattCharacteristicGroupData);
    }

    SimpleExpandableListAdapter gattServiceAdapter = new SimpleExpandableListAdapter(
            this,
            gattServiceData,
            android.R.layout.simple_expandable_list_item_2,
            new String[] {LIST_NAME, LIST_UUID},
            new int[] { android.R.id.text1, android.R.id.text2 },
            gattCharacteristicData,
            android.R.layout.simple_expandable_list_item_2,
            new String[] {LIST_NAME, LIST_UUID},
            new int[] { android.R.id.text1, android.R.id.text2 }
    );
    mGattServicesList.setAdapter(gattServiceAdapter);
}

这是服务代码 -

   private void broadcastUpdate(final String action,
                             final BluetoothGattCharacteristic characteristic) {
    final Intent intent = new Intent(action);

    // This is special handling for the Heart Rate Measurement profile.  Data parsing is
    // carried out as per profile specifications:
    // http://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.heart_rate_measurement.xml
    if (UUID_HEART_RATE_MEASUREMENT.equals(characteristic.getUuid())) {
        int flag = characteristic.getProperties();
        int format = -1;
        if ((flag & 0x01) != 0) {
            format = BluetoothGattCharacteristic.FORMAT_UINT16;
            Log.d(TAG, "Heart rate format UINT16.");
        } else {
            format = BluetoothGattCharacteristic.FORMAT_UINT8;
            Log.d(TAG, "Heart rate format UINT8.");
        }
        final int heartRate = characteristic.getIntValue(format, 1);
        Log.d(TAG, String.format("Received heart rate: %d", heartRate));
        intent.putExtra(EXTRA_DATA, String.valueOf(heartRate));
    } else {
        // For all other profiles, writes the data formatted in HEX.
        final byte[] data = characteristic.getValue();
        if (data != null && data.length > 0) {
            final StringBuilder stringBuilder = new StringBuilder(data.length);
            for(byte byteChar : data)
                stringBuilder.append(String.format("%02X ", byteChar));
            intent.putExtra(EXTRA_DATA, new String(data) + "\n" + stringBuilder.toString());
        }
    }
    sendBroadcast(intent);
}


    @Override
    public void onCharacteristicRead(BluetoothGatt gatt,
                                     BluetoothGattCharacteristic characteristic,
                                     int status) {
        if (status == BluetoothGatt.GATT_SUCCESS) {
            broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic);
        }
    }

    @Override
    public void onCharacteristicChanged(BluetoothGatt gatt,
                                        BluetoothGattCharacteristic characteristic) {
        broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic);
    }
};

每当我尝试检索Characaricts时,gattService.getCharacteristics()都会返回一个空列表。 我做得对吗,问题出在硬件上,还是我错过了什么?

由于

2 个答案:

答案 0 :(得分:0)

  

每当我尝试检索Characaricts时,gattService.getCharacteristics()都会返回一个空列表。

您收到空列表,因为支持BLE芯片的远程设备不支持任何特性。

  

问题是硬件

这对Galaxy S3设备没有问题,实际问题是支持BLE芯片的远程设备(固件端),如Galaxy Gear ......如果Galaxy Gear设备不支持任何特性,你的Galaxy S3将无法找到任何特征。

p / s:您从示例代码获取的编码是好​​的。适合我。

答案 1 :(得分:0)

您的代码似乎是正确的。

有两个可能的原因,为什么你看不到特征:

1)硬件不支持任何特性。测试这个的最好方法是安装一些允许你探索BLE设备的扫描应用程序。 (有很多可用的Andorid,例如SensorTag,也可以扫描其他设备),甚至更好用于iOS,其中BLE堆栈更稳定。

2)Andorid BLE堆栈不是完全稳定的(正如许多线程中所讨论的那样) - 你做了一些事情,它在内部崩溃了,而出路就是尝试禁用并启用BT,如果这没有帮助,重启设备。但在这种情况下,这是不可能的,因为你可以看到服务。