Get the most of Android WebView – Add a file explorer to Android WebView user interface

When developing Android applications, you can spend a great deal of time designing application layout and content display for mobile technologies.  There are two available solutions – you can either use the Android OS User Interface which is highly maintained and well documented, or you can use the Android WebView class.

The Android WebView class enables you to display web pages as part of the activity layout, and is an extension of Android’s View class. It does not support web browser functionalities like the address bar, navigation controls or saving form data. This class lacks formal documentation of many of its important features, and most of them are based on best practices, tricks and hidden doors.

In this blog I will try to shed a light on some of them.

 

Like a lantern in a dark cave

Imagine you would like to enable the user to choose a file or a folder using a file explorer from within the WebView UI. This is a simple task when implemented by native Android UI elements.

We will need a few hacks when implementing this in WebView:

 

1. Setting up the displayed HTML page

In the HTML file in which WebView displays, create an HTML button which will act as a browse button, using ‘file’ HTML input type. It should look like this

<input type="file" class="file_input "/>

 

The magic here is the type=”file” directive. We will be using a built-in Android class in order to capture the user tapping on this ‘browse’ button, and later we will attach a file explorer activity to it.

 

2. Prepare the ‘file explorer’ library

For the ‘file browser’ or ‘file explorer’ functionality, there are many extensions and solutions. In this example I will use the open source library Android File Dialog which enables you to select a file or folder, and easy integrate it with the existing code.

Download the source code of Android File Dialog. Copy the files to your application’s project.

The activity returns the file/folder path, as selected by the user.

We will now setup the class that triggers the file explorer activity - it is of type WebChromeClient class which we will derive and implement the needed methods.

 

3. Define and customize WebChromeClient class

This class will be later be registered to the WebView class.
The symbol REQUEST_CHOOSE_FILE  can be any integer, it is used to distinguish between many types of requests.

 

private final static int REQUEST_CHOOSE_FILE = 1 ;
public class MyWebChromeClient extends WebChromeClient {
        private String mFileChooserPath;       
        // fileChooserPath is passed as default location of the file explorer when it opens
        MyWebChromeClient(String fileChooserPath){
                mFileChooserPath = fileChooserPath;
        }
        // For Android 3.0+
        public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType) {  
if (mUploadMessage != null) return; mUploadMessage = uploadMsg; Intent intent = new Intent(getBaseContext(), FileDialog.class); intent.putExtra(FileDialog.START_PATH,mFileChooserPath); //alternatively you can set file filter according to the preferred extension (.jpg, .doc, …) intent.putExtra(FileDialog.FORMAT_FILTER, new String[] { "myextension" }); startActivityForResult(intent, REQUEST_CHOOSE_FILE); } // For Android < 3.0 public void openFileChooser(ValueCallback<Uri> uploadMsg) { openFileChooser( uploadMsg, "" ); } // For Android > 4.1.1 public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType, String capture) { openFileChooser(uploadMsg, acceptType); } }

 

 

 

Note that there is no need to use the @override annotation on ‘openfilechooser’ method.

 

4. Accept the result of the File Explorer activity

The original activity that has launched the file explorer’s activity, should be implementing the following code, the ‘filepath’ string contains the path of the selected file

 

@Override
protected void onActivityResult(int requestCode, int resultCode,Intent intent) {
        if (resultCode == Activity.RESULT_OK) {
                if (REQUEST_CHOOSE_FILE == requestCode){
                        String filePath = intent.getStringExtra(FileDialog.RESULT_PATH);
                        // do something with ‘filepath’                
                        }
                       
                } else if (resultCode == Activity.RESULT_CANCELED) {
                        com.levelup.logutils.FLog.w(LogHandler.LOG_TAG, "file not selected");
        }
               
        Uri result = intent == null || resultCode != RESULT_OK ? null: intent.getData();       
        mUploadMessage.onReceiveValue(result); 
        mUploadMessage = null;
}

 

Good luck!

 

This blog post was written by David Bekel

 

Leave a Comment

We encourage you to share your comments on this post. Comments are moderated and will be reviewed
and posted as promptly as possible during regular business hours

To ensure your comment is published, be sure to follow the Community Guidelines.

Be sure to enter a unique name. You can't reuse a name that's already in use.
Be sure to enter a unique email address. You can't reuse an email address that's already in use.
Type the characters you see in the picture above.Type the words you hear.
Search
Showing results for 
Search instead for 
Do you mean 
About the Author


Follow Us
The opinions expressed above are the personal opinions of the authors, not of HP. By using this site, you accept the Terms of Use and Rules of Participation