如何以编程方式迫使蓝牙低功耗技术服务发现在Android上,而无需使用的缓存蓝牙、缓存、技术服务、低功耗

2023-09-12 07:23:27 作者:鱼念七秒、人念一生

我使用的一台Nexus 7的Andr​​oid 4.4.2。 我有一个蓝牙低功耗外设的服务时,它被重新引导改变。 Android应用程序调用BluetoothGatt.discoverServices()。但是Android的只查询外围一旦发现服务,后续调用discoverServices()导致从第一次调用缓存的数据,甚至是断开的。 如果我禁用/启用Android的BT适配器,然后discoverServices()通过查询周边刷新缓存。 有没有一种编程方式,迫使机器人刷新其均衡器服务缓存,而不禁用/启用适配器?

I am using Android 4.4.2 on a Nexus 7. I have a bluetooth low energy peripheral whose services change when it is rebooted. The android app calls BluetoothGatt.discoverServices(). However Android only queries the peripheral once to discover services, subsequent calls to discoverServices() result in the cached data from the first call, even between disconnections. If I disable/enable the Android bt adapter then discoverServices() refreshes the cache by querying the peripheral. Is there a programmatic way to force Android to refresh its' ble services cache without disabling/enabling the adapter?

推荐答案

我有同样的问题。如果你看到的来源$ C ​​$ C的 BluetoothGatt.java 的,你可以看到,有一个叫做方法的刷新()的

I just had the same problem. If you see the source code of BluetoothGatt.java you can see that there is a method called 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,我们有反射的,这样我们就可以访问该方法。这是我的code连接蓝牙设备刷新缓存。

This method does actually clear the cache from a bluetooth device. But the problem is that we don't have access to it. But in java we have reflection, so we can access this method. Here is my code to connect a bluetooth device refreshing the cache.

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 occured 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;
    }
 
精彩推荐
图片推荐