How to pause a WebView in flutter?
Asked Answered
P

3

6

I have added a webview plugin (official flutter plugin) for viewing webpages. One of the webpage has a youtube video playing and when I press the home button and the app goes into background. But the problem is that the sound keeps on playing. There are other sections in the application that contain some component playing sound or video.

So I want to know what can be done to pause the webview altogether once I move the app to background.

I am currently using this webview plugin: webview_flutter: ^0.3.9+1 There is no option in the plugin to pause the webview itself.

Pluckless answered 10/7, 2019 at 9:55 Comment(0)
F
5

Got the same issue on Android side with webview_flutter: ^0.3.18+1. I found a solution to pause the video by requesting audio focus again in the onPause callback of host 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)
    }
}

Also check this issue.

Frivolous answered 24/2, 2020 at 10:20 Comment(1)
rayworks this is such a Hack XD but it works so bows to you fo adding that here. I hope they will handle this properly in flutter-webview.Missi
A
5

It's not possible from Dart using the webview_flutter plugin. However, you can use my plugin flutter_inappwebview, which is a Flutter plugin that allows you to add inline WebViews or open an in-app browser window and has a lot of events, methods, and options to control WebViews.

It implements methods to pause/resume the WebView.

For Android, you can use InAppWebViewController.android.pause and InAppWebViewController.android.resume to pause and resume WebView. You should implement WidgetsBindingObserver in your Widget and check AppLifecycleState state through didChangeAppLifecycleState() method.

If you need to pause/resume also JavaScript execution you can use InAppWebViewController.pauseTimers/InAppWebViewController.resumeTimers methods.

Here is an example with a 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) {},
          ))
        ])),
      ),
    );
  }
}
Aurar answered 3/6, 2020 at 20:9 Comment(0)
C
0
@override
void dispose() {
  super.dispose();
  _controller.loadRequest(Uri.parse('about:blank'));
}

Loading about:blank resets the webview state and release page resources (including any running JavaScript, like video or audio).

More info: https://github.com/flutter/flutter/issues/119616#issuecomment-1419991144

Chow answered 26/3 at 11:22 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.