Skip to content

Foreground service takes microphone type from RECORD_AUDIO being granted, blocking all background restarts on Android 14+ #3775

Description

@CarlKho-Minerva

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.

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