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 be exploring WebView while adding file download, file upload, JavaScript alert, and HTML5 video support using custom and modified Android Java codes. We would also be using an example Android project to test out 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 users-permissions (android.permission.INTERNET) in your AndroidManifest.xml to grant permission to access the Internet.

<manifest xlmns:android...>
 ...
 <uses-permission android:name="android.permission.INTERNET" />
 <application ...
</manifest>

Running an app without this permission would crash your app again and again 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 would 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(CONTEXT); //replace CONTEXT with YOUR_ACTIVITY_NAME.CLASS`
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 would be overriding WebViewClient() with custom methods
webView.setWebChromeClient(new chromeView()); //we would be overriding 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 to be added within the scope of onCreate() method.

Overriding WebViewClient (should be written within the main class but outside the scope of 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 onPageFinishedied(), 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 tell 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 plan 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 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 BrowserActivity.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 Boolean.parseBoolean(null);
        }
    }
    public void onActivityResult(int i, int i2, Intent intent) {
        if (i == 1001 && Build.VERSION.SDK_INT >= 21) {
            mUploadMessageArr.onReceiveValue(WebChromeClient.FileChooserParams.parseResult(i2, intent));
            mUploadMessageArr = null;
        }
}

Handing on back press button:

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">

Isrg Team
Isrg Team
Isrg Team is a member of Digital Pradesh News Networks, a collective of journalists, reporters, writers, editors, lawyers, advocates, professors, and scholars affiliated with the Digital Pradesh News Network.

Latest Updates