Debug School

rakesh kumar
rakesh kumar

Posted on • Updated on

Build a mobile app Using WebView Flutter

Flutter WebView widget displays a browser like space to show the webpage specified by URL. So, you can display a webpage just like another widget in your mobile application

Let's break down the code into steps and explain each part separately.

Step 1: Dependencies
Add the required dependencies in your pubspec.yaml file:

dependencies:
  flutter:
    sdk: flutter
  webview_flutter: ^2.3.0
  permission_handler: ^12.0.0
Enter fullscreen mode Exit fullscreen mode

Run flutter pub get to install the dependencies.

Step 2: Import Packages
In your Dart file, import the necessary packages:

import 'package:flutter/material.dart';
import 'package:webview_flutter/webview_flutter.dart';
import 'package:permission_handler/permission_handler.dart';
Enter fullscreen mode Exit fullscreen mode

Step 3: Request Storage Permission
Before running the app, request the necessary storage permission:

Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Permission.storage.request();
  runApp(MyApp());
}
Enter fullscreen mode Exit fullscreen mode

Step 4: Create WebView Widget
Create a stateful widget containing a WebView:

class WebViewExample extends StatefulWidget {
  @override
  _WebViewExampleState createState() => _WebViewExampleState();
}

class _WebViewExampleState extends State<WebViewExample> {
  late WebViewController _webViewController;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('WebView File Upload'),
      ),
      body: WebView(
        initialUrl: 'https://www.myhospitalnow.com/hospitals/',
        javascriptMode: JavascriptMode.unrestricted,
        onWebViewCreated: (WebViewController webViewController) {
          _webViewController = webViewController;
        },
        onPageFinished: (String url) {
          _webViewController.evaluateJavascript('''
            document.getElementById('fileInput').click();
          ''');
        },
        navigationDelegate: (NavigationRequest request) {
          if (request.url.startsWith('data:')) {
            print('File uploaded!');
            return NavigationDecision.prevent;
          } else {
            return NavigationDecision.navigate;
          }
        },
      ),
    );
  }
}
Enter fullscreen mode Exit fullscreen mode

Step 5: HTML Input Element for File Upload
Inside your web page's HTML, make sure there is an input element for file uploading:

<input type="file" id="fileInput" />
Enter fullscreen mode Exit fullscreen mode

Step 6: Trigger File Input
In your Flutter code, use JavaScript to trigger the file input after the WebView has finished loading:

onPageFinished: (String url) {
  _webViewController.evaluateJavascript('''
    document.getElementById('fileInput').click();
  ''');
},
Enter fullscreen mode Exit fullscreen mode

Step 7: Handle File Uploads in WebView
Implement a navigationDelegate in your WebView to handle file uploads:

navigationDelegate: (NavigationRequest request) {
  if (request.url.startsWith('data:')) {
    print('File uploaded!');
    return NavigationDecision.prevent;
  } else {
    return NavigationDecision.navigate;
  }
},
Enter fullscreen mode Exit fullscreen mode

This code checks if the navigation request's URL starts with 'data:' (indicating a file upload). If so, it prevents the WebView from navigating, allowing you to handle the file upload in your Flutter code.

This should provide a basic structure for handling file uploads in a WebView within a Flutter app. Adjust the code according to your specific use case and UI requirements.

Let's break down the code block:

onPageFinished: (String url) {
  _webViewController.evaluateJavascript('''
    document.getElementById('fileInput').click();
  ''');
},
Enter fullscreen mode Exit fullscreen mode

This code is part of the WebView widget in Flutter and is used to trigger a click on an HTML element with the id 'fileInput' after the WebView has finished loading a page.

Here's a detailed explanation:

onPageFinished: This is a callback function that gets called when the WebView finishes loading a web page.

