如何在Flutter中暂停一个WebView?

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

因此,我想知道如何在将应用程序移到后台时完全暂停Webview。

我目前正在使用的Webview插件是:webview_flutter: ^0.3.9+1插件本身没有选项可以暂停Webview。

2个回答

5
无法使用webview_flutter插件在Dart中实现。但是,您可以使用我的插件flutter_inappwebview,它是Flutter插件,允许您添加内联WebViews或打开内置浏览器窗口,并具有大量的事件、方法和选项来控制WebViews。
它实现了暂停/恢复WebView的方法。
对于Android,您可以使用InAppWebViewController.android.pauseInAppWebViewController.android.resume来暂停和恢复WebView。您应该在Widget中实现WidgetsBindingObserver并通过didChangeAppLifecycleState()方法检查AppLifecycleState state
如果您需要暂停/恢复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) {},
          ))
        ])),
      ),
    );
  }
}

5

在使用 webview_flutter: ^0.3.18+1 的 Android 端也出现了同样的问题。我找到了一个解决方案,在宿主 ActivityonPause 回调中再次请求音频焦点以暂停视频。

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)
    }
}

还要检查这个问题


rayworks,这真是个骚操作XD,但它确实有效,所以向你致敬,感谢你在这里添加了它。 希望他们在flutter-webview中能够妥善处理这个问题。 - oziem

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接