How to programmatically force bluetooth low energy service discovery on Android without using cache

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?

  • How to programmatically set drawableRight on Android Edittext?
  • Android: Get App-Name from Intent
  • Can I have onScrollListener for a ScrollView?
  • how to convert double to 2 number after the dot?
  • What is callback in Android?
  • FusedLocationApi.getLastLocation always null
  • Related posts:

    Android: What is used for?
    android - apply selectableItemBackground in xml with support v7
    query the google play store for the version of an app?
    Android Saving created bitmap to directory on sd card
    Detect the status of two SIM cards in a dual-SIM Android phone
    Output one character per two keys in Android Keyboard
  • Billing API v3 IabHelper NullPointerException
  • @SmallTest, @MediumTest, and @LargeTest deprecated on Android
  • Keystore and Aliases - is there a use to multiple aliases?
  • Android share intent chooser
  • android intent for sdcard ready
  • Insert a time stamp into database via ContentValues
  • 4 Solutions collect form web for “How to programmatically force bluetooth low energy service discovery on Android without using cache”

    I just had the same problem. If you see the source code of 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) {
                return false;
            return true;

    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
            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));
            Log.d(TAG, "Trying to create a new connection.");
            return true;

    Indeed Miguel’s answer works. To use refreshDeviceCache, I’m successful with this calling order:

    // Attempt GATT connection
    public void connectGatt(MyBleDevice found) {
        BluetoothDevice device = found.getDevice();
        gatt = device.connectGatt(mActivity, false, mGattCallback);

    This works for OS 4.3 through 5.0 tested with Android and iPhone Peripherals.

    Use the following before scanning the device:

    if(mConnectedGatt != null) mConnectedGatt.close();

    This will disconnect the device and clear the cache and hence you would be able to reconnect to the same device.

    In Some Devices, Even you disconnect the socket the connection wont end because of the cache. You need to disconnect the remote device by using the BluetoothGatt Class. As Below

    BluetoothGatt mBluetoothGatt = device.connectGatt(appContext, false, new BluetoothGattCallback() {

    Note : This logic worked for me in china based devices

    Android Babe is a Google Android Fan, All about Android Phones, Android Wear, Android Dev and Android Games Apps and so on.