flutter_webview save last loaded web page for offline access

165 Views Asked by At

i'm trying to save web page for offline. suppose, if an user has internet connection and visited the page. then it should have to save the last loaded page for offline view. if user don't have internet connection and open the page, it should have to show the previously loaded page. is that possible?

import 'package:connectivity_plus/connectivity_plus.dart';
import 'package:flutter/material.dart';
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
import 'package:flutter_cache_manager/flutter_cache_manager.dart';

class MyCertificatesScreen extends StatefulWidget {
  static const routeName = '/webview';

  final String url;

  const MyCertificatesScreen({Key? key, required this.url}) : super(key: key);

  @override
  _MyCertificatesScreenState createState() => _MyCertificatesScreenState();
}

class _MyCertificatesScreenState extends State<MyCertificatesScreen> {
  late InAppWebViewController _controller;
  bool isLoading = true;
  final cacheManager = DefaultCacheManager();

  @override
  void initState() {
    super.initState();

    // Initialize connectivity
    Connectivity().onConnectivityChanged.listen((result) {
      if (result == ConnectivityResult.none) {
        // No internet connection, try loading cached HTML file
        _loadCachedHtmlFile();
      }
    });
  }

  @override
  void didChangeDependencies() {
    super.didChangeDependencies();

    // Load the appropriate content based on connectivity
    _checkConnectivityAndLoadContent();
  }

  // Function to load cached HTML file
  void _loadCachedHtmlFile() async {
    try {
      final fileInfo = await cacheManager.getFileFromCache(widget.url);
      if (fileInfo != null && fileInfo.file != null && await fileInfo.file.exists()) {
        // Cached file exists, load it
        final fileContent = await fileInfo.file.readAsString();
        _controller.loadData(data: fileContent, mimeType: 'text/html');
      } else {
        // No cached file found, show an error message or a default page
        // You can display an error message here or load a default local HTML file
      }
    } catch (e) {
      // Error loading cached file, show an error message or a default page
      // You can display an error message here or load a default local HTML file
    }
  }

  // Function to check connectivity and load content accordingly
  void _checkConnectivityAndLoadContent() async {
    var connectivityResult = await Connectivity().checkConnectivity();
    if (connectivityResult != ConnectivityResult.none) {
      // Internet connection available, load web page from URL
      if (_controller != null) {
        _controller.loadUrl(urlRequest: URLRequest(url: Uri.parse(widget.url)));
      }
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Color(0xFFF5F9FA),
      appBar: null, // Set the app bar to null to remove it
      body: Stack(
        children: [
          InAppWebView(
            initialOptions: InAppWebViewGroupOptions(
              crossPlatform: InAppWebViewOptions(
                javaScriptEnabled: true,
              ),
            ),
            onWebViewCreated: (InAppWebViewController controller) {
              _controller = controller;

              // Load the appropriate content based on connectivity
              _checkConnectivityAndLoadContent();
            },
            onLoadStop: (InAppWebViewController controller, Uri? url) {
              setState(() {
                isLoading = false; // Hide the progress indicator
              });
            },
            onLoadError: (InAppWebViewController controller, Uri? url, int code, String message) {
              // Handle web page loading errors here
              print("Webpage error: $message");

              // If loading from cache fails, show an error message or a default page
              // You can display an error message here or load a default local HTML file
            },
          ),
          if (isLoading)
            Center(
              child: CircularProgressIndicator(), // Show the progress indicator
            ),
        ],
      ),
    );
  }

  @override
  void dispose() {
    cacheManager.dispose();
    super.dispose();
  }
}
1

There are 1 best solutions below

1
luvzfootball On

I see you are using an InAppWebViewController objet. If this object is the one documented here, you have a getHtml() → Future<String?> method which you could call like this to get the HTML:

String html = await _controller.getHtml();

This html String can then be stored for later offline navigation.