首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >蓝牙网关onConnectionState更改在棒棒糖上不起作用

蓝牙网关onConnectionState更改在棒棒糖上不起作用
EN

Stack Overflow用户
提问于 2015-06-25 08:56:05
回答 1查看 4.1K关注 0票数 4

我目前有一种方法,可以写入BLE设备发出蜂鸣音。我的蓝牙回调如下:

代码语言:javascript
复制
public class ReadWriteCharacteristic extends BluetoothGattCallback {
    public ReadWriteCharacteristic(Context context, String macAddress, UUID service, UUID characteristic, Object tag, Activity activity) {
        mMacAddress = macAddress;
        mService = service;
        mCharacteristic = characteristic;
        mTag = tag;
        mContext = context;
        this.activity =activity;
        final BluetoothManager bluetoothManager =
                (BluetoothManager) mContext.getSystemService(Context.BLUETOOTH_SERVICE);
        mBluetoothAdapter = bluetoothManager.getAdapter();

    }

    final private static String TAG = "ReadCharacteristic";
    private Object mTag;
    private String mMacAddress;
    private UUID mService;
    private BluetoothManager mBluetoothManager = null;
    private BluetoothAdapter mBtAdapter = null;
    private BluetoothGatt mBluetoothGatt = null;
    private String mBluetoothDeviceAddress ="";
    private UUID mCharacteristic;
    BluetoothDevice device;
    private Activity activity;
    private BluetoothAdapter mBluetoothAdapter;
    private Context mContext;
    ReadWriteCharacteristic rc;

    private int retry = 5;


    public String getMacAddress() {
        return mMacAddress;
    }

    public UUID getService() {
        return mService;
    }

    public UUID getCharacteristic() {
        return mCharacteristic;
    }

    public byte[] getValue() { return mValue; }

    public void onError() {
        Log.w(TAG, "onError");
    }

    public void readCharacteristic(){
        if (retry == 0)
        {
            onError();
            return;
        }
        retry--;


                device = mBluetoothAdapter.getRemoteDevice(getMacAddress());


                mBluetoothManager = (BluetoothManager) mContext.getSystemService(Context.BLUETOOTH_SERVICE);
                int connectionState = mBluetoothManager.getConnectionState(device,
                        BluetoothProfile.GATT);

                if (device != null) {

                    if (connectionState == BluetoothProfile.STATE_DISCONNECTED)
                    {

                        // Previously connected device. Try to reconnect.
                        if (mBluetoothDeviceAddress != null
                                && getMacAddress().equals(mBluetoothDeviceAddress)
                                && mBluetoothGatt != null) {
                            Log.w(TAG, "Re-use GATT connection");
                            if (mBluetoothGatt.connect()) {
                                Log.w(TAG, "Already connected, discovering services");
                                mBluetoothGatt.discoverServices();
                                //return ;
                            } else {
                                Log.w(TAG, "GATT re-connect failed.");
                                return;
                            }
                        }

                        if (device == null) {
                            Log.w(TAG, "Device not found.  Unable to connect.");
                            return;
                        }
                        Log.w(TAG, "Create a new GATT connection.");
                        rc= ReadWriteCharacteristic.this;
                        Log.w(TAG, "Starting Read [" + getService() + "|" + getCharacteristic() + "]");
                        mBluetoothGatt = device.connectGatt(mContext, false, rc);
                        refreshDeviceCache(mBluetoothGatt);
                        mBluetoothDeviceAddress = getMacAddress();
                    } else {
                        Log.w(TAG, "Attempt to connect in state: " + connectionState);
                        if(mBluetoothGatt!=null)
                            mBluetoothGatt.close();
                        readCharacteristic();
                    }

                }

    }

    @Override
    public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
        super.onConnectionStateChange(gatt, status, newState);

        Log.w(TAG,"onConnectionStateChange [" + status + "|" + newState + "]");


