TechAndroid WebView with Download, Upload, JavaScript Alert, and HTML5 Video Support

Android WebView with Download, Upload, JavaScript Alert, and HTML5 Video Support

App development in Android is relatively simple and quick thanks to WebView, which allows you to load your custom HTML code or a website. However, WebView has some limitations, including a lack of features such as file download and upload, JavaScript alerts, and HTML5 video support, including YouTube embedding and playing issues.

In this tutorial, we will explore WebView while adding file download, file upload, JavaScript alerts, and HTML5 video support using custom and modified Android Java code. We will also use an example Android project to test these features.

Prerequisites

  • Knowledge of Java (Android)
  • Understanding of Android Project structure
  • Knowledge of HTML and JavaScript

Adding required permissions to AndroidManifest.xml

You need to add Internet access user permissions (android.permission.INTERNET) in your AndroidManifest.xml to grant permission to access the Internet.

<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="your.package.name">
 ...
 <uses-permission android:name="android.permission.INTERNET" />
 <application ...
</manifest>

Running an app without this permission would crash your app repeatedly without a proper error indication.

Creating WebView Activity

Add an empty activity to your project from Android > Empty Activity and add the following XML code to your newly created activity layout file:

...
<WebView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:id="@+id/webView">
</WebView>
...

Once you’ve added the above WebView layout to your main activity, where you will be displaying the HTML pages, the next step is adding the necessary Java code to handle the various events.

Declare the following variables in the main public class:

...
WebView webView;
ProgressDialog progressDialog;
private static ValueCallback<Uri[]> mUploadMessageArr;
...

Define the ProgressDialog after setContentView(…) as:

...
progressDialog = new ProgressDialog(YOUR_ACTIVITY_NAME.this);
progressDialog.setCancelable(true);
progressDialog.setMessage("Loading..."); // you can set your custom message here
progressDialog.show();
...

Define WebView as:

webView = (WebView) findViewById(R.id.webView);
webView.getSettings().setJavaScriptEnabled(true); // true/false to enable/disable JavaScript support
webView.getSettings().setUserAgentString(new WebView(this).getSettings().getUserAgentString()); // set default user agent as of Chrome
webView.setWebViewClient(new WebViewClient()); // we will override WebViewClient() with custom methods
webView.setWebChromeClient(new chromeView()); // we will override WebChromeClient() with custom methods.
webView.loadUrl("https://www.google.com"); // website on app launch

Adding download file capability/support:

webView.setDownloadListener(new DownloadListener() {
            @Override
            public void onDownloadStart(String url, String userAgent, String contentDisposition, String mimetype, long contentLength) {
                progressDialog.dismiss();
                Intent i = new Intent(Intent.ACTION_VIEW);
                i.setData(Uri.parse(url));
                startActivity(i);
            }
});

All of the above code except the declaration part should be added within the scope of the onCreate() method.

Overriding WebViewClient (should be written within the main class but outside the scope of the onCreate() method):

You need to override the WebViewClient to open the links within the app instead of opening them in Chrome or your default web browser. By overriding WebViewClient, you can also handle events like onPageStarted(), which is useful for displaying the progress bar or determining when the page has started loading, and onPageFinished(), which fires when the page finishes loading the content and allows you to hide the progress bar. onReceivedError() is very useful, especially when you want to display custom “404” messages or inform the user that there are Internet issues that need to be fixed, as well as hide the progress bar if any error occurs in loading the page.

class WebViewClient extends android.webkit.WebViewClient {
        @Override
        public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
                return super.shouldOverrideUrlLoading(view, request);
        }

        @Override
        public void onPageStarted(WebView view, String url, Bitmap favicon) {
            super.onPageStarted(view, url, favicon);
            progressDialog.show(); // showing the progress bar once the page has started loading
        }

        @Override
        public void onPageFinished(WebView view, String url) {
            super.onPageFinished(view, url);
            progressDialog.dismiss(); // hide the progress bar once the page has loaded
        }

        @Override
        public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) {
            super.onReceivedError(view, request, error);
            webView.loadData("","text/html","utf-8"); // replace the default error page with plain content
            progressDialog.dismiss(); // hide the progress bar on error in loading
            Toast.makeText(getApplicationContext(),"Internet issue",Toast.LENGTH_SHORT).show();
        }
}

Adding upload file support by overriding WebChromeClient (should be written within the main class but outside the scope of the onCreate() method):

By overriding WebChromeClient(), you not only add JavaScript alert support but also file upload support with the help of startFileChooserIntent() and onActivityResult().

public class chromeView extends WebChromeClient {
        @SuppressLint("NewApi")
        @Override
        public boolean onShowFileChooser(WebView webView, ValueCallback<Uri[]> valueCallback, FileChooserParams fileChooserParams) {
            return YOUR_ACTIVITY_NAME.this.startFileChooserIntent(valueCallback, fileChooserParams.createIntent());
        }
    }

    @SuppressLint({"NewApi", "RestrictedApi"})
    public boolean startFileChooserIntent(ValueCallback<Uri[]> valueCallback, Intent intent) {
        if (mUploadMessageArr != null) {
            mUploadMessageArr.onReceiveValue(null);
            mUploadMessageArr = null;
        }
        mUploadMessageArr = valueCallback;
        try {
            startActivityForResult(intent, 1001, new Bundle());
            return true;
        } catch (Throwable valueCallback2) {
            valueCallback2.printStackTrace();
            if (mUploadMessageArr != null) {
                mUploadMessageArr.onReceiveValue(null);
                mUploadMessageArr = null;
            }
            return false;
        }
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == 1001 && Build.VERSION.SDK_INT >= 21) {
            mUploadMessageArr.onReceiveValue(WebChromeClient.FileChooserParams.parseResult(resultCode, data));
            mUploadMessageArr = null;
        }
    }
}

Handling the back button press:

You may be looking for functionality that can take the user to the previous page, and if there is no previous page, then close the current activity. Well, you can achieve this by overriding the onBackPressed() method as follows:

@Override
    public void onBackPressed() {
        if (webView.canGoBack()) {
            webView.goBack();
        } else {
            finish();
        }
}

To add HTML5 audio and video play support, including YouTube, you need to enable hardware acceleration by adding the following code in your Manifest.xml file.

<application android:hardwareAccelerated="true">

IR Digital Media Team
IR Digital Media Teamhttps://www.isrgrajan.com/
IR Digital Media Team is a member of Digital Pradesh, a collective of journalists, reporters, writers, editors, lawyers, advocates, professors, and scholars affiliated with the Digital Pradesh.

Latest Updates