如何在不使用缓存的情况下以编程方式在 Android 上强制发现蓝牙低能耗服务 [英] How to programmatically force bluetooth low energy service discovery on Android without using cache

查看:14
本文介绍了如何在不使用缓存的情况下以编程方式在 Android 上强制发现蓝牙低能耗服务的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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?

推荐答案

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

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中我们有reflection,所以我们可以访问这个方法.这是我连接蓝牙设备刷新缓存的代码.

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 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 上强制发现蓝牙低能耗服务的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