Android/Java如何从匿名重写类的onReadRemoteRssi方法获取rssi值
Android BLE中从onReadRemoteRssi回调获取RSSI值的实现方法
onReadRemoteRssi是蓝牙GATT操作的异步回调,gatt.readRemoteRssi()调用后会立刻返回,不会阻塞等待结果,因此无法直接在调用readRemoteRssi()的代码行同步拿到返回的RSSI值,所有依赖RSSI结果的逻辑都需要在回调触发后执行,常用的实现方案有以下两种:
方案1:使用类成员变量暂存值
- 在当前承载蓝牙逻辑的Activity、Service或工具类中,定义int类型的成员变量存储RSSI结果
- 在
onReadRemoteRssi回调中判断操作状态,成功后给成员变量赋值,再直接触发后续业务逻辑
示例代码:
// 类成员位置定义变量 private int currentRssi; private BluetoothGatt gatt; // 蓝牙连接与读RSSI逻辑 gatt = c.connectGatt(getApplicationContext(), false, new BluetoothGattCallback() { @Override public void onReadRemoteRssi(BluetoothGatt gatt, int rssi, int status) { super.onReadRemoteRssi(gatt, rssi, status); // 先校验操作状态,避免拿到错误值 if (status == BluetoothGatt.GATT_SUCCESS) { currentRssi = rssi; Log.d("BSSI", "rssi is : " + rssi); // 赋值后在这里执行后续逻辑,比如更新UI、做信号强度判断 handleRssiResult(currentRssi); } } }); gatt.readRemoteRssi();
注意:不要在
gatt.readRemoteRssi()调用后立刻读取currentRssi的值,此时回调还未触发,变量会是默认初始值,必须等回调执行完成后再使用。
方案2:自定义回调接口传递结果
如果蓝牙逻辑被封装在独立工具类中,可以自定义监听接口把RSSI结果抛给上层调用处,避免成员变量耦合。
- 首先定义结果监听接口
public interface RssiResultListener { void onGetRssi(int rssi, int status); }
- 在蓝牙管理类中持有监听实例,GATT回调触发时回传结果
// 蓝牙管理类中的成员 private RssiResultListener rssiListener; private BluetoothGatt gatt; // 对外暴露的读RSSI方法 public void getRemoteRssi(RssiResultListener listener) { this.rssiListener = listener; if (gatt != null) { gatt.readRemoteRssi(); } } // BluetoothGattCallback中的实现 @Override public void onReadRemoteRssi(BluetoothGatt gatt, int rssi, int status) { super.onReadRemoteRssi(gatt, rssi, status); if (rssiListener != null) { rssiListener.onGetRssi(rssi, status); } }
- 上层调用时直接在回调中拿到结果使用
bleManager.getRemoteRssi(new RssiResultListener() { @Override public void onGetRssi(int rssi, int status) { if (status == BluetoothGatt.GATT_SUCCESS) { // 此处即可直接拿到RSSI值执行业务逻辑 Log.d("RSSI", "获取到的信号强度:" + rssi); } } });
所有蓝牙GATT操作(读/写特征、发现服务、读RSSI等)都是异步执行的,不要写轮询等待、线程阻塞的代码去等结果,很容易触发主线程ANR,直接把后续逻辑放到对应回调中执行即可。
内容的提问来源于stack exchange,提问作者Ali Abdullah
相关产品推荐
相关产品推荐

