Android API 31+ 耳机媒体按键检测方案求助
Android API 31+ 耳机媒体按键可靠接收方案
针对API31+下无法稳定接收耳机媒体按键(尤其是后台/锁屏场景)的问题,先梳理现有方案的核心缺陷,再给出官方标准的可行方案:
现有方案的问题分析
- MediaSession配置缺失关键参数:仅激活MediaSession但未请求音频焦点、未设置活跃播放状态,系统不会将媒体按键事件分发给非活跃的媒体会话。
- 静态注册BroadcastReceiver失效:API26+(Oreo)后,
MEDIA_BUTTON这类隐式广播被禁止静态注册(系统例外广播除外),清单中注册的接收器无法收到事件。 - 动态注册BroadcastReceiver稳定性差:APP进入后台后,动态注册的接收器会被系统自动注销,且无音频焦点时系统不会分发事件。
- onKeyDown仅适用于前台Activity:该方法仅在Activity获得焦点时生效,锁屏、后台场景完全失效。
官方标准可行方案:前台Service+MediaSession(推荐)
要在后台/锁屏下稳定接收按键,必须让音频会话处于系统认可的活跃状态,同时用前台Service避免被系统回收。以下是完整实现步骤:
1. 创建前台Service托管MediaSession
Service是后台运行的组件,配合前台状态可绕过API26+的后台限制,同时托管MediaSession确保会话持续活跃。
class RecorderMediaService : Service() { private lateinit var mediaSession: MediaSession private lateinit var audioManager: AudioManager private val audioFocusRequest: AudioFocusRequest by lazy { // 请求录制音频的焦点,匹配MediaRecorder场景 AudioFocusRequest.Builder(AudioManager.AUDIOFOCUS_RECORD) .setOnAudioFocusChangeListener { focusChange -> // 处理焦点变化,比如失去焦点时停止录制 when (focusChange) { AudioManager.AUDIOFOCUS_LOSS -> { // 执行停止录制、释放资源逻辑 } } } .build() } override fun onCreate() { super.onCreate() audioManager = getSystemService(AUDIO_SERVICE) as AudioManager // 先请求音频焦点,获得焦点后再初始化MediaSession if (audioManager.requestAudioFocus(audioFocusRequest) == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) { initMediaSession() // 启动前台Service,避免被系统回收 startForeground( 1001, Notification.Builder(this, "Recorder_Channel") .setContentTitle("音频录制中") .setSmallIcon(R.drawable.ic_recording) .build() ) } } private fun initMediaSession() { mediaSession = MediaSession(this, "RecorderMediaSession") mediaSession.setCallback(object : MediaSession.Callback() { override fun onMediaButtonEvent(mediaButtonIntent: Intent): Boolean { val keyEvent = mediaButtonIntent.getParcelableExtra<KeyEvent>(Intent.EXTRA_KEY_EVENT) keyEvent?.let { // 处理耳机按键:覆盖媒体按键和通话按键(KEYCODE_HEADSETHOOK) when (it.keyCode) { KeyEvent.KEYCODE_HEADSETHOOK, KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE -> { Log.d("MediaKey", "耳机按键触发,执行录制/暂停") // 添加你的录制控制逻辑 return true // 消费事件,避免传递给其他应用 } KeyEvent.KEYCODE_MEDIA_NEXT, KeyEvent.KEYCODE_MEDIA_PREVIOUS -> { // 处理其他按键需求 return true } } } return super.onMediaButtonEvent(mediaButtonIntent) } }) // 设置播放状态为活跃(STATE_PLAYING),告知系统当前会话处于工作状态 mediaSession.setPlaybackState( PlaybackState.Builder() .setState(PlaybackState.STATE_PLAYING, 0, 1.0f) .build() ) mediaSession.isActive = true } override fun onDestroy() { super.onDestroy() // 释放资源 mediaSession.release() audioManager.abandonAudioFocusRequest(audioFocusRequest) } override fun onBind(intent: Intent): IBinder? = null }
2. 清单注册Service
添加必要权限和前台服务类型,适配API31+要求:
<manifest ...> <!-- 录制音频权限 --> <uses-permission android:name="android.permission.RECORD_AUDIO" /> <!-- 前台服务权限 --> <uses-permission android:name="android.permission.FOREGROUND_SERVICE" /> <uses-permission android:name="android.permission.FOREGROUND_SERVICE_MICROPHONE" /> <application ...> <service android:name=".RecorderMediaService" android:foregroundServiceType="microphone" /> </application> </manifest>
3. 启动Service
在需要开始录制的场景(如Activity按钮点击)启动Service:
// 检查录制权限后启动Service if (ContextCompat.checkSelfPermission(this, Manifest.permission.RECORD_AUDIO) == PackageManager.PERMISSION_GRANTED) { startService(Intent(this, RecorderMediaService::class.java)) }
关键说明
- 音频焦点:必须请求与场景匹配的音频焦点(录制用
AUDIOFOCUS_RECORD),系统只会将媒体按键事件分发给拥有焦点的应用。 - 前台Service:API26+后后台Service会被系统限制,前台Service可保证组件持续运行,即使锁屏或APP切换到后台。
- MediaSession状态:设置
STATE_PLAYING是核心,系统只会向活跃的媒体会话分发按键事件。 - 按键覆盖:部分耳机的通话按键对应
KEYCODE_HEADSETHOOK,需与媒体按键一同处理。
兼容方案:MediaSessionCompat
若需兼容旧版本API,可改用MediaSessionCompat,核心逻辑一致,调整初始化代码即可:
private lateinit var mediaSessionCompat: MediaSessionCompat private fun initMediaSessionCompat() { mediaSessionCompat = MediaSessionCompat(this, "RecorderMediaSession") mediaSessionCompat.setFlags(MediaSessionCompat.FLAG_HANDLES_MEDIA_BUTTONS) mediaSessionCompat.setCallback(object : MediaSessionCompat.Callback() { override fun onMediaButtonEvent(mediaButtonIntent: Intent): Boolean { // 按键处理逻辑与上述一致 return true } }) mediaSessionCompat.isActive = true }
内容的提问来源于stack exchange,提问作者RatherBeSailing
相关产品推荐
相关产品推荐

