android - 如何在不使用缓存的情况下以编程方式在 Android 上强制蓝牙低能耗服务发现

标签 android bluetooth bluetooth-lowenergy service-discovery

我在 Nexus 7 上使用 Android 4.4.2。 我有一个蓝牙低功耗外围设备,它的服务在重新启动时会发生变化。 android 应用程序调用 BluetoothGatt.discoverServices()。然而,Android 只查询一次外围设备以发现服务,随后对 discoverServices() 的调用会导致第一次调用的缓存数据,即使在断开连接之间也是如此。 如果我禁用/启用 Android bt 适配器,则 d​​iscoverServices() 通过查询外围设备来刷新缓存。 是否有一种编程方式可以强制 Android 在不禁用/启用适配器的情况下刷新其 ble 服务缓存?

最佳答案

我也遇到了同样的问题。如果你看BluetoothGatt.java的源码你可以看到有一个方法叫refresh()

/**
* Clears the internal cache and forces a refresh of the services from the 
* remote device.
* @hide
*/
public boolean refresh() {
        if (DBG) Log.d(TAG, "refresh() - device: " + mDevice.getAddress());
        if (mService == null || mClientIf == 0) return false;

        try {
            mService.refreshDevice(mClientIf, mDevice.getAddress());
        } catch (RemoteException e) {
            Log.e(TAG,"",e);
            return false;
        }

        return true;
}

此方法确实会从蓝牙设备中清除缓存。但问题是我们无法访问它。 但是在java中我们有reflection ,所以我们可以访问这个方法。这是我连接蓝牙设备刷新缓存的代码。

private boolean refreshDeviceCache(BluetoothGatt gatt){
    try {
        BluetoothGatt localBluetoothGatt = gatt;
        Method localMethod = localBluetoothGatt.getClass().getMethod("refresh", new Class[0]);
        if (localMethod != null) {
           boolean bool = ((Boolean) localMethod.invoke(localBluetoothGatt, new Object[0])).booleanValue();
            return bool;
         }
    } 
    catch (Exception localException) {
        Log.e(TAG, "An exception occurred while refreshing device");
    }
    return false;
}

    
    public boolean connect(final String address) {
           if (mBluetoothAdapter == null || address == null) {
            Log.w(TAG,"BluetoothAdapter not initialized or unspecified address.");
                return false;
        }
            // Previously connected device. Try to reconnect.
            if (mBluetoothGatt != null) {
                Log.d(TAG,"Trying to use an existing mBluetoothGatt for connection.");
              if (mBluetoothGatt.connect()) {
                    return true;
               } else {
                return false;
               }
        }

        final BluetoothDevice device = mBluetoothAdapter
                .getRemoteDevice(address);
        if (device == null) {
            Log.w(TAG, "Device not found.  Unable to connect.");
            return false;
        }

        // We want to directly connect to the device, so we are setting the
        // autoConnect
        // parameter to false.
        mBluetoothGatt = device.connectGatt(MyApp.getContext(), false, mGattCallback));
        refreshDeviceCache(mBluetoothGatt);
        Log.d(TAG, "Trying to create a new connection.");
        return true;
    }

关于android - 如何在不使用缓存的情况下以编程方式在 Android 上强制蓝牙低能耗服务发现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22596951/

相关文章:

android - GetCameraDisplayOrientation 始终返回 0

android - Xamarin Android 安装失败

ios - 使用 Mac 数据包记录器进行蓝牙 LE 跟踪

java - Android BLE 中未调用 onBatchScanResults

android - 多个应用程序可以处理 ibeacon 事件吗

android - 如何在 Android 中为微调器设置下拉列表参数?

android - 展开微调项目

java - 如果关闭 BluetoothSocket,是否需要关闭 InputStream/OutputStream?

android - 保持 Android 蓝牙扫描但它自行停止

java - 使用 Java 的蓝牙设备的电池电量