title: Android BLE Gatt Connection Issue (Connection Timeout Status:8)
body: <p>I'm developing an Android app that discovers and connects to a GATT service that is being advertised by my rPi 3B+. The iOS app that I've finished developing works without any issue. However, almost every time (95%) my Android app connects to the GATT server and tries to discover the services, the GATT connection times out with the status response code: 8.</p>
  <p>Here's my android code:</p>
  <pre><code>package com.example.myapplication;
  
  import android.bluetooth.BluetoothAdapter;
  import android.bluetooth.BluetoothDevice;
  import android.bluetooth.BluetoothGatt;
  import android.bluetooth.BluetoothGattCallback;
  import android.bluetooth.BluetoothGattCharacteristic;
  import android.bluetooth.BluetoothGattDescriptor;
  import android.bluetooth.BluetoothManager;
  import android.bluetooth.BluetoothProfile;
  import android.bluetooth.le.BluetoothLeScanner;
  import android.bluetooth.le.ScanCallback;
  import android.bluetooth.le.ScanFilter;
  import android.bluetooth.le.ScanResult;
  import android.bluetooth.le.ScanSettings;
  import android.content.Intent;
  import android.os.Build;
  import android.os.Bundle;
  import android.os.Handler;
  import android.os.Looper;
  import android.os.ParcelUuid;
  import android.util.Log;
  import android.view.View;
  import android.widget.AdapterView;
  import android.widget.ArrayAdapter;
  import android.widget.ListView;
  import android.widget.TextView;
  import androidx.appcompat.app.AppCompatActivity;
  import java.util.ArrayList;
  import java.util.List;
  import java.util.UUID;
  
  public class MainActivity extends AppCompatActivity implements AdapterView.OnItemClickListener {
  
  BluetoothAdapter bluetoothAdapter;
  BluetoothLeScanner bluetoothLeScanner;
  BluetoothManager bluetoothManager;
  BluetoothScanCallback bluetoothScanCallback;
  BluetoothGatt gattClient;
  BluetoothGattCharacteristic characteristicID;
  TextView scanningText;
  
  final UUID SERVICE_UUID = UUID.fromString(&quot;6E400001-B5A3-F393-E0A9-E50E24DCCA9E&quot;);
  final UUID CHARACTERISTIC_UUID_ID = UUID.fromString(&quot;6E400002-B5A3-F393-E0A9-E50E24DCCA9E&quot;);
  final UUID DESCRIPTOR_UUID_ID = UUID.fromString(&quot;00002902-0000-1000-8000-00805F9B34FB&quot;);
  
  ArrayList&lt;String&gt; wifiSSIDs = new ArrayList&lt;&gt;() ;
  ListView listViewSSID;
  ArrayAdapter&lt;String&gt; SSIDadapter;
  
  @Override
  protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.main);
      getSupportActionBar().setDefaultDisplayHomeAsUpEnabled(true);
      listViewSSID = findViewById(R.id.lv_SSID);
      scanningText = findViewById(R.id.scanningText);
      SSIDadapter = new ArrayAdapter&lt;&gt;(this, android.R.layout.simple_list_item_1, wifiSSIDs);
      listViewSSID.setAdapter(SSIDadapter);
      listViewSSID.setOnItemClickListener(this);
  
      bluetoothManager = (BluetoothManager) getSystemService(BLUETOOTH_SERVICE);
      bluetoothAdapter = bluetoothManager.getAdapter();
      startScan();
  }
  
  @Override
  protected void onDestroy() {
      super.onDestroy();
      Log.i(&quot;App&quot;,&quot;App closing...&quot;);
      gattClient.disconnect();
      gattClient.close();
  }
  
  
  private void startScan(){
  
      ScanFilter scanFilter = new ScanFilter.Builder().setServiceUuid(new ParcelUuid(SERVICE_UUID)).build();
      ArrayList&lt;ScanFilter&gt; filters = new ArrayList&lt;&gt;();
  
      filters.add(scanFilter);
  
      ScanSettings scanSettings = new ScanSettings.Builder().setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY).build();
  
      Log.i(&quot;Bluetooth Scan&quot;,&quot;startScan()&quot;);
      bluetoothScanCallback = new BluetoothScanCallback();
      bluetoothLeScanner = bluetoothAdapter.getBluetoothLeScanner();
      bluetoothLeScanner.startScan(filters, scanSettings, bluetoothScanCallback);
  }
  
  private void connectDevice(BluetoothDevice device) {
      if (device == null) Log.i(&quot;Bluetooth Connection&quot;,&quot;Device is null&quot;);
      GattClientCallback gattClientCallback = new GattClientCallback();
      gattClient = device.connectGatt(this,false, gattClientCallback, BluetoothDevice.TRANSPORT_LE);
  }
  
  private class BluetoothScanCallback extends ScanCallback {
      @Override
      public void onScanResult(int callbackType,final ScanResult result) {
          Log.i(&quot;Bluetooth Scan Result&quot;, &quot;onScanResult&quot;);
          bluetoothLeScanner.stopScan(bluetoothScanCallback); // stop scan
          connectDevice(result.getDevice());
      }
  
      @Override
      public void onBatchScanResults(List&lt;ScanResult&gt; results) {
          Log.i(&quot;Bluetooth Scan Result&quot;, &quot;onBathScanResults&quot;);
      }
  
      @Override
      public void onScanFailed(int errorCode) {
          Log.i(&quot;Bluetooth Scan Result&quot;, &quot;ErrorCode: &quot; + errorCode);
      }
  }
  
  private class GattClientCallback extends BluetoothGattCallback {
      @Override
      public void onConnectionStateChange(final BluetoothGatt gatt, int status, int newState) {
          super.onConnectionStateChange(gatt, status, newState);
          Log.i(&quot;Bluetooth Connection&quot;,&quot;onConnectionStateChange&quot;);
  
          if (status == BluetoothGatt.GATT_FAILURE) {
              Log.i(&quot;Bluetooth Connection&quot;, &quot;onConnectionStateChange GATT FAILURE&quot;);
              return;
          } else if (status != BluetoothGatt.GATT_SUCCESS) {
              Log.i(&quot;Bluetooth Connection&quot;, &quot;onConnectionStateChange != GATT_SUCCESS&quot;);
              Log.i(&quot;Bluetooth Connection&quot;, String.valueOf(status));
  
              startScan();
              return;
          }
          else {
              final BluetoothDevice device = gatt.getDevice();
              if (newState == BluetoothProfile.STATE_CONNECTED) {
  
                  Log.i(&quot;Bluetooth Connection&quot;, &quot;onConnectionStateChange CONNECTED&quot;);
  
                  new Handler(Looper.getMainLooper()).postDelayed(new Runnable() {
                      @Override
                      public void run() {
                      gatt.discoverServices(); }
                  }, 500);
  
              } else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
                  Log.i(&quot;Bluetooth Connection&quot;, &quot;onConnectionStateChange DISCONNECTED&quot;);
              }
          }
      }
  
      @Override
      public void onServicesDiscovered(final BluetoothGatt gatt, int status) {
          super.onServicesDiscovered(gatt, status);
          Log.i(&quot;Bluetooth Services&quot;,&quot;onServicesDiscovered&quot;);
  
          new Handler(Looper.getMainLooper()).postDelayed(new Runnable() {
              @Override
              public void run() {
                  characteristicID = gatt.getService(SERVICE_UUID).getCharacteristic(CHARACTERISTIC_UUID_ID);
                  gatt.setCharacteristicNotification(characteristicID,true); }
          }, 500);
  
  
          new Handler(Looper.getMainLooper()).postDelayed(new Runnable() {
              @Override
              public void run() {
                  BluetoothGattDescriptor descriptor = characteristicID.getDescriptor(DESCRIPTOR_UUID_ID);
                  descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
                  gatt.writeDescriptor(descriptor); }
          }, 500);
  
      }
  
      @Override
      public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
          super.onCharacteristicRead(gatt, characteristic, status);
          Log.i(&quot;BT Characteristics&quot;,&quot;onCharacteristicRead&quot;);
      }
  
      @Override
      public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
          super.onCharacteristicWrite(gatt, characteristic, status);
          Log.i(&quot;BT Characteristics&quot;,&quot;onCharacteristicWrite&quot;);
      }
  
      @Override
      public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
          super.onCharacteristicChanged(gatt, characteristic);
          Log.i(&quot;BT Characteristics&quot;,&quot;onCharacteristicChanged&quot;);
          Log.i(&quot;Characteristic Change&quot;,new String(characteristic.getValue()));
          final String characteristicValue = new String(characteristic.getValue());
          runOnUiThread(new Runnable() {
              @Override
              public void run() {
                  wifiSSIDs.add(characteristicValue);
                  SSIDadapter.notifyDataSetChanged();
  
                  listViewSSID.setVisibility(View.VISIBLE);
                  scanningText.setVisibility(View.INVISIBLE);
              }
          });
      }
  
      @Override
      public void onDescriptorRead(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {
          super.onDescriptorRead(gatt, descriptor, status);
          Log.i(&quot;BT Characteristics&quot;,&quot;onDescriptorRead&quot;);
      }
  
      @Override
      public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {
          super.onDescriptorWrite(gatt, descriptor, status);
          Log.i(&quot;BT Characteristics&quot;,&quot;onDescriptorWrite&quot;);
  
          characteristicID.setValue(&quot;RW&quot;);
          gatt.writeCharacteristic(characteristicID);
  
      }
  }
  
  @Override
  public void onItemClick(AdapterView&lt;?&gt; parent, View view, int position, long id) {
      String ssid = ((TextView) view).getText().toString();
      Log.i(&quot;Item Click&quot;,&quot;SSID: &quot; + ssid);
      characteristicID.setValue(&quot;SSID: &quot; + ssid);
      gattClient.writeCharacteristic(characteristicID);
  
      Intent intent = new Intent(this, PasswordActivity.class);
      startActivity(intent);
  }
  }
  </code></pre>
  <p>I can provide the python script code that's running on rPi but I believe that the problem stems from the android code. The log returns:</p>
  <pre><code>2020-10-05 14:05:53.710 19952-19952/com.example.myapplication I/Bluetooth Scan: startScan()
  2020-10-05 14:05:53.711 19952-19952/com.example.myapplication I/chatty: uid=10299(com.example.myapplication) identical 1 line
  2020-10-05 14:05:53.852 19952-19952/com.example.myapplication I/InputMethodManager: startInputInner - mService.startInputOrWindowGainedFocus
  2020-10-05 14:05:54.937 19952-19952/com.example.myapplication I/Bluetooth Scan Result: onScanResult
  2020-10-05 14:05:56.688 19952-19966/com.example.myapplication I/Bluetooth Connection: onConnectionStateChange
  2020-10-05 14:05:56.688 19952-19966/com.example.myapplication I/Bluetooth Connection: onConnectionStateChange CONNECTED
  2020-10-05 14:06:02.208 19952-19966/com.example.myapplication I/Bluetooth Connection: onConnectionStateChange
  2020-10-05 14:06:02.208 19952-19966/com.example.myapplication I/Bluetooth Connection: onConnectionStateChange != GATT_SUCCESS
  2020-10-05 14:06:02.208 19952-19966/com.example.myapplication I/Bluetooth Connection: 8
  </code></pre>