React Native应用用HBRecorder时,Play Store装应用致录音静音问题
React Native中HBRecorder录制音频被Play Store安装行为静音的问题处理
问题描述
在React Native应用中使用HBRecorder实现屏幕音视频录制时,遇到一个异常情况:从Play Store安装其他应用时,录音功能会被静音,推测是音频权限冲突导致录音失效。该问题在HBRecorder的演示项目和实际集成场景中均会出现,期望实现以下任一效果:
- 权限被抢占时收到通知
- 自动停止录制(当前视频仍能正常录制,但音频丢失)
- 保持应用对音频权限的独占性
核心错误日志
2023-08-29 11:53:46.844 1505-7216 AppOps system_server E evalMode() Foreground Record OP returned IGNORE, uid - 10980, capability - 8 2023-08-29 11:53:46.845 1291-1751 AudioPolicyService audioserver I App op 27 missing, silencing record AttributionSourceState{pid: 15457, uid: 10980, packageName: com.hbisoft.hbrecorderexample, attributionTag: (null), token: {no toString() implemented}, renouncedPermissions: [], next: []}
完整日志信息
2023-08-29 11:53:46.811 1246-15535 QC2C2DEngine media.hwcodec I calcYSize: unsupported or RGB color format, RGBA8888(1) 2023-08-29 11:53:46.828 1246-15535 QC2C2DEngine media.hwcodec I calcYSize: unsupported or RGB color format, RGBA8888(1) 2023-08-29 11:53:46.840 1225-8088 sensors-hal and....sensors@2.0-service.multihal I handle_sns_std_sensor_event:231, [SSC_LIGHT] P: 43(43),als:169,green:36,ir:4,delta_avg:0,delta_max:94,stdev:0,stdev_per_4sample:1,magig_code or itime:384 2023-08-29 11:53:46.844 1246-15535 QC2C2DEngine media.hwcodec I calcYSize: unsupported or RGB color format, RGBA8888(1) 2023-08-29 11:53:46.844 1505-7216 AppOps system_server E evalMode() Foreground Record OP returned IGNORE, uid - 10980, capability - 8 2023-08-29 11:53:46.845 1291-1751 AudioPolicyService audioserver I App op 27 missing, silencing record AttributionSourceState{pid: 15457, uid: 10980, packageName: com.hbisoft.hbrecorderexample, attributionTag: (null), token: {no toString() implemented}, renouncedPermissions: [], next: []} 2023-08-29 11:53:46.862 1246-15535 QC2C2DEngine media.hwcodec I calcYSize: unsupported or RGB color format, RGBA8888(1) 2023-08-29 11:53:46.868 3282-4415 ViewRootIm...orOverlay] com.android.systemui I dispatchDetachedFromWindow 2023-08-29 11:53:46.871 1505-7260 InputManager-JNI system_server W Input channel object '1e63692 ScreenDecorOverlay (client)' was disposed without first being removed with the input manager! 2023-08-29 11:53:46.873 1505-7260 WindowManager system_server I Destroying surface Surface(name=ScreenDecorOverlay$_3282)/@0x6b21ba2 called by com.android.server.wm.WindowStateAnimator.destroySurface:942 com.android.server.wm.WindowStateAnimator.destroySurfaceLocked:536 com.android.server.wm.WindowState.removeImmediately:2969 com.android.server.wm.WindowState.removeIfPossible:3227 com.android.server.wm.WindowState.removeIfPossible:3040 com.android.server.wm.WindowManagerService.removeWindow:2282 com.android.server.wm.Session.remove:236 android.view.IWindowSession$Stub.onTransact:743 2023-08-29 11:53:46.875 1505-1607 Looper system_server W Drained
设备与环境信息
- 设备:三星A52s (SM-A528B)
- Android版本:13
- SDK版本:33
已声明权限(AndroidManifest.xml)
<uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.WRITE_INTERNAL_STORAGE"/> <uses-permission android:name="android.permission.RECORD_AUDIO"/> <uses-permission android:name="android.permission.FOREGROUND_SERVICE"/> <uses-permission android:name="android.permission.VIBRATE"/> <uses-permission android:name="android.permission.CAMERA" /> <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> <uses-permission android:name="android.permission.POST_NOTIFICATIONS"/> <uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM"/> <uses-permission android:name="android.permission.USE_EXACT_ALARM"/> <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
解决方案尝试方向
1. 监听音频录制状态变化
Android 10+提供AudioManager.ACTION_AUDIO_RECORDING_STATE_CHANGED广播,注册接收器监听录制状态,当状态变为停止时,触发录制停止逻辑并通知React Native:
val filter = IntentFilter(AudioManager.ACTION_AUDIO_RECORDING_STATE_CHANGED) registerReceiver(object : BroadcastReceiver() { override fun onReceive(context: Context?, intent: Intent?) { val state = intent?.getIntExtra(AudioManager.EXTRA_AUDIO_RECORDING_STATE, -1) if (state == AudioManager.AUDIO_RECORDING_STATE_STOPPED) { // 通知React Native音频丢失,停止录制 sendEventToReactNative("recording_audio_lost", null) } } }, filter)
2. 强化前台服务优先级
录制时确保服务以前台模式运行,提升进程优先级:
- 确认
FOREGROUND_SERVICE权限已声明 - 启动录制时调用HBRecorder的前台服务配置接口,设置持续显示的通知内容
3. 主动检查AppOps权限状态
日志中App op 27 missing对应录音权限的AppOps状态异常,可在录制前后主动检查:
val appOpsManager = getSystemService(Context.APP_OPS_SERVICE) as AppOpsManager val mode = appOpsManager.checkOpNoThrow(AppOpsManager.OPSTR_RECORD_AUDIO, android.os.Process.myUid(), packageName) if (mode != AppOpsManager.MODE_ALLOWED) { // 权限异常,停止录制并提示用户 }
4. 尝试独占音频输入设备
修改HBRecorder底层音频配置,设置独占模式:
val audioAttributes = AudioAttributes.Builder() .setUsage(AudioAttributes.USAGE_MEDIA) .setContentType(AudioAttributes.CONTENT_TYPE_MUSIC) .build() val audioFormat = AudioFormat.Builder() .setSampleRate(44100) .setEncoding(AudioFormat.ENCODING_PCM_16BIT) .setChannelMask(AudioFormat.CHANNEL_IN_MONO) .build() val audioRecord = AudioRecord.Builder() .setAudioAttributes(audioAttributes) .setAudioFormat(audioFormat) .setBufferSizeInBytes(AudioRecord.getMinBufferSize(44100, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT)) .setExclusive(true) .build()
5. 三星设备特殊适配
三星Android 13可能有自定义音频策略,可尝试添加三星特定权限:
<uses-permission android:name="com.samsung.android.providers.context.permission.WRITE_USE_APP_FEATURE_SURVEY"/>
同时检查设备权限管理器中是否有额外的录音限制项,确保应用允许后台录制音频。
内容的提问来源于stack exchange,提问作者rkenan
相关产品推荐
相关产品推荐

