Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save pichillilorenzo/ee74e103fdc324f761c5fde7b73bd430 to your computer and use it in GitHub Desktop.
Save pichillilorenzo/ee74e103fdc324f761c5fde7b73bd430 to your computer and use it in GitHub Desktop.
InAppWebView - How to enable download files in WebView
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
import 'package:flutter_downloader/flutter_downloader.dart';
import 'package:path_provider/path_provider.dart';
import 'package:permission_handler/permission_handler.dart';
Future main() async {
WidgetsFlutterBinding.ensureInitialized();
await FlutterDownloader.initialize(
debug: true // optional: set false to disable printing logs to console
);
await Permission.storage.request();
runApp(MyApp());
}
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => new _MyAppState();
}
class _MyAppState extends State<MyApp> {
InAppWebViewController _webViewController;
@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: "http://ovh.net/files/1Mio.dat",
initialOptions: InAppWebViewGroupOptions(
crossPlatform: InAppWebViewOptions(
debuggingEnabled: true,
useOnDownloadStart: true
),
),
onWebViewCreated: (InAppWebViewController controller) {
_webViewController = controller;
},
onDownloadStart: (controller, url) async {
print("onDownloadStart $url");
final taskId = await FlutterDownloader.enqueue(
url: url,
savedDir: (await getExternalStorageDirectory()).path,
showNotification: true, // show download progress in status bar (for Android)
openFileFromNotification: true, // click on notification to open downloaded file (for Android)
);
},
))
])),
),
);
}
}
@aristhiooo
Copy link

I have followed the example above. And the code is like this:

/// on crossPlatform: InAppWebViewOptions
useOnDownloadStart: true,

onDownloadStart: (controller, url) async {
          Directory tempDir = await getExternalStorageDirectory();
          print("onDownload $url");
          await FlutterDownloader.enqueue(
            url: "$url",
            savedDir: tempDir.path,
            showNotification: true,
            openFileFromNotification: true,
            saveInPublicStorage: true,
          );
        },

But there is no reaction. In the console it just shows up like this:

I/flutter (16534): onDownload https://botmaster-files.s3.ap-southeast-1.amazonaws.com/Content/this-file-to-download.pdf
W/WM-WorkSpec(16534): Backoff delay duration less than minimum value

What is missing? or that I haven't implemented yet?

@jayashankaamila
Copy link

Hi
When I tried to download a pdf, app getting closed automatically.
Any solution found for this?

@shimafanissa
Copy link

Hi When I tried to download a pdf, app getting closed automatically. Any solution found for this?

any solution?

@chrisvidal
Copy link

chrisvidal commented Nov 14, 2022

Anyone solved this issue?
even with the new onDownloadStartRequest, the download does not start (with useOnDownloadStart: true, in the options).

@Aadesh2003
Copy link

this code is not working when there is no any direct url for download files. for example :- link doesn't have any extension like .jpg, .png, .mp3
example.com/file.jpg -- it will work
example.com/file/download -- it will not work

@asrafulattare
Copy link

ettings plea

example.com/file/download -- it will not work
any solution?

@chrisvidal
Copy link

I believe your server code executing the route /file/download need to specifically return the data as an attache file and specify the text-mime

@pichillilorenzo
Copy link
Author

An updated example can be found here for plugin version 6: https://github.com/pichillilorenzo/flutter_inappwebview_examples/tree/main/file_download

@abdorll
Copy link

abdorll commented Aug 15, 2023

LATEST APPROACH: As at August 2023

//===========START=============
InAppWebViewGroupOptions options = InAppWebViewGroupOptions(
      crossPlatform: InAppWebViewOptions('
        useShouldOverrideUrlLoading: true,
        useOnDownloadStart: true, //======================Very Important
        mediaPlaybackRequiresUserGesture: false,
      ),
      android: AndroidInAppWebViewOptions(
        useHybridComposition: true,
        supportMultipleWindows: true,
      ),
      ios: IOSInAppWebViewOptions(
        allowsInlineMediaPlayback: true,
      ));
//===========END=============



//===========START=============
   InAppWebView(
      .........
      .........
	      onDownloadStartRequest: (controller, url) async {
                    Directory? tempDir =
                              await getExternalStorageDirectory();
                    setState(() {});
                    print(
                        "onDownload ${url.url.toString()}\n ${tempDir!.path}");
                    await FlutterDownloader.enqueue(
                      url: url.url.toString(),
                      fileName: url.suggestedFilename, //================File Name
                      savedDir: tempDir.path,
                      showNotification: true,
                      requiresStorageNotLow: false,
                      openFileFromNotification: true,
                      saveInPublicStorage: true,
                          );
                        },
      .........
      .........
      .........

)
//===========END=============

@Trend74X
Copy link

LATEST APPROACH: As at August 2023

Well it seems the download started but the app crashed showing the error

D/DownloadWorker(26207): Update too frequently!!!!, this should be dropped

how did you made it to work?

@Mrunal333
Copy link

Mrunal333 commented Jan 18, 2024

            `onDownloadStart: (controller, url) async {
              print("Download Start: $url");
              // Check if the file is a PDF
              if (url.toString().toLowerCase().endsWith('.pdf')) {
                // Open PDF viewer using url_launcher
                // ignore: deprecated_member_use
                if (await canLaunch(url.toString())) {
                  // ignore: deprecated_member_use
                  await launch(url.toString());
                } else {
                  log("Could not launch PDF viewer");
                }
              } else {
                // Launch for other file types
                if (await canLaunch(url.toString())) {
                      await launch(url.toString());
                    } else {
                      log("Could not launch file");
                    }
                //log("Handle other file types or open in-app viewer");
              }
            },`
            try this code it worked for me

@ranjan51
Copy link

i am not able to download if my file is related to blob URL getting below error.

Update notification: {notificationId: 7, title: blob:
"COMPANY URL", status: RUNNING, progress: 0}
D/DownloadWorker( 5399): Update too frequently!!!!, but it is the final update, we should sleep a second to ensure the update call can be processed
D/DownloadWorker( 5399): Update notification: {notificationId: 7, title: blob: "COMPANY URL" status: FAILED, progress: -1}
W/System.err( 5399): java.net.MalformedURLException: unknown protocol: blob

@EArminjon
Copy link

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment