onServicesDiscovered never called while connecting to GATT Server

前端 未结 5 371
闹比i
闹比i 2020-12-17 20:04

I have a bluetooth headset which is paired with my Nexus 5X (running Android 7.1) and I would like to connect to a GATT Server of the headset. I tried it with the following

5条回答
  •  北荒
    北荒 (楼主)
    2020-12-17 20:40

    This may help

    I will explain in two steps: connecting and discovering services

    connecting: connect from mainthread

    set auto-reconnect to false

    if version greater than or equals to M, set Transport type

    else directly use reflection and handle it properly

    Handler(applicationContext.mainLooper).post {
                        Log.d(TAG, " Post is called inside mainlooper")
                        mBluetoothGatt = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                            Log.d(TAG, " Is Or Greater than M $mBluetoothDevice")
                            mBluetoothDevice!!.connectGatt(this, false,
                                    onGhattListener, TRANSPORT_LE)
                        } else {
                            Log.d(TAG, " Less than M")
                            try {
                                Log.d(TAG, " Trying TRANPORT LE with reflection")
                                val m = mBluetoothDevice!!.javaClass.getDeclaredMethod("connectGatt", Context::class.java, Boolean::class.javaPrimitiveType, BluetoothGattCallback::class.java, Int::class.javaPrimitiveType)
                                m.isAccessible = true
                                val transport = mBluetoothDevice!!.javaClass.getDeclaredField("TRANSPORT_LE").getInt(null)
                                m.invoke(mBluetoothDevice, this, false, onGhattListener, transport) as BluetoothGatt
                            } catch (e: Exception) {
                                e.printStackTrace()
                                Log.d(TAG, " Catch to call normal connection")
                                mBluetoothDevice!!.connectGatt(this, false,
                                        onGhattListener)
                            }
                        }
                        Log.d(TAG, "mBluetooth gatt is $mBluetoothGatt")
                        mBluetoothGatt?.let {
                            refreshDeviceCache(mBluetoothGatt!!)
                        }
                    }
    

    discover services : in onGhattListener , if device is connected fire discoverServices() from main thread

    override fun onConnectionStateChange(gatt: BluetoothGatt, status: Int,
                                             newState: Int) {
            Log.d(TAG, "onConnectionStateChange $gatt and status $status and newstate $newState")
            when (newState) {
                BluetoothGatt.STATE_CONNECTED -> {
                    Handler(Looper.getMainLooper()).post {
                        gatt.discoverServices()
                    }
                }
                BluetoothGatt.STATE_DISCONNECTED -> {
    
                }
                BluetoothGatt.STATE_CONNECTING -> {
    
                }
                BluetoothGatt.STATE_DISCONNECTING -> {
    
                }
            }
        }
    

    this may solve your problem

    call refresh method with reflection

    fun refreshDeviceCache(gatt: BluetoothGatt): Boolean {
        try {
            val localMethod = gatt.javaClass.getMethod("refresh")
            if (localMethod != null) {
                return localMethod.invoke(gatt) as Boolean
            }
        } catch (localException: Exception) {
            Log.e(TAG, "An exception occured while refreshing device")
            localException.printStackTrace()
        }
        return false
    }
    

提交回复
热议问题