Jame
Jame

Reputation: 3854

How to solve the error onClientConnectionState() - status=22 clientIf=7 in BLE

I have an Android application which uses Bluetooth Low Energy (BLE) to connect with my phone. The application worked well in almost all phones such as Galaxy S5 (Android 5.0.1), Galaxy S6 (Android 6.0). However, it has a critical issue in Galaxy Note 3 (Android 5.0.1).

When I call the connect() function, and then call the readCharacteristic(), it returns the error:

onClientConnectionState() - status=22 clientIf=7

The error happens after I call the connect function for about 2 seconds. I look up some solution, such as making a delay before calling readCharacteristic(), but it cannot solve.

Could you have any way to solve my issue?

Thank all.

This is my code:

 private final BluetoothGattCallback mGattCallback = new BluetoothGattCallback() {
   @Override
   public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
            
     if (newState == BluetoothProfile.STATE_CONNECTED) {               
        mBluetoothGatt.discoverServices();      
     } else if (newState == BluetoothProfile.STATE_DISCONNECTED) {}
     }

     @Override
     public void onServicesDiscovered(BluetoothGatt gatt, int status) {
       if (status == BluetoothGatt.GATT_SUCCESS) {
          try {
            Thread.sleep(500);
            readCharacteristic();
          } catch (InterruptedException e) {
            e.printStackTrace();
          }

       } else {
           Log.w(TAG, "onServicesDiscovered received: " + status);
       }
     }

     @Override
     public void onCharacteristicRead(BluetoothGatt gatt,
                                         BluetoothGattCharacteristic characteristic,
                                         int status) {           
     }

     @Override
     public void onCharacteristicChanged(BluetoothGatt gatt,
                                            BluetoothGattCharacteristic characteristic) {            
     }
 };

 public void readCharacteristic() {
   /*check if the service is available on the device*/
   BluetoothGattService mCustomService = mBluetoothGatt.getService(UUID.fromString("00001c00-d102-11e1-9b23-00025b00123"));
   /*get the read characteristic from the service*/
   BluetoothGattCharacteristic mReadCharacteristic = mCustomService.getCharacteristic(UUID.fromString("00001233-d102-11e1-9b23-00025b00a5a5"));
   mBluetoothGatt.setCharacteristicNotification(mReadCharacteristic, true);
   BluetoothGattDescriptor descriptor = mReadCharacteristic.getDescriptor(
                UUID.fromString(SampleGattAttributes.CLIENT_CHARACTERISTIC_CONFIG));
   descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
   mBluetoothGatt.writeDescriptor(descriptor);
 }

This is my full service function file to connect BLE

public class ConnectionService extends Service{
    private BluetoothLeService mBluetoothLeService;
    public String mDeviceAddress="0A:1B:6C:22:11:3D";
    private ServiceMonitor serviceMonitor = ServiceMonitor.getInstance();
    private final ServiceConnection mServiceConnection = new ServiceConnection() {

        @Override
        public void onServiceConnected(ComponentName componentName, IBinder service) {           
            mBluetoothLeService = ((BluetoothLeService.LocalBinder) service).getService();
            if (!mBluetoothLeService.initialize()) {
                Log.e(TAG, "Unable to initialize Bluetooth");
            }
            mBluetoothLeService.connect(mDeviceAddress);
        }
        @Override
        public void onServiceDisconnected(ComponentName componentName) {
            mBluetoothLeService = null;
        }
    };

    @Override
    public void onCreate() {
        super.onCreate();        
    }

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }
    @Override
    public void onDestroy() {
        if(mGattUpdateReceiver!=null) {
            unregisterReceiver(mGattUpdateReceiver);
        }
        if(mServiceConnection!=null) {
            unbindService(mServiceConnection);
        }
    }


    @Override
    public int onStartCommand(Intent intent, int flags, int startId)
    {      
        //If some device is connecting to phone, let disconnect 
        if(mConnected==true) {
            mBluetoothLeService.disconnect();           
        } 
        //If bluetooth is enable    
        if (BleUtils.getBluetoothAdapter(getApplicationContext()).enable()) {
            Intent gattServiceIntent = new Intent(this, BluetoothLeService.class);
            bindService(gattServiceIntent, mServiceConnection, BIND_AUTO_CREATE);
            registerReceiver(mGattUpdateReceiver, makeGattUpdateIntentFilter());
            //Try to reconnect if the connect is not successful
            if (mBluetoothLeService != null) {
                new CountDownTimer(3000,1000) {
                    public void onTick(long millisUntilFinished) {}
                    public void onFinish() {
                        final boolean result = mBluetoothLeService.connect(mDeviceAddress);
                        Log.d(TAG, "Connect request result=" + result);
                    }
                }.start();
            }            
        }
        return START_STICKY;
}

Upvotes: 23

Views: 6709

Answers (1)

Pedro Varela
Pedro Varela

Reputation: 2425

There are different parameters for connectGatt() method, it differs from API version. This is kotlin code. I don't see your connect method anywhere but i know you have to call connectGatt() somewhere.

Build.VERSION.SDK_INT >= Build.VERSION_CODES.M -> bluetoothDevice?.connectGatt(applicationContext, true, mGattCallback, BluetoothDevice.TRANSPORT_LE)

else -> bluetoothDevice?.connectGatt(applicationContext, false, mGattCallback)

Upvotes: 1

Related Questions