为什么部分 Android 版本 App 锁屏或切后台音视频采集或播放(渲染)无效?
更新时间不可用
问题现象
- Android 设备锁屏 1 分钟内,远端音频无声或看不到视频。
- Android App 在运行过程中切换到后台,远端音频无声。
问题原因
- 自 Android 9 版本起,Android 系统对于后台 App 访问用户数据进行了限制。详见 Android 9 行为变更。
- 自 Android 14 版本起,Android 系统要求 App 指定必需的前台服务类型。如果开发者将 App 的
targetSdkVersion设置为34或更高,当 App 在 Android 14 或更高版本的设备上运行时,系统会触发容性检查,以验证 App 是否已正确声明其前台服务类型。如果 App 未能正确集成前台服务,用户将 App 切换到后台时,可能会遇到麦克风采集无效、远端音频无声等问题。详见 Android 14 行为变更和必需的前台服务类型。
解决方案
你需要正确集成前台服务,确保设备处于锁屏状态或 App 切换到后台时,仍能正常访问并使用麦克风、摄像头、媒体播放等功能,从而避免因系统限制造成音视频采集中断。声网提供了集成前台服务的示例项目供你参考,具体步骤如下:
-
在
AndroidManifest.xml文件中,声明前台服务权限 (FOREGROUND_SERVICE) 并指定前台服务类型 (foregroundServiceType)。对于实时音视频互动 App 来说,通常需要指定麦克风 (microphone)、摄像头(camera) 和媒体播放 (mediaPlayback) 服务类型。示例代码如下:XML <manifest ...> <!-- 声明前台服务权限 --> <uses-permission android:name="android.permission.FOREGROUND_SERVICE" /> <uses-permission android:name="android.permission.FOREGROUND_SERVICE_MICROPHONE" /> <uses-permission android:name="android.permission.FOREGROUND_SERVICE_CAMERA" /> <uses-permission android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PLAYBACK" /> <application ...> ... <!-- 指定前台服务类型 --> <service android:name=".YourForegroundService" android:foregroundServiceType="microphone|camera|mediaPlayback" /> ... </application> </manifest> -
当服务被创建时,调用
startForeground将指定服务提升为前台服务。示例代码如下:Java @Override public void onCreate() { super.onCreate(); // 获取默认的通知 Notification notification = getDefaultNotification(); try { // 根据 Android 版本,选择合适的方式处理前台服务 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { // 对于 Android 11 及以上版本,启动前台服务并指定多种服务类型 int serviceTypes = ServiceInfo.FOREGROUND_SERVICE_TYPE_MICROPHONE | ServiceInfo.FOREGROUND_SERVICE_TYPE_CAMERA | ServiceInfo.FOREGROUND_SERVICE_TYPE_MEDIA_PLAYBACK; this.startForeground(NOTIFICATION_ID, notification, serviceTypes); } else { // 对于 Android 11 以下版本,无需指定服务类型,简单地启动前台服务即可 this.startForeground(NOTIFICATION_ID, notification); } } catch (Exception ex) { Log.e(TAG, "Error starting foreground service", ex); } } -
当 App 切换到后台时,调用
startForegroundService启动服务,确保服务的持续运行。示例代码如下:Java @Override public void onPause() { super.onPause(); startRecordingService(); } private void startRecordingService() { if (joined) { // 创建一个 intent Intent intent = new Intent(requireContext(), LocalRecordingService.class); // 根据 Android 版本,选择合适的方式启动前台服务 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { // 对于 Android 8 及以上版本,使用 startForegroundService 来启动服务 requireContext().startForegroundService(intent); } else { // 对于 Android 8 以下版本,使用 startService 来启动服务 requireContext().startService(intent); } } }
如需更多信息,请参考以下官方文档: