Android 13下WebView应用锁屏后持续播放网页音频的实现咨询
Android 13下WebView屏幕关闭后持续播放音频的实现方案
你的思路是对的,Android 13对后台进程限制严格,只有前台Service能保证进程不被系统杀死,从而让WebView中的音频持续播放。以下是具体实现步骤:
1. 配置Manifest权限与Service声明
在AndroidManifest.xml中添加必要权限和Service配置,注意指定前台Service的类型为mediaPlayback,符合Android 13的规范:
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" /> <uses-permission android:name="android.permission.FOREGROUND_SERVICE_MEDIA" /> <application ...> <service android:name=".MediaPlaybackService" android:foregroundServiceType="mediaPlayback" /> </application>
2. 实现前台Media播放Service
创建一个继承自Service的类,负责维护WebView的生命周期并启动前台通知:
class MediaPlaybackService : Service() { private var webView: WebView? = null override fun onBind(intent: Intent): IBinder = LocalBinder() inner class LocalBinder : Binder() { fun getService(): MediaPlaybackService = this@MediaPlaybackService } fun attachWebView(targetWebView: WebView) { webView = targetWebView startForegroundNotification() } private fun startForegroundNotification() { val channelId = "audio_playback_channel" // Android 8.0+ 创建通知渠道 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { val channel = NotificationChannel( channelId, "音频播放", NotificationManager.IMPORTANCE_LOW ) getSystemService(NotificationManager::class.java).createNotificationChannel(channel) } val notification = NotificationCompat.Builder(this, channelId) .setSmallIcon(R.drawable.ic_audio_play) .setContentTitle("音频播放中") .setContentText("点击回到应用") .setPriority(NotificationCompat.PRIORITY_LOW) .build() startForeground(100, notification) } override fun onDestroy() { webView?.destroy() super.onDestroy() } }
3. 在Activity中绑定Service并关联WebView
在承载WebView的Activity中,完成Service绑定、权限请求和WebView初始化:
class WebViewActivity : AppCompatActivity() { private lateinit var webView: WebView private var playbackService: MediaPlaybackService? = null private var isServiceBound = false private val serviceConn = object : ServiceConnection { override fun onServiceConnected(className: ComponentName, binder: IBinder) { val localBinder = binder as MediaPlaybackService.LocalBinder playbackService = localBinder.getService() playbackService?.attachWebView(webView) isServiceBound = true } override fun onServiceDisconnected(arg0: ComponentName) { isServiceBound = false playbackService = null } } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_webview) webView = findViewById(R.id.web_view) initWebViewSettings() webView.loadUrl("你的目标网页地址") // Android 13+ 请求通知权限 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { if (ContextCompat.checkSelfPermission(this, Manifest.permission.POST_NOTIFICATIONS) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.POST_NOTIFICATIONS), 1001) } } // 绑定前台Service Intent(this, MediaPlaybackService::class.java).also { bindService(it, serviceConn, Context.BIND_AUTO_CREATE) } } private fun initWebViewSettings() { webView.settings.apply { javaScriptEnabled = true // 允许网页自动播放音频(按需开启) mediaPlaybackRequiresUserGesture = false // 开启缓存等优化设置 domStorageEnabled = true cacheMode = WebSettings.LOAD_DEFAULT } } override fun onDestroy() { super.onDestroy() if (isServiceBound) { unbindService(serviceConn) isServiceBound = false } } }
关键注意事项
- 确保网页中的音频使用HTML5
<audio>标签播放,WebView对这种原生播放方式支持最好。 - 不要在Activity销毁时直接销毁WebView,交由Service在
onDestroy中处理,避免音频中途中断。 - 前台通知的优先级设为
IMPORTANCE_LOW,避免过度打扰用户,同时满足系统对前台Service的要求。
内容的提问来源于stack exchange,提问作者crazywolf
相关产品推荐
相关产品推荐

