admin管理员组

文章数量:1289542

Using a Pixel 9 Pro Fold with Android 15, I developed an app that functions as a peripheral, while the notebook (NB) runs an app as a central. When the NB pairs with the peripheral, the pairing is successful, but during the connection process, both apps keep disconnecting and reconnecting repeatedly. Additionally, it keeps requesting pairing. However, if I skip the pairing step and directly connect, everything works fine.

Has anyone else encountered this issue? How did you solve it?

If the Pixel 9 is used as the central and the NB as the peripheral, the connection works normally after pairing.

@SuppressLint("MissingPermission")
private fun bleStartAdvertising() {
    isAdvertising = true
    bleStartGattServer()
    bleAdvertiser.startAdvertising(advertiseSettings, advertiseData, scanResponse, advertiseCallback)
}

@SuppressLint("MissingPermission")
private fun bleStopAdvertising() {
    isAdvertising = false
    bleStopGattServer()
    bleAdvertiser.stopAdvertising(advertiseCallback)
}

@SuppressLint("MissingPermission")
private fun bleStartGattServer() {
    val gattServer = bluetoothManager.openGattServer(this, gattServerCallback)
    val service = BluetoothGattService(UUID.fromString(SERVICE_UUID), BluetoothGattService.SERVICE_TYPE_PRIMARY)
    var charForRead = BluetoothGattCharacteristic(UUID.fromString(CHAR_FOR_READ_UUID),
            BluetoothGattCharacteristic.PROPERTY_READ,
            BluetoothGattCharacteristic.PERMISSION_READ)
    var charForWrite = BluetoothGattCharacteristic(UUID.fromString(CHAR_FOR_WRITE_UUID),
            BluetoothGattCharacteristic.PROPERTY_WRITE,
            BluetoothGattCharacteristic.PERMISSION_WRITE)
    var charForIndicate = BluetoothGattCharacteristic(UUID.fromString(CHAR_FOR_INDICATE_UUID),
            BluetoothGattCharacteristic.PROPERTY_INDICATE,
            BluetoothGattCharacteristic.PERMISSION_READ)
    var charConfigDescriptor = BluetoothGattDescriptor(UUID.fromString(CCC_DESCRIPTOR_UUID),
            BluetoothGattDescriptor.PERMISSION_READ or BluetoothGattDescriptor.PERMISSION_WRITE)
    charForIndicate.addDescriptor(charConfigDescriptor)

    service.addCharacteristic(charForRead)
    service.addCharacteristic(charForWrite)
    service.addCharacteristic(charForIndicate)

    val result = gattServer.addService(service)
    this.gattServer = gattServer
    appendLog("addService " + when(result) {
        true -> "OK"
        false -> "fail"
    })
}

@SuppressLint("MissingPermission")
private fun bleStopGattServer() {
    gattServer?.close()
    gattServer = null
    appendLog("gattServer closed")
    runOnUiThread {
        textViewConnectionState.text = getString(R.string.text_disconnected)
    }
}

private val bluetoothManager: BluetoothManager by lazy {
    getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager
}

private val bluetoothAdapter: BluetoothAdapter by lazy {
    bluetoothManager.adapter
}

//region BLE advertise
private val bleAdvertiser by lazy {
    bluetoothAdapter.bluetoothLeAdvertiser
}

private val advertiseSettings = AdvertiseSettings.Builder()
        .setAdvertiseMode(AdvertiseSettings.ADVERTISE_MODE_BALANCED)
        .setTxPowerLevel(AdvertiseSettings.ADVERTISE_TX_POWER_MEDIUM)
        .setConnectable(true)
        .build()

private val advertiseData = AdvertiseData.Builder()
        .setIncludeDeviceName(false) // don't include name, because if name size > 8 bytes, ADVERTISE_FAILED_DATA_TOO_LARGE
        .addServiceUuid(ParcelUuid(UUID.fromString(SERVICE_UUID)))
        .build()

private val scanResponse = AdvertiseData.Builder()
        .setIncludeDeviceName(true)
        .build()

private val advertiseCallback = object : AdvertiseCallback() {
    override fun onStartSuccess(settingsInEffect: AdvertiseSettings) {
        appendLog("Advertise start success\n$SERVICE_UUID")
    }

    override fun onStartFailure(errorCode: Int) {
        val desc = when (errorCode) {
            ADVERTISE_FAILED_DATA_TOO_LARGE -> "\nADVERTISE_FAILED_DATA_TOO_LARGE"
            ADVERTISE_FAILED_TOO_MANY_ADVERTISERS -> "\nADVERTISE_FAILED_TOO_MANY_ADVERTISERS"
            ADVERTISE_FAILED_ALREADY_STARTED -> "\nADVERTISE_FAILED_ALREADY_STARTED"
            ADVERTISE_FAILED_INTERNAL_ERROR -> "\nADVERTISE_FAILED_INTERNAL_ERROR"
            ADVERTISE_FAILED_FEATURE_UNSUPPORTED -> "\nADVERTISE_FAILED_FEATURE_UNSUPPORTED"
            else -> ""
        }
        appendLog("Advertise start failed: errorCode=$errorCode $desc")
        isAdvertising = false
    }
}
//endregion

The NB's central is using Microsoft's sample program.

本文标签: