使用Android Studio的蓝牙LE:使用按钮写入特征

时间:2015-12-04 18:16:37

标签: android-studio bluetooth-lowenergy

我是Android和蓝牙新手并且遇到了这个问题。

如果触摸了两个按钮,我想写一个特定的特征。 如果我触摸第一个按钮,0-9之间的数字应该计为+1。使用另一个按钮时,数字应减少为-1。 作为一个基础,我使用了谷歌的BluetootleGatt示例应用程序。 在DeviceControlActivity中,我更改了以下代码:

private final ExpandableListView.OnChildClickListener servicesListClickListner =
        new ExpandableListView.OnChildClickListener() {
            @Override
            public boolean onChildClick(ExpandableListView parent, View v, int groupPosition,
                                        int childPosition, long id) {
                if (mGattCharacteristics != null) {
                    final BluetoothGattCharacteristic characteristic =
                            mGattCharacteristics.get(groupPosition).get(childPosition);
                    final int charaProp = characteristic.getProperties();  //The properties contain a bit mask of property flags indicating
                   //the features of this characteristic.
                   if ((charaProp | BluetoothGattCharacteristic.PROPERTY_READ) > 0) {
                        // If there is an active notification on a characteristic, clear
                        // it first so it doesn't update the data field on the user interface.
                        if (mNotifyCharacteristic != null) {
                            mBluetoothLeService.setCharacteristicNotification(
                                    mNotifyCharacteristic, false);
                            mNotifyCharacteristic = null;
                        }
                      mBluetoothLeService.readCharacteristic(characteristic);
                    }
                    if ((charaProp | BluetoothGattCharacteristic.PROPERTY_NOTIFY ) > 0) {

                        mNotifyCharacteristic = characteristic;
                        mBluetoothLeService.setCharacteristicNotification(
                                characteristic, true);
                    }

                    if ((charaProp | BluetoothGattCharacteristic.PROPERTY_WRITE) > 0) {
                        characteristic.setWriteType(BluetoothGattCharacteristic.PERMISSION_WRITE);
                        addListenerOnButton();

                    }

                    return true;
                }
                return false;
            }
};

这是两个按钮的addListenerOnButton():

public void addListenerOnButton() {

    mArrowUp = (ImageButton) findViewById(R.id.arrow_up);
    mArrowUp.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View arg0) {
          mBluetoothLeService.writeCharacteristicUp();

        }

    });

    mArrowDown = (ImageButton) findViewById(R.id.arrow_down);
    mArrowDown.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View arg0) {
        mBluetoothLeService.writeCharacteristicDown();
        }

    });

}

他们将调用BluetoothLeService-Class中的两个writeCharacteristic方法。例如,我在这里只发布了writeCharacteristicUp() - 方法:

public boolean writeCharacteristicUp() {

    //check mBluetoothGatt is available
    if (mBluetoothGatt == null) {
        Log.e(TAG, "lost connection");
        return false;
    }
    BluetoothGattService Service = mBluetoothGatt.getService(UUID_DO_LOGGER_TEST);
    if (Service == null) {
        Log.e(TAG, "service not found!");
        return false;
    }
    BluetoothGattCharacteristic charac = Service
            .getCharacteristic(UUID_TEST_NUMBER);
    if (charac == null) {
        Log.e(TAG, "char not found!");
        return false;
    }

    byte[] value0 = new byte[1];
    value0[0] = (byte) 0;   //Constant of 0 for comparison later
    byte[] value1 = new byte[1];
    value1[0] = (byte) 1;  //Constant of 1 for comparison later
    byte[] value2 = new byte[1];
    value2[0] = (byte) 2;  //Constant of 1 for comparison later
    byte[] value3 = new byte[1];
    value3[0] = (byte) 3;  //Constant of 1 for comparison later
    byte[] value4 = new byte[1];
    value4[0] = (byte) 4;  //Constant of 1 for comparison later
    byte[] value5 = new byte[1];
    value5[0] = (byte) 5;  //Constant of 1 for comparison later
    byte[] value6 = new byte[1];
    value6[0] = (byte) 6;  //Constant of 1 for comparison later
    byte[] value7 = new byte[1];
    value7[0] = (byte) 7;  //Constant of 1 for comparison later
    byte[] value8 = new byte[1];
    value8[0] = (byte) 8;  //Constant of 1 for comparison later
    byte[] value9 = new byte[1];
    value9[0] = (byte) 9;  //Constant of 1 for comparison later

    byte[] actualvalue = charac.getValue();

    if (actualvalue == value0) {
        charac.setValue(value1);
    }
    if (actualvalue == value1) {
        charac.setValue(value2);
    }
    if (actualvalue == value2) {
        charac.setValue(value3);
    }
    if (actualvalue == value3) {
        charac.setValue(value4);
    }
    if (actualvalue == value4) {
        charac.setValue(value5);
    }
    if (actualvalue == value5) {
        charac.setValue(value6);
    }
    if (actualvalue == value6) {
        charac.setValue(value7);
    }
    if (actualvalue == value7) {
        charac.setValue(value8);
    }
    if (actualvalue == value8) {
        charac.setValue(value9);
    }
    if (actualvalue == value9) {
        charac.setValue(value0);
    } 
  //  charac.setValue(value0);
  //  byte[] actualvaluenew1 = charac.getValue();
    boolean status = mBluetoothGatt.writeCharacteristic(charac);
  //  byte[] actualvaluenew2 = charac.getValue();
    return status;
}

问题在于

boolean status = mBluetoothGatt.writeCharacteristic(charac)  

不起作用,状态为false。因此,实际值不会显示在相应TextView的屏幕上。为什么? 另外我发现if-grinds没有工作,因为charac.setValue(value0)只在if-grinds之外工作?

1 个答案:

答案 0 :(得分:0)

我建议您按住 control 键并单击代码中的BluetoothGatt#writeCharacteristic(ch)功能。然后Android Studio将查看BluetoothGatt#writeCharacteristic(BluetoothGattCharacteristic characteristic)功能:

    public boolean writeCharacteristic(BluetoothGattCharacteristic characteristic) {
    if ((characteristic.getProperties() & BluetoothGattCharacteristic.PROPERTY_WRITE) == 0
        && (characteristic.getProperties() &
            BluetoothGattCharacteristic.PROPERTY_WRITE_NO_RESPONSE) == 0) return false;

    if (VDBG) Log.d(TAG, "writeCharacteristic() - uuid: " + characteristic.getUuid());
    if (mService == null || mClientIf == 0 || characteristic.getValue() == null) return false;

    BluetoothGattService service = characteristic.getService();
    if (service == null) return false;

    BluetoothDevice device = service.getDevice();
    if (device == null) return false;

    synchronized(mDeviceBusy) {
        if (mDeviceBusy) return false;
        mDeviceBusy = true;
    }

    try {
        mService.writeCharacteristic(mClientIf, device.getAddress(),
            service.getType(), service.getInstanceId(),
            new ParcelUuid(service.getUuid()), characteristic.getInstanceId(),
            new ParcelUuid(characteristic.getUuid()),
            characteristic.getWriteType(), AUTHENTICATION_NONE,
            characteristic.getValue());
    } catch (RemoteException e) {
        Log.e(TAG,"",e);
        mDeviceBusy = false;
        return false;
    }

    return true;
}

在方法中放置一个断点并进行调试。以下是您根据源代码获取false的可能原因:

  1. 远程BLE设备没有 Write Write with No Response access
  2. 您的服务为空或您设置的特征值为空
  3. 您的设备已在使用远程设备执行另一个BLE流程
  4. 在我看来,最有可能的第二项是原因。