When I test ble advertising with your Galaxy Watch hundreds of times in a row, I got too many advertisers error and Bluetooth will no longer work. If I turn off Bluetooth in your watch settings or reboot the device, it will function normally again.
Below is my BleAdvertising code
object BleAdvertiserManager {
private var bluetoothLeAdvertiser: BluetoothLeAdvertiser? = null
private var advertisingSetCallback: AdvertisingSetCallback? = null
private var bluetoothManager: BluetoothManager? = null
private var bluetoothAdapter: BluetoothAdapter? = null
fun startAdvertising(context: Context, handleError: () -> Unit) {
bluetoothManager = context.getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager
bluetoothAdapter = bluetoothManager?.adapter
if (bluetoothAdapter?.isEnabled == false) {
Timber.e("Bluetooth not enabled")
return
}
if (bluetoothLeAdvertiser == null) {
bluetoothLeAdvertiser = bluetoothAdapter?.bluetoothLeAdvertiser
}
@SuppressLint("SimpleDateFormat")
advertisingSetCallback = object : AdvertisingSetCallback() {
override fun onAdvertisingSetStarted(
advertisingSet: AdvertisingSet?,
txPower: Int,
status: Int,
) {
super.onAdvertisingSetStarted(advertisingSet, txPower, status)
handleStatus(status, advertisingSet, handleError)
}
override fun onAdvertisingDataSet(advertisingSet: AdvertisingSet?, status: Int) {
super.onAdvertisingDataSet(advertisingSet, status)
handleStatus(status, advertisingSet, handleError)
}
override fun onAdvertisingSetStopped(advertisingSet: AdvertisingSet?) {
super.onAdvertisingSetStopped(advertisingSet)
advertisingSet?.enableAdvertising(false, 0, 0)
}
}
val parameters = AdvertisingSetParameters.Builder()
.setScannable(true)
.setConnectable(true)
.setLegacyMode(true)
.setInterval(AdvertisingSetParameters.INTERVAL_HIGH)
.setTxPowerLevel(AdvertisingSetParameters.TX_POWER_HIGH)
.build()
bluetoothLeAdvertiser?.stopAdvertisingSet(advertisingSetCallback)
bluetoothLeAdvertiser?.startAdvertisingSet(
parameters,
oneData,
null,
null,
null,
advertisingSetCallback
)
}
@SuppressLint("SimpleDateFormat")
private fun handleStatus(
status: Int,
advertisingSet: AdvertisingSet?,
handleError: () -> Unit
) {
when (status) {
ADVERTISE_FAILED_ALREADY_STARTED -> Timber.e("Already started")
ADVERTISE_FAILED_DATA_TOO_LARGE -> Timber.e("Data too large")
ADVERTISE_FAILED_FEATURE_UNSUPPORTED -> Timber.e("Feature unsupported")
ADVERTISE_FAILED_INTERNAL_ERROR -> Timber.e("Internal error")
ADVERTISE_FAILED_TOO_MANY_ADVERTISERS -> {
handleError()
}
ADVERTISE_SUCCESS -> {
CoroutineScope(Dispatchers.IO).launch {
advertisingSet?.let {
it.setAdvertisingData(switchData) // switch One / Two Data
it.enableAdvertising(false, 0, 0)
it.enableAdvertising(true, 0, 0)
}
}
}
else -> Timber.e("Unknown error")
}
}
fun stopAdvertising() {
advertisingSetCallback?.let {
bluetoothLeAdvertiser?.stopAdvertisingSet(it)
}
advertisingSetCallback = null
bluetoothLeAdvertiser = null
}
}
I am trying to advertise one / two data when they advertise success But As mentioned above, if I try again after trying hundreds of times, I get too many advertisers error.
Below is my operating start / stop advertising code
LifecycleResumeEffect(key1 = Unit) {
context.getActivity()?.window?.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
?: Timber.e("Activity is Empty")
BleAdvertiserManager.startAdvertising(context, cardInfo, handleError)
onPauseOrDispose {
context.getActivity()?.window?.clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
BleAdvertiserManager.stopAdvertising()
}
}
If I enter this screen start advertising and after 7 seconds popbackstack.
When I enter this screen try again after trying hundreds of times, I get too many advertisers error.