Search code examples
flutterdartwebview-flutter

Unable to display html file from local storage in webview


I have a Flutter project in which I am:

  • Downloading the zip file (full of html files)
  • Extracting the html files to a new directory (ebooks/02)
  • Saving the local file urls in a List
  • Displaying the urls in Webview & iterate through List for back & forth.

However, in the web view all I get is "Unable to load asset..."

enter image description here

Though any standard http url works fine in webview.

I tried from these two answers but no result: Answer1 & Answer2

The exception I get is :

E/flutter (10963): [ERROR:flutter/lib/ui/ui_dart_state.cc(186)] Unhandled Exception: Unable to load asset: /data/user/0/com.pts.school_ebook_reader_app_prag/app_flutter/ebooks/04/00.html

I need to understand how to make the local html at the given path display in webview.

Any help would be appreciated.

Edit:

The webview code (currently trying to display only 1st url in list):

 class _BookReaderState extends State<BookReader> {
  List<String> urls = UserData.ebook;

  WebViewController web;
  final _key = UniqueKey();
  String _url;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          automaticallyImplyLeading: false,
          title: Text(
            "Book Title Here",
            style: GoogleFonts.roboto(
                fontWeight: FontWeight.w900,
                fontSize: 25.0,
                color: Colors.white),
            textAlign: TextAlign.center,
          ),
          actions: [
            Padding(
              padding: EdgeInsets.only(right: 50),
              child: IconButton(
                  icon: Image.asset('images/04_mobile-menu.png'),
                  color: Colors.red,
                  alignment: Alignment.centerLeft,
                  onPressed: () {
                    Navigator.push(
                        context,
                        MaterialPageRoute(
                            builder: (context) => MyLibrary_Screen()));
                  }),
            ),
            Padding(
              padding: const EdgeInsets.only(left: 1.0),
              child: IconButton(
                  icon: Image.asset('images/05_mobile-close.png'),
                  color: Colors.red,
                  alignment: Alignment.centerRight,
                  onPressed: () {
                    Navigator.push(
                        context,
                        MaterialPageRoute(
                            builder: (context) => MyLibrary_Screen()));
                  }),
            ),
          ],
        ),
        body: Column(
          children: [
            Padding(
              padding: EdgeInsets.symmetric(horizontal: 10, vertical: 10),
              child: Container(
                  width: 700,
                  height: 490,
                  child: FutureBuilder<String>(
                      future: _loadHtmlFromAssets(0),
                      builder: (context, snapshot) {
                        if (snapshot.hasData) {
                          return WebView(
                            initialUrl: new Uri.dataFromString(snapshot.data,
                                    mimeType: 'text/html')
                                .toString(),
                            javascriptMode: JavascriptMode.unrestricted,
                          );
                        } else if (snapshot.hasError) {
                          return Text("${snapshot.error}");
                        }
                        return CircularProgressIndicator();
                      })),
            ),
            Padding(
              padding: EdgeInsets.only(top: 85),
              child: Container(
                height: 70,
                color: Colors.blue,
                child: RowSuper(
                  innerDistance: 50,
                  children: [
                    InkWell(
                      child: Image.asset(
                        "images/05_mobile-arrow-left.png",
                        alignment: Alignment.bottomLeft,
                        height: 170,
                        width: 90,
                      ),
                      onTap: () => pageIncDec(1),
                    ),
                    Text('Page ${urls.indexOf(_url) + 1} of ${urls.length}',
                        style: GoogleFonts.roboto(
                            fontWeight: FontWeight.w900,
                            fontSize: 33.0,
                            color: Colors.white)),
                    InkWell(
                      child: Image.asset(
                        "images/05_mobile-arrow-right.png",
                        alignment: Alignment.bottomRight,
                        height: 270,
                        width: 90,
                      ),
                      onTap: () => pageIncDec(2),
                    ),
                  ],
                ),
              ),
            ),
          ],
        ));
  }

  pageIncDec(int i) async {
    int n;
    if (i == 1) {
      setState(() {
        urls.indexOf(_url) > 0 ? n = urls.indexOf(_url) - 1 : n = 0;
      });
    } else {
      setState(() {
        urls.indexOf(_url) < urls.length
            ? n = urls.indexOf(_url) + 1
            : n = urls.length - 1;
      });
    }

     _url = await _loadHtmlFromAssets(n);

    web.loadUrl(_url);
    print(_url);
  }

  Future<String> _loadHtmlFromAssets(int n) async {
    String fileText = await rootBundle.loadString(urls[n]);
    print(fileText);
    String r = (Uri.dataFromString(fileText,
            mimeType: 'text/html', encoding: Encoding.getByName('utf-8'))
        .toString());
    print(r);
    return r;
  }

Code to add files :

Directory dir =
        Directory('${_appDocDir.path}/$folderName/${item.key_name}');
    List<FileSystemEntity> listOfAllFolderAndFiles =
        await dir.list(recursive: false).toList();

    if (UserData.ebook != null) UserData.ebook.clear();

    listOfAllFolderAndFiles.forEach((element) {
      if (element.toString().contains("html")) {
        String url = element.toString().replaceAll("File: ", "");
        url = url.replaceAll("'", "");
        UserData.ebook.add(url.toString());
      }
      UserData.eBookTitle = item.title;
    });

    print(UserData.ebook);

And result of printing UserData.ebook :

I/flutter ( 3465): [/data/user/0/com.pts.school_ebook_reader_app_prag/app_flutter/ebooks/02/00.html, /data/user/0/com.pts.school_ebook_reader_app_prag/app_flutter/ebooks/02/01.html, /data/user/0/com.pts.school_ebook_reader_app_prag/app_flutter/ebooks/02/02.html, /data/user/0/com.pts.school_ebook_reader_app_prag/app_flutter/ebooks/02/03.html, /data/user/0/com.pts.school_ebook_reader_app_prag/app_flutter/ebooks/02/04.html, /data/user/0/com.pts.school_ebook_reader_app_prag/app_flutter/ebooks/02/05.html, /data/user/0/com.pts.school_ebook_reader_app_prag/app_flutter/ebooks/02/06.html]

Checking:

//Checking if file exists
      print("File ${UserData.ebook[0]} exists ? " +
          File(UserData.ebook[0]).existsSync().toString());

Result:

I/flutter ( 3465): File /data/user/0/com.pts.school_ebook_reader_app_prag/app_flutter/ebooks/02/00.html exists ? true

Solution

  • Finally after trying all possible plugins realized that Flutter webview as of now cannot display local html files that are heavy on css & javascript side.

    The same webview can only display external urls or basic html files(minus css & js).

    I switched over to native android for this.