        if ((newState == 2)&&(status ==0)) {
            gatt.discoverServices();
        }
        else if(status == 133 )
        {
            //gatt.disconnect();
            gatt.close();
            mBluetoothGatt = null;
            try
            {
                Thread.sleep(2000);
            }
            catch(Exception e)
            {

            }
            readCharacteristic();
        }
        else{

            if(mBluetoothGatt!=null)
                mBluetoothGatt.close();

           // gatt.close();

            Log.w(TAG, "[" + status + "]");
            //gatt.disconnect();

            try
            {
                Thread.sleep(2000);
            }
            catch(Exception e)
            {

            }
            mBluetoothGatt = null;
            readCharacteristic();
        }
    }



    @Override
    public void onServicesDiscovered(BluetoothGatt gatt, int status) {
        Log.w(TAG,"onServicesDiscovered [" + status + "]");
        BluetoothGattService bgs = gatt.getService(getService());
        if (bgs != null) {
            BluetoothGattCharacteristic bgc = bgs.getCharacteristic(getCharacteristic());
            gatt.readCharacteristic(bgc);
        }
    }

    @Override
    public void onCharacteristicWrite(BluetoothGatt gatt,
                                      BluetoothGattCharacteristic characteristic,
                                      int status) {
        Log.w(TAG,"onCharacteristicWrite [" + status + "]");
        if (status == BluetoothGatt.GATT_SUCCESS) {
            Log.w(TAG,"onCharacteristicWrite [" + getDataHex(characteristic.getValue()) + "]");
           // gatt.disconnect();
            if(mBluetoothGatt!=null)
                mBluetoothGatt.close();
          //  gatt.close();
          //  mBluetoothGatt=null;
        }
        else if(status ==133)
        {
            gatt.close();
            try
            {
                Thread.sleep(2000);
            }
            catch(Exception e)
            {

            }

            readCharacteristic();
        }

        else{
            //gatt.disconnect();
            gatt.close();

        }
    }

    @Override
    public void onCharacteristicRead(BluetoothGatt gatt,
                                     BluetoothGattCharacteristic characteristic,
                                     int status) {
        Log.w(TAG,"onCharacteristicRead [" + status + "]");
        if (status == BluetoothGatt.GATT_SUCCESS) {
            mValue = characteristic.getValue();
            // Perform write operations
            gatt.writeCharacteristic(bgc);


        }

        else if(status ==133)
        {
            gatt.close();
            try
            {
                Thread.sleep(2000);
            }
            catch(Exception e)
            {

            }

            readCharacteristic();
        }

        else {
          //  gatt.disconnect();
            gatt.close();
        }
    }

}

此代码在运行Kitkat及更低版本的设备上运行良好。但在运行棒棒糖的设备上,这段代码在第一个实例中工作得很好。但从下一个实例来看,无论我是断开连接还是关闭连接并重试,它都不起作用。在onConnectionStateChange方法中,它一直给我一个257的状态码。据我所知,对于kitkat和Lollipop设备,蓝牙GATT方法是相同的。

让我惊讶的是,当我使用旧的BLE API时,这个代码在棒棒糖设备上运行得很好,即startLeScan (用于eg - mBluetoothAdapter.startLeScan(mLeScanCallback);)。只有当我使用新的BLE,即BluetoothLeScanner ( scanner.startScan(filters, settings, new scancallback());)时,才会出现这个问题。使用旧的BLE API的棒棒糖设备的扫描速度真的很慢,因此我无法使用它。我只是不明白如何解决这个problem.Has,有没有人遇到同样的问题,找到了解决方案?任何帮助都将深表感谢。

EN

回答 1

Stack Overflow用户

发布于 2015-06-25 09:45:53

这里有相当多的东西我需要修改。为您要从特征中读取的数据创建一个类变量,如私有字符串heartRate;

1)您不需要readCharacteristic()方法。相反,一旦设备正确连接,就应该在onConnectionStateChange中调用mBluetoothGatt.discoverServices()。然后,在onServicesDiscovered()方法中,我将调用gatt.getServices()。然后使用foreach循环遍历返回的服务,比较服务的UUID,直到找到您关心的服务。如果heartRate ==为空,则调用service.getCharacteristic(HeartRateUUID),然后读取特征。在onCharacteristicRead()中,检查UUID是否等于心率特征。如果是,则将特征的值赋给heartRate变量。如果您感兴趣,我可以输入方法或提供伪代码。

2)我不会调用后面跟着gatt.discoverServices()的gatt.connect()。一旦看到来自当前设备的通告数据包,gatt.connect()将立即重新连接到该设备。我会先调用gatt.connect(),然后在onConnectedStateChange()方法中调用gatt.discoverServices()。

3)在onConnectedStateChange方法中,不要使用gatt变量。请改用mBluetoothGatt。mBluetoothGatt.disconnect()与当前连接的设备断开连接。mBluetoothGatt.close()终止gatt实例。在调用mBluetoothGatt.Close()之后,不能调用mBluetoothGatt.connect()。这可能不是必需的,但如果设备已连接,我将调用mBluetoothGatt.disconnect(),然后调用mBluetoothGatt.close()。

4)您还可以将特征读数链接在一起。在onCharacteristicRead()中,在获得heartRate的值之后,可以立即调用characteristic.getService().getCharacteristic(UUIDTemperature),然后读取该特征。它将再次调用OnCharacteristicRead方法。

如果你想要我澄清什么,请告诉我;我正在糟糕的Surface Pro 3键盘上打字。:)

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/31039519

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档