Skip to content

Unable to clear the state of connected devices #239

@Kinny2014

Description

@Kinny2014

First of all, thank you for providing such an excellent library.

I currently have a use case: an Android phone acts as the central device, continuously scanning (with filtering rules, based on specific names) and connecting to peripheral devices. Once a target device is detected, it connects.

I'm encountering a problem: when a peripheral device disconnects and then reconnects, it reverts to the state it was in when disconnected.

I noticed that CentralManagerImpl uses managedPeripherals to cache peripheral devices. Even after a peripheral device is powered off and disconnected, rescanning still returns the cached device, and I can't reset the _state in the peripheral from the outside. Is there a way to clear or reset the state of the peripheral devices? What's the best way to implement this for my use case?

Here is my code example:

    fun scan() {
        centralManager.scan(Duration.INFINITE) {
            Any {
                Name(FILTER_NAME)
            }
        }.filter { seenDevicesAddress.add(it.peripheral.address) }
            .map {
                wrapDevice(it)
            }
            .onEach { newDevice ->
                observePeripheralState(newDevice.peripheral, scope)
                onPeripheralSelected(newDevice.peripheral)
            }
            .catch { e ->

            }
            .onCompletion {

            }
            .launchIn(scope)
    }

    private fun observePeripheralState(
        peripheral: Peripheral,
        scope: CoroutineScope
    ) {
        observedPeripheralJobs[peripheral.address]?.cancel() observedPeripheralJobs . remove (peripheral.address)

        val job = peripheral.state
            .onEach {
                when (it) {
                    is ConnectionState.Connected -> {

                    }

                    is ConnectionState.Disconnected -> {

                    }

                    else -> {

                    }
                }
            }
            .onCompletion {
                observedPeripheralJobs.remove(peripheral.address)
            }
            .launchIn(scope)

        observedPeripheralJobs[peripheral.address] = job
    }

    fun onPeripheralSelected(peripheral: Peripheral, autoConnect: Boolean = false) {
        val connectionScope = connectionScopeMap[peripheral]
        connectionScope?.launch {
            try {
                peripheral.disconnect()
            } catch (e: Exception) {

            }
        } ?: run {
            connectionScopeMap[peripheral] = CoroutineScope(context = Dispatchers.IO)
                .apply {
                    launch {
                        try {
                            withTimeout(CONNECT_TIMEOUT) {
                                connect(peripheral, autoConnect)
                            }

                            observeServices(peripheral, scope)
                        } catch (e: Exception) {
                            connectionScopeMap.remove(peripheral)?.cancel()
                        }
                    }
                }
        }
    }

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions