You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android跨类调用BluetoothGatt时getServices返回Null问题求助

Android中BluetoothGatt.getServices()返回Null的解决方法

核心问题分析

调用bluetoothGatt.getServices()返回null,本质是BluetoothGatt实例未完成服务发现流程,或实例本身无效(未连接/已断开)。

具体解决步骤

1. 确保服务发现流程完成

  • 必须在BluetoothGattCallback的onConnectionStateChange回调确认连接成功后,调用bluetoothGatt.discoverServices()触发服务发现。
  • 只有当onServicesDiscovered回调触发且status为BluetoothGatt.GATT_SUCCESS时,才能安全调用getServices()。

2. 校验BluetoothGatt实例有效性

在writeCommand方法开头增加实例和连接状态校验:

if (bluetoothGatt == null || bluetoothGatt.getConnectionState(device) != BluetoothProfile.STATE_CONNECTED) {
    Log.e("jyothi", "BluetoothGatt未连接或实例无效");
    return;
}

3. 标记服务发现状态,避免提前调用

添加状态位标记服务是否已发现,在writeCommand中先检查该状态:

private boolean isServicesDiscovered = false;

// 在BluetoothGattCallback的onServicesDiscovered中设置状态
@Override
public void onServicesDiscovered(BluetoothGatt gatt, int status) {
    if (status == BluetoothGatt.GATT_SUCCESS) {
        isServicesDiscovered = true;
    }
}

// 在writeCommand中校验
if (!isServicesDiscovered) {
    Log.e("jyothi", "服务尚未发现,请等待连接完成");
    return;
}

4. 缓存目标服务与特征,避免重复遍历

服务发现完成后直接缓存需要的特征,无需每次写命令都遍历所有服务:

private BluetoothGattCharacteristic txCharacteristic;

// 在onServicesDiscovered中缓存特征
@Override
public void onServicesDiscovered(BluetoothGatt gatt, int status) {
    if (status == BluetoothGatt.GATT_SUCCESS) {
        BluetoothGattService service = gatt.getService(UUID.fromString(SERVICE_GUID));
        if (service != null) {
            txCharacteristic = service.getCharacteristic(UUID.fromString(TX_CHAR_GUID));
        }
        isServicesDiscovered = true;
    }
}

// 修改后的writeCommand方法
public void writeCommand(int auto_bright_value) {
    if (ActivityCompat.checkSelfPermission(activity, Manifest.permission.BLUETOOTH_CONNECT) != PackageManager.PERMISSION_GRANTED) {
        return;
    }
    if (bluetoothGatt == null || bluetoothGatt.getConnectionState(device) != BluetoothProfile.STATE_CONNECTED) {
        Log.e("jyothi", "蓝牙未连接");
        return;
    }
    if (txCharacteristic == null) {
        Log.e("jyothi", "未找到目标特征");
        return;
    }

    String jsonString = "{\"i\": 1, \"v\": 1, \"t\": 8, \"s\": \"dbri\", \"n\": " + auto_bright_value + "}";
    Log.d("jsonstring", jsonString);
    byte[] payload = jsonString.getBytes();
    txCharacteristic.setValue(payload);
    txCharacteristic.setWriteType(BluetoothGattCharacteristic.WRITE_TYPE_NO_RESPONSE);
    boolean writeStatus = bluetoothGatt.writeCharacteristic(txCharacteristic);
    Log.i("mtu", "writeStatus:" + writeStatus);
}

5. 处理连接断开后的重连逻辑

蓝牙连接断开后,需重新初始化BluetoothGatt、重新连接并触发服务发现,不能复用旧实例。

关键注意事项

  • 禁止在连接成功后立即调用getServices(),必须等待onServicesDiscovered回调。
  • 权限检查要在蓝牙操作前完成,避免中途因权限中断流程。
  • 全局维护BluetoothGatt实例,防止被垃圾回收。

内容的提问来源于stack exchange,提问作者Hayjyo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 18:32:02