SO, let me start with the immediate answer here:
Is there any supported way to ensure notification sounds consistently route through connected Bluetooth/external speakers?
Basically, no. Your app has no direct control over how notification audio is routed.
Our app sends push notifications with a custom sound file using the sound parameter in the APNs payload.
What's the nature of the audio you're trying to send? In particular, if this is "communication" of some kind, then you might want to consider using the PushToTalk framework, which would give you much more control over exactly how audio is played.
Is this routing behavior expected for push notification sounds?
The word "expected" is a tricky one here, as it's clearly not the system "goal" to have the notification route audio in a "weird" way. I've provided a bit more background on why this happens below, but here is how I'd describe the state of things:
-
The expected behavior is that, ignoring exceptions, alerts critical alerts or ringtones, notification audio will be handled in a “consistent" way, so that "all" notification audio is played and routed in the same way in any given configuration.
-
The details of the audio configuration do change how notification audio is routed. The primary factor here should be the audio device (speaker, headset, etc.) and its current state, not the iOS device.
Are notification sounds intentionally restricted from routing to Bluetooth in certain conditions (e.g., device locked, system policy, audio session state)?
Sort of. The primary factor here is that the system can be "connected" to a device (meaning, it's aware of the device and has an active Bluetooth connection with it) without actually having an active audio channel (meaning, it's able to play audio NOW). The notification system doesn't want to force the channel open to brief audio, so it plays it on the local device.
Note that this is why this "always" works:
Media playback (e.g., YouTube or Music) routes correctly to Bluetooth, so the connection itself is functioning properly.
...since that's obviously opening the channel.
The inconsistent behavior across devices makes it difficult to determine whether this is by design or a configuration issue.
Strictly speaking, it's typically a configuration issue, but the "configuration" here is the audio device, not the iOS device. This is also why you tend to see patterns across devices— for example, many car heads units send a "play" command when a device connects over Bluetooth, which ends up activating the A2DP channel... to notifications tend to be played over car speakers. Headsets tend to avoid this (to save power), which means they're less likely to play.
__
Kevin Elliott
DTS Engineer, CoreOS/Hardware