(String url): It receives the URL of the finished page as a parameter. In this case, the URL is stored in the variable url (though it's not used in the code block).

_webViewController: This is an instance of the WebViewController class, which allows you to control and interact with the WebView.

evaluateJavascript: This method of the WebViewController is used to execute JavaScript code in the WebView.

The JavaScript code block enclosed in triple single quotes (''') is:

document.getElementById('fileInput').click();
Enter fullscreen mode Exit fullscreen mode

This JavaScript code does the following:

document.getElementById('fileInput'): It selects the HTML element with the id 'fileInput'. This is assumed to be an input element of type file (file input) in your HTML.

.click(): It simulates a click on the selected element. In the context of a file input, this would trigger the file selection dialog that allows the user to choose a file.

So, when the WebView finishes loading a page, this code block uses JavaScript to programmatically click the file input element with the id 'fileInput'. This is a common technique to automate certain actions on a web page using WebView in a Flutter app, such as triggering file uploads.

Another Way

webview_flutter plugin

Below is an example Flutter code demonstrating how to implement file upload functionality in an Android WebView using webview_flutter_android and file_picker:

First, make sure to add the required dependencies to your

dependencies:
  webview_flutter: ^2.0.13
  webview_flutter_android: ^2.0.13
  file_picker: ^4.0.10
Enter fullscreen mode Exit fullscreen mode

Next, use the following code in your Dart file:

import 'dart:io';
import 'package:flutter/material.dart';
import 'package:webview_flutter/webview_flutter.dart';
import 'package:webview_flutter_android/webview_flutter_android.dart';
import 'package:file_picker/file_picker.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: const Text('WebView File Upload'),
        ),
        body: WebViewFileUpload(),
      ),
    );
  }
}

class WebViewFileUpload extends StatefulWidget {
  @override
  _WebViewFileUploadState createState() => _WebViewFileUploadState();
}

class _WebViewFileUploadState extends State<WebViewFileUpload> {
  late WebViewController _webViewController;

  @override
  Widget build(BuildContext context) {
    return WebView(
      initialUrl: 'https://www.example.com', // Replace with your web page URL
      javascriptMode: JavascriptMode.unrestricted,
      onWebViewCreated: (WebViewController webViewController) {
        _webViewController = webViewController;
        addFileSelectionListener();
      },
    );
  }

  void addFileSelectionListener() async {
    if (Platform.isAndroid) {
      final androidController = _webViewController.platform as AndroidWebViewController;
      await androidController.setOnShowFileSelector(_androidFilePicker);
    }
  }

  Future<List<String>> _androidFilePicker(final FileSelectorParams params) async {
    final result = await FilePicker.platform.pickFiles();

    if (result != null && result.files.single.path != null) {
      final file = File(result.files.single.path!);
      return [file.uri.toString()];
    }

    return [];
  }
}
Enter fullscreen mode Exit fullscreen mode

Replace the initialUrl in the WebView widget with your desired web page URL. This code sets up a simple Flutter app with a WebView, allowing file uploads through the file picker on Android

select file using webview flutter
evaluateJavascript

import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
import 'package:file_picker/file_picker.dart';
void main() {
 runApp(MyApp());
}
class MyApp extends StatelessWidget {
 @override
 Widget build(BuildContext context) {
    return MaterialApp(
      home: WebViewApp(),
    );
 }
}
class WebViewApp extends StatefulWidget {
 @override
 _WebViewAppState createState() => _WebViewAppState();
}
class _WebViewAppState extends State<WebViewApp> {
 final Completer<InAppWebViewController> _controller = Completer<InAppWebViewController>();
 @override
 Widget build(BuildContext context) {
    return Scaffold(
      body: InAppWebView(
        initialUrlRequest: URLRequest(url: Uri.parse("https://www.myhospitalnow.com/hospitals/")),
        onWebViewCreated: (InAppWebViewController webViewController) {
          webViewController.addJavaScriptHandler(handlerName: 'flutter_inappwebview', callback: (args) {
            if (args.first == 'pickFile') {
              _pickFile();
            }
          });
          _controller.complete(webViewController);
        },
        onLoadStop: (controller, url) {
          _controller.future.then((value) {
            value.evaluateJavascript(source: '''
              document.querySelectorAll('input[type=file]').forEach(function(node) {
                node.addEventListener('click', function() {
                 window.flutter_inappwebview.callHandler('flutter_inappwebview', 'pickFile');
                });
              });
            ''');
          });
        },
      ),
    );
 }
 Future<void> _pickFile() async {
    FilePickerResult? result = await FilePicker.platform.pickFiles();
    if (result != null) {
      _controller.future.then((value) {
        value.evaluateJavascript(source: '''
          document.querySelector('input[type=file]').value = '${result.files.single.name}';
        ''');
      });
    }
 }
}

Enter fullscreen mode Exit fullscreen mode

reference1
reference2
reference3
reference4
reference5
reference6

Top comments (0)