3

我正在编写一个通过蓝牙 LE 连接到健康设备的 Android 应用程序。但是,似乎我没有正确连接到它的 GATT 服务器。每隔几秒钟,我的日志文件就会显示:

03-27 11:33:39.821: D/BluetoothAdapter(26644): onScanResult() - Device=0C:F3:EE:AA:33:35 RSSI=-53
03-27 11:33:39.821: I/BluetoothGattActivity(26644): New LE Device: BT-001 @ -53
03-27 11:33:39.821: I/BluetoothGattActivity(26644): New LE Device matches !!!
03-27 11:33:39.831: I/BluetoothGattActivity(26644): In the fish function.
03-27 11:33:39.831: D/BluetoothGatt(26644): connect() - device: 0C:F3:EE:AA:33:35, auto:  false
03-27 11:33:39.831: D/BluetoothGatt(26644): registerApp()
03-27 11:33:39.831: D/BluetoothGatt(26644): registerApp() - UUID=7155a6e0-5432-42cc-8b05-a080c86aaccb
03-27 11:33:39.841: I/BluetoothGatt(26644): Client registered, waiting for callback
03-27 11:33:49.840: E/BluetoothGatt(26644): Failed to register callback
03-27 11:33:49.840: I/BluetoothGattActivity(26644): myBluetoothGatt is null

如果有人可以帮助我了解我的问题在哪里以及发生了什么,将不胜感激。我正在使用 Galaxy s4。我相信我所有的相关代码如下:

private void broadcastUpdate(final String action) {
   final Intent intent = new Intent(action);
   sendBroadcast(intent);
}

private void fish(final BluetoothDevice device) {      
   Log.i(TAG, "In the fish function.");
   myBluetoothGatt = device.connectGatt(this, false, myGattCallback);
   Log.i(TAG, "myBluetoothGatt is " + myBluetoothGatt);
}

private BluetoothAdapter.LeScanCallback callbackFunction = new BluetoothAdapter.LeScanCallback() {
   @Override
   public void onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord) {
       Log.i(TAG, "New LE Device: " + device.getName() + " @ " + rssi);
       if (DEVICE_NAME.equals(device.getName())) {
           Log.i(TAG, "New LE Device matches !!!");
           fish (device);
           }
   }
};

private final BluetoothGattCallback myGattCallback = new BluetoothGattCallback() {
    @Override
    public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
        String intentAction;
        Log.i(TAG, "We are in the ConnectionStateChanged().");
        if (newState == BluetoothProfile.STATE_CONNECTED) {
            intentAction = ACTION_GATT_CONNECTED;
            mConnectionState = STATE_CONNECTED;
            broadcastUpdate(intentAction);
            Log.i(TAG, "Connected to GATT server.");
            Log.i(TAG, "Attempting to start service discovery:" +
                    myBluetoothGatt.discoverServices());

        } else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
            intentAction = ACTION_GATT_DISCONNECTED;
            mConnectionState = STATE_DISCONNECTED;
            Log.i(TAG, "Disconnected from GATT server.");
            broadcastUpdate(intentAction);
        }
    }

    @Override
    public void onServicesDiscovered(BluetoothGatt gatt, int status) {
        Log.i(TAG, "In area 1");
        if (status == BluetoothGatt.GATT_SUCCESS) {
            broadcastUpdate(ACTION_GATT_SERVICES_DISCOVERED);
            System.out.println("--onServicesDiscovered");
        } else {
            Log.w(TAG, "onServicesDiscovered received: " + status);
        }
    }

    @Override
    public void onCharacteristicRead(BluetoothGatt gatt,BluetoothGattCharacteristic characteristic,int status) {
        Log.i(TAG, "In area 2");
        if (status == BluetoothGatt.GATT_SUCCESS) {
            broadcastUpdate(ACTION_DATA_AVAILABLE);
            Log.i(TAG, "--onCharacteristicRead GATT_SUCCESS");
        }
    }

    @Override
    public void onCharacteristicChanged(BluetoothGatt gatt,
                                        BluetoothGattCharacteristic characteristic) {
        Log.i(TAG, "In area 3");
        broadcastUpdate(ACTION_DATA_AVAILABLE);
        System.out.println("--onCharacteristicChanged");
    }
};
4

3 回答 3

4

对 device.connectGatt(this, false, myGattCallback) 的调用应该在主 UIThread 上完成。所以它应该是这样的:

private void fish(final BluetoothDevice device) {
        Log.i(TAG, "In the fish function.");
        runOnUiThread(new Runnable() {
          @Override
          public void run() {
              myBluetoothGatt = device.connectGatt(this, false, myGattCallback);
          }
        });
}
于 2014-11-13T10:05:39.720 回答
2

I have a partial fix for this particular form of the error. I saw in this question GATT callback fails to register that Samsung devices require Gatt discovery attempts to be done on the UI thread.

The tricky part for me was realizing that I wasn't on the thread I thought I was. The onLeScan callback was not returning on the UI thread, but instead on a Binder thread (at least according to the debugger). I wound up having to use a Handler to post a Runnable which kicked off my service discovery code.

The reason this is a partial fix is that now I'm in a state where the Gatt connection isn't null but Hangs after these lines

04-04 14:21:15.115    9616-9616/BluetoothApp I/BluetoothGatt﹕ Client registered, waiting for callback
04-04 14:21:15.115    9616-9627/BluetoothApp D/BluetoothGatt﹕ onClientRegistered() - status=0 clientIf=5

I haven't yet figured out how to solve this last issue, but this should get you one step further.

于 2014-04-04T21:30:57.940 回答
0

在绑定服务中注册回调和 device.connectGatt(this, false, myGattCallback) 并使用广播接收器进行进一步通信。

一旦您在回调中接收到事件或数据,只需广播相同的内容并从接收器接收它(如果您只使用一个活动,其余的都是片段,则应将其作为单独的或内部的主要活动编写在应用程序中)。

于 2014-12-22T06:44:43.737 回答