如何在颤动中暂停 WebView?

Dhr*_*rma 5 browser webview dart flutter

我添加了一个 webview 插件(官方 flutter 插件)来查看网页。其中一个网页正在播放 youtube 视频,当我按下主页按钮时,应用程序进入后台。但问题是声音一直在播放。 应用程序中还有其他部分包含一些播放声音或视频的组件。

所以我想知道一旦我将应用程序移到后台,可以做些什么来完全暂停 webview。

我目前正在使用这个 webview 插件:插件webview_flutter: ^0.3.9+1 中没有选项可以暂停 webview 本身。

ray*_*rks 5

在 Android 方面遇到了同样的问题webview_flutter: ^0.3.18+1。我找到了通过在onPausehost的回调中再次请求音频焦点来暂停视频的解决方案Activity

val audioManager = activity.getSystemService(Context.AUDIO_SERVICE) as AudioManager

if (audioManager.isMusicActive) {
    if (Utils.hasOreoSDK26()) {
        val audioAttributes = AudioAttributes.Builder()
                .setUsage(AudioAttributes.USAGE_MEDIA)
                .setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
                .build()
        val audioFocusRequest = AudioFocusRequest.Builder(AudioManager.AUDIOFOCUS_GAIN_TRANSIENT)
                .setAudioAttributes(audioAttributes)
                .setAcceptsDelayedFocusGain(true)
                .setWillPauseWhenDucked(true)
                .setOnAudioFocusChangeListener(
                        { focusChange -> Timber.i(">>> Focus change to : %d", focusChange) },
                        Handler())
                .build()
        audioManager.requestAudioFocus(audioFocusRequest)
    } else {
        audioManager.requestAudioFocus({ }, AudioManager.STREAM_MUSIC,
                AudioManager.AUDIOFOCUS_GAIN_TRANSIENT)
    }
}
Run Code Online (Sandbox Code Playgroud)

还要检查这个问题


Lor*_*lli 5

Dart 无法使用该webview_flutter插件。但是,您可以使用我的插件flutter_inappwebview,这是一个 Flutter 插件,允许您添加内联 WebView 或打开应用内浏览器窗口,并且有很多事件、方法和选项来控制 WebView。

它实现了暂停/恢复 WebView 的方法。

对于 Android,您可以使用InAppWebViewController.android.pauseInAppWebViewController.android.resume来暂停和恢复 WebView。您应该在您的小部件中实现WidgetsBindingObserver并检查AppLifecycleState state方法didChangeAppLifecycleState()

如果您还需要暂停/恢复 JavaScript 执行,您可以使用InAppWebViewController.pauseTimers/InAppWebViewController.resumeTimers方法。

以下是一个包​​含 YouTube URL 的示例:

import 'dart:async';
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutter_inappwebview/flutter_inappwebview.dart';

Future main() async {
  WidgetsFlutterBinding.ensureInitialized();
  runApp(MyApp());
}

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => new _MyAppState();
}

class _MyAppState extends State<MyApp> with WidgetsBindingObserver {
  InAppWebViewController webView;

  @override
  void initState() {
    WidgetsBinding.instance.addObserver(this);
    super.initState();
  }

  @override
  void dispose() {
    WidgetsBinding.instance.removeObserver(this);
    super.dispose();
  }

  @override
  void didChangeAppLifecycleState(AppLifecycleState state) {
    print('state = $state');
    if (webView != null) {
      if (state == AppLifecycleState.paused) {
        webView.pauseTimers();
        if (Platform.isAndroid) {
          webView.android.pause();
        }
      } else {
        webView.resumeTimers();
        if (Platform.isAndroid) {
          webView.android.resume();
        }
      }
    }
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: const Text('InAppWebView Example'),
        ),
        body: Container(
            child: Column(children: <Widget>[
          Expanded(
              child: InAppWebView(
            initialUrl: "https://www.youtube.com/watch?v=NfNdXgJZfFo",
            initialHeaders: {},
            initialOptions: InAppWebViewGroupOptions(
              crossPlatform: InAppWebViewOptions(
                debuggingEnabled: true,
              ),
            ),
            onWebViewCreated: (InAppWebViewController controller) {
              webView = controller;
            },
            onLoadStart: (InAppWebViewController controller, String url) {},
            onLoadStop: (InAppWebViewController controller, String url) {},
          ))
        ])),
      ),
    );
  }
}
Run Code Online (Sandbox Code Playgroud)