What happens
ForegroundService.detectServiceType() adds FOREGROUND_SERVICE_TYPE_MICROPHONE
whenever RECORD_AUDIO is granted, rather than when the phone microphone is
actually about to be used:
// mobile/modules/bluetooth-sdk/android/.../services/Foreground.kt:135
val hasMicPermission =
ContextCompat.checkSelfPermission(this, android.Manifest.permission.RECORD_AUDIO) ==
PackageManager.PERMISSION_GRANTED
if (hasMicPermission) {
serviceType = serviceType or ServiceInfo.FOREGROUND_SERVICE_TYPE_MICROPHONE
Android 14+ refuses to start a microphone-type foreground service from the
background. So for any SDK consumer that holds RECORD_AUDIO, every background start
— BOOT_COMPLETED, MY_PACKAGE_REPLACED — throws SecurityException and the app
dies silently.
Why it matters
My app is an always-on capture relay. It reads the glasses microphone over BLE GATT
and never opens the phone's own microphone, but the AAR merges RECORD_AUDIO into the
manifest, so it inherited the mic FGS type and could not survive a reboot. There was no
crash dialog and no log I was watching — it simply never came back, four reboots deep,
before I went looking.
Workaround
Strip the permission entirely, which requires an explicit removal because the AAR
merges its own copy back:
<uses-permission android:name="android.permission.RECORD_AUDIO" tools:node="remove" />
The SDK's PhoneMic fallback then logs permission_denied if it is ever engaged,
which is acceptable for a glasses-only consumer.
Suggested fix
Gate the microphone FGS type on whether the phone mic is actually going to be opened
(mic preference / active fallback state), not on whether the permission happens to be
granted. Consumers that only ever use the glasses mic would then keep working across
background restarts without having to fight the manifest merger.
What happens
ForegroundService.detectServiceType()addsFOREGROUND_SERVICE_TYPE_MICROPHONEwhenever
RECORD_AUDIOis granted, rather than when the phone microphone isactually about to be used:
Android 14+ refuses to start a microphone-type foreground service from the
background. So for any SDK consumer that holds
RECORD_AUDIO, every background start—
BOOT_COMPLETED,MY_PACKAGE_REPLACED— throwsSecurityExceptionand the appdies silently.
Why it matters
My app is an always-on capture relay. It reads the glasses microphone over BLE GATT
and never opens the phone's own microphone, but the AAR merges
RECORD_AUDIOinto themanifest, so it inherited the mic FGS type and could not survive a reboot. There was no
crash dialog and no log I was watching — it simply never came back, four reboots deep,
before I went looking.
Workaround
Strip the permission entirely, which requires an explicit removal because the AAR
merges its own copy back:
The SDK's
PhoneMicfallback then logspermission_deniedif it is ever engaged,which is acceptable for a glasses-only consumer.
Suggested fix
Gate the microphone FGS type on whether the phone mic is actually going to be opened
(mic preference / active fallback state), not on whether the permission happens to be
granted. Consumers that only ever use the glasses mic would then keep working across
background restarts without having to fight the manifest merger.