某些设备上没有蓝牙 gatt 回调

No Bluetooth gatt callback on some devices

我的应用列出了在蓝牙 LE 设备上找到的服务。它有:

我无法在我的广播接收器中可靠地从 BluetoothGatt 获得 GATT 回调。我有 2 个正在测试的设备,它们对相同的代码得到不同的结果。我的 Tablet 运行 Android 4.4.2 完全没有回调,而我的 Nexus 4 phone 运行 5.1.1 获得回调并显示服务。

这是我服务内部的 gatt 回调:

private final BluetoothGattCallback mGattCallback = new BluetoothGattCallback() {
    @Override
    public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
        String intentAction;
        if (newState == BluetoothProfile.STATE_CONNECTED) {
            intentAction = ACTION_GATT_CONNECTED;
            mConnectionState = STATE_CONNECTED;
            broadcastUpdate(intentAction);
            Log.i(TAG, "Connected to GATT server.");
            // Attempts to discover services after successful connection.
            Log.i(TAG, "Attempting to start service discovery.");
                    //mBluetoothGatt.discoverServices();
                    gatt.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) {

        if (status == BluetoothGatt.GATT_SUCCESS) {
            broadcastUpdate(ACTION_GATT_SERVICES_DISCOVERED);
            Log.d(TAG, "Services discovered, broadcasting update");
        } else {
            Log.w(TAG, "onServicesDiscovered received: " + status);
        }
    }

    @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);
        Log.d(TAG, "Characteristic changed, broadcasting update");


    }

    @Override
    public void onCharacteristicWrite(BluetoothGatt gatt,
                                      BluetoothGattCharacteristic characteristic,
                                      int status) {
        broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic);
        Log.d(TAG, "Characteristic written, braodcasting update");
    }
};

这是我的主要内容 activity:

// Code to manage Service lifecycle.
private final ServiceConnection mServiceConnection = new ServiceConnection() {

    @Override
    public void onServiceConnected(ComponentName componentName, IBinder service) {
        mBluetoothLeService = ((BluetoothLeService.LocalBinder) service).getService();
        if (!mBluetoothLeService.initialize()) {
            Log.e(TAG, "Unable to initialize Bluetooth");
            finish();
        }
        // Automatically connects to the device upon successful start-up initialization.
        mBluetoothLeService.connect(mDeviceAddress);
    }

    @Override
    public void onServiceDisconnected(ComponentName componentName) {
        Log.d(TAG,"Disconnected from service");
        mBluetoothLeService = null;
    }
};
// Handles various events fired by the Service.
// ACTION_GATT_CONNECTED: connected to a GATT server.
// ACTION_GATT_DISCONNECTED: disconnected from a GATT server.
// ACTION_GATT_SERVICES_DISCOVERED: discovered GATT services.
// ACTION_DATA_AVAILABLE: received data from the device.  This can be a result of read
//                        or notification operations.

private final BroadcastReceiver mGattUpdateReceiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {

        final String action = intent.getAction();
        Log.d(TAG,"Received data from broadcast receiver: "+ action);

        if (BluetoothLeService.ACTION_GATT_CONNECTED.equals(action)) {
            mConnected = true;
            updateConnectionState(R.string.connected);
            invalidateOptionsMenu();
        } else if (BluetoothLeService.ACTION_GATT_DISCONNECTED.equals(action)) {
            Log.d(TAG,"Disconnected from the gatt server");
            mConnected = false;
            updateConnectionState(R.string.disconnected);
            invalidateOptionsMenu();
             clearUI();
        } else if (BluetoothDevice.ACTION_FOUND.equals(action)) {
            Log.d(TAG,"Receiver: Action Found");
            // Get the BluetoothDevice object from the Intent
            BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);

            // get fresh uuids
            device.fetchUuidsWithSdp();

        } else if (BluetoothDevice.ACTION_UUID.equals(action)) {
            // Get the device and teh uuids
            BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
            Parcelable[] uuidExtra = intent.getParcelableArrayExtra(BluetoothDevice.EXTRA_UUID);

            if (uuidExtra != null) {

                for (Parcelable uuid : uuidExtra) {
                    Log.d(TAG, "Device: " + device.getName() + " ( " + device.getAddress() + " ) - Service: " + uuid.toString());
                }

            }
        } else if (BluetoothLeService.ACTION_GATT_SERVICES_DISCOVERED.equals(action)) {
            // Show all the supported services and characteristics on the user interface.
            myDevice.setServices(mBluetoothLeService.getSupportedGattServices());
            Log.d(TAG,"Services for "+ myDevice.getName() +" set by broadcast receiver");
            displayGattServices(mBluetoothLeService.getSupportedGattServices());
        } else if (BluetoothLeService.ACTION_DATA_AVAILABLE.equals(action)) {

            displayData(intent.getStringExtra(BluetoothLeService.EXTRA_DATA));
            Log.d(TAG, "Display Data: " + intent.getStringExtra(BluetoothLeService.EXTRA_DATA));
        }
    }
};

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_api);

    final Intent intent = getIntent();

    final Context context = getApplicationContext();

    // Initializes a Bluetooth adapter.  For API level 18 and above, get a reference to
    // BluetoothAdapter through BluetoothManager.
    final BluetoothManager bluetoothManager =
            (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
    mBluetoothAdapter = bluetoothManager.getAdapter();


    //Intent gattServiceIntent = new Intent(context, BluetoothLeService.class);
    //context.bindService(gattServiceIntent, mServiceConnection, Context.BIND_AUTO_CREATE);
    Intent gattServiceIntent = new Intent(this, BluetoothLeService.class);
    bindService(gattServiceIntent, mServiceConnection, BIND_AUTO_CREATE);
...
});

最后,当我没有收到回调时发生的一些日志输出

D/BluetoothGatt﹕ connect() - device: 00:07:80:2D:D3:5C, auto: false
D/BluetoothGatt﹕ registerApp()
D/BluetoothGatt﹕ registerApp() - UUID=468b550a-c0e6-4c54-8437-bb83d07f9be8
D/BluetoothGatt﹕ onClientRegistered() - status=0 clientIf=5
D/VXHB﹕ Trying to create a new connection.
D/BluetoothGatt﹕ onClientConnectionState() - status=133 clientIf=5 device=00:07:80:2D:D3:5C
I/VXHB﹕ Connected to GATT server.
I/VXHB﹕ Attempting to start service discovery.
D/BluetoothGatt﹕ discoverServices() - device: 00:07:80:2D:D3:5C
D/VXHB﹕ Received data from broadcast receiver: my.package.name.ACTION_GATT_CONNECTED

正如您从 logcat 输出中看到的那样,ACTION_GATT_CONNECTED 的广播有效并且 discoverservices 实际上被触发了,但我从未收到回调。

任何解决此问题的线索?

尝试在 onCreate 中注册您的广播接收器:

IntentFilter filter = new IntentFilter();
filter.addAction(BluetoothLeService.ACTION_GATT_CONNECTED);
filter.addAction(BluetoothLeService.ACTION_GATT_DISCONNECTED);
filter.addAction(BluetoothDevice.ACTION_FOUND);
filter.addAction(BluetoothDevice.ACTION_UUID);
filter.addAction(BluetoothLeService.ACTION_GATT_SERVICES_DISCOVERED);
filter.addAction(BluetoothLeService.ACTION_DATA_AVAILABLE);

registerReceiver(mGattUpdateReceiver, filter);

我的代码中有其他地方导致此故障。恢复到较旧的提交,问题已解决。