You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android Kotlin中Ant+设备重复选择:如何实现单次自动连接?

如何实现ANT+设备的单次自动连接(无需多次手动选择)

我正在用Kotlin开发Android应用,需要通过蓝牙连接支持ANT+协议的设备,获取踏频(Cadence)、速度(Speed)以及健身设备相关数据。目前的代码需要手动三次选择目标设备,请问有没有办法实现单次自动选择设备?

当前实现代码:

private fun setPanoramaChangeListener() {
    //some code
    setupAntSampler()
    //some code
}

private fun setupAntSampler() {
    bsdReleaseHandle = AntPlusBikeSpeedDistancePcc.requestAccess(
        this, this,
        mResultReceiver, mDeviceStateChangeReceiver
    )
}

var mResultReceiver: IPluginAccessResultReceiver<AntPlusBikeSpeedDistancePcc> =
    object :
        IPluginAccessResultReceiver<AntPlusBikeSpeedDistancePcc> {
        override fun onResultReceived(
            result: AntPlusBikeSpeedDistancePcc?,
            resultCode: RequestAccessResult?, initialDeviceState: DeviceState?
        ) {
            when (resultCode) {
                RequestAccessResult.SUCCESS -> {
                    HomeActivity.bsdPcc = result
                    subscribeToEvents()
                }
            }
            releaseHandle = AntPlusFitnessEquipmentPcc.requestNewOpenAccess(
                this@TourActivity,
                this@TourActivity, mPluginAccessResultReceiver, mDeviceStateChangeReceiver,
                mFitnessEquipmentStateReceiver
            )
        }

private fun subscribeToEvents() {
    bcPcc?.subscribeCalculatedCadenceEvent { _, _, calculatedCadence ->
        runOnUiThread {
            cadenceDoubleList.add(calculatedCadence.toDouble())
            if (maxCadence < calculatedCadence.toDouble())
                maxCadence = calculatedCadence.toDouble()
        }
    }
    bcPcc?.subscribeRawCadenceDataEvent { _, _, _, _ ->
        runOnUiThread {
            // 注释代码
        }
    }
    if (bcPcc?.isSpeedAndCadenceCombinedSensor == true) {
        runOnUiThread {
            bsdReleaseHandle = AntPlusBikeSpeedDistancePcc.requestAccess(
                this@TourActivity, bcPcc?.antDeviceNumber ?: 0, 0, true,
                mResultReceiver, mDeviceStateChangeReceiver
            )
        }
    } else {
        runOnUiThread {
            // 注释代码
        }
        bcPcc?.subscribeCumulativeOperatingTimeEvent { _, _, _ ->
            runOnUiThread {
                // 注释代码
            }
        }
        bcPcc?.subscribeManufacturerAndSerialEvent { _, _, _, _ ->
            runOnUiThread {
                // 注释代码
            }
        }
        bcPcc?.subscribeVersionAndModelEvent { _, _, _, _, _ ->
            runOnUiThread {
                // 注释代码
            }
        }
        bcPcc?.subscribeBatteryStatusEvent { _, _, _, _ ->
            runOnUiThread {
                // 注释代码
            }
        }
        bcPcc?.subscribeMotionAndCadenceDataEvent { _, _, _ ->
            runOnUiThread {
                // 注释代码
            }
        }
    }
}

解决方案:通过预扫描+指定设备号实现自动连接

当前代码需要三次手动选择的核心原因:多次调用无设备号的requestAccess/requestNewOpenAccess,每次都会触发系统选择弹窗;且在组合传感器逻辑中重复发起连接请求。可以通过以下步骤优化:

1. 预扫描并缓存目标设备信息

一次性扫描所有可用ANT+设备,筛选出需要的类型(踏频/速度传感器、健身设备),记录设备号(antDeviceNumber):

private var cachedCadenceSpeedDeviceNumber: Int? = null
private var cachedFitnessDeviceNumber: Int? = null

private fun scanAntDevices() {
    val scanner = AntScanner(this)
    scanner.setScanCallback(object : AntScanner.ScanCallback {
        override fun onDeviceFound(device: AntDevice) {
            // 筛选目标设备类型
            when (device.deviceType) {
                AntDeviceType.TYPE_BIKE_SPEED_CADENCE -> {
                    cachedCadenceSpeedDeviceNumber = device.number
                }
                AntDeviceType.TYPE_FITNESS_EQUIPMENT -> {
                    cachedFitnessDeviceNumber = device.number
                }
            }
        }

        override fun onScanFinished() {
            // 扫描完成后自动连接所有缓存设备
            connectToAntDevices()
        }
    })
    scanner.startScan()
}

2. 指定设备号发起连接,跳过手动选择

直接用缓存的设备号调用连接API,避免触发选择弹窗:

private fun connectToAntDevices() {
    // 连接踏频/速度传感器
    cachedCadenceSpeedDeviceNumber?.let { deviceNumber ->
        bsdReleaseHandle = AntPlusBikeSpeedDistancePcc.requestAccess(
            this@TourActivity,
            deviceNumber,
            0,
            true, // 启用自动连接
            mBsdResultReceiver,
            mDeviceStateChangeReceiver
        )
    }

    // 连接健身设备
    cachedFitnessDeviceNumber?.let { deviceNumber ->
        releaseHandle = AntPlusFitnessEquipmentPcc.requestNewOpenAccess(
            this@TourActivity,
            this@TourActivity,
            mFitnessAccessResultReceiver,
            mDeviceStateChangeReceiver,
            mFitnessEquipmentStateReceiver
        )
    }
}

3. 优化传感器事件订阅逻辑

如果是踏频+速度组合传感器,无需重复发起连接,直接通过已有PCC实例订阅速度事件:

private fun subscribeToEvents() {
    bcPcc?.subscribeCalculatedCadenceEvent { _, _, calculatedCadence ->
        runOnUiThread {
            cadenceDoubleList.add(calculatedCadence.toDouble())
            if (maxCadence < calculatedCadence.toDouble())
                maxCadence = calculatedCadence.toDouble()
        }
    }

    // 组合传感器直接订阅速度事件,无需重新连接
    if (bcPcc?.isSpeedAndCadenceCombinedSensor == true) {
        bcPcc?.subscribeCalculatedSpeedEvent { _, _, calculatedSpeed ->
            runOnUiThread {
                // 处理速度数据逻辑
            }
        }
    } else {
        // 纯踏频传感器的事件订阅逻辑(保持原有代码)
    }
}

4. 修改初始化流程

将原来的setupAntSampler改为启动扫描:

private fun setupAntSampler() {
    scanAntDevices()
}

注意事项

  • 权限配置:确保AndroidManifest.xml中添加ANT+权限:
    <uses-permission android:name="com.dsi.ant.permission.ANT" />
    <uses-permission android:name="com.dsi.ant.permission.ANT_ADMIN" />
    
  • 首次配对:首次使用可能需要手动配对一次,之后可将设备号持久化存储(如SharedPreferences),下次启动直接连接。
  • 错误处理:添加连接失败的回调逻辑,例如设备未找到时提示用户重新扫描。

内容的提问来源于stack exchange,提问作者bircastri

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 10:14:57