Having trouble displaying image previews on Android webview?

Although this may seem like a repetitive query, I have been unable to find any solutions from previously posted questions. On my JSP page, I am able to select images from the PC and display a preview of that image in the Chrome browser on my Android phone. However, when I run it on a WebView, the document.getElementById.click() function does not work, preventing me from getting an image preview.

This is the code snippet from my JSP page:

<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>JSP Page</title>
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
    <script>
        function img_preview(id1, id2) { /******************* Show preview of image *******************/
            var oFiles = document.getElementById(id1).files;
            var valid_extensions = /(.jpg|.jpeg|.png)$/i;
            if (!(valid_extensions.test(document.getElementById(id1).files[0].name))) {
                document.getElementById('er').innerHTML = "Select jpg or png image";
            } else {
                var reader = new FileReader();
                reader.readAsDataURL(oFiles[0]);
                reader.onload = function (e) {
                    document.getElementById(id2).src = e.target.result;
                };
            }
}

        </script>
 </head>
 <body>
  <input type="file" style="display: none;" id="advrts_img" name="advrts_img" onchange="img_prvw('advrts_img','advrts_img_prvw')">
<img src="images/img_place.png" id="advrts_img_prvw" alt="" class="cursor margin_top10" style="width:100px;height:100px" onClick="document.getElementById('advrts_img').click()">
 </body>
 </html>

This section shows my Android WebView code:

package com.example.sample_webview;

import android.app.Activity;
import android.content.Intent;
import android.content.res.Configuration;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Bundle;
import android.view.View;
import android.webkit.ValueCallback;
import android.webkit.WebChromeClient;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.ProgressBar;

public class MainActivity extends Activity {
/** Called when the activity is first created. */

WebView web;

private ValueCallback<Uri> mUploadMessage;
private final static int FILECHOOSER_RESULTCODE = 1;

@Override
protected void onActivityResult(int requestCode, int resultCode,
        Intent intent) {
    if (requestCode == FILECHOOSER_RESULTCODE) {
        if (null == mUploadMessage)
            return;
        Uri result = intent == null || resultCode != RESULT_OK ? null
                : intent.getData();
        mUploadMessage.onReceiveValue(result);
        mUploadMessage = null;
    }
}

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    web = (WebView) findViewById(R.id.wView);

    web = new WebView(this);
    web.getSettings().setJavaScriptEnabled(true);
    web.loadUrl("http://minkme.org/minkmeuser/image_preview1.jsp");
    web.setWebViewClient(new myWebClient());
    web.setWebChromeClient(new WebChromeClient() {
        // The undocumented magic method override
        // Eclipse will swear at you if you try to put @Override here
        // For Android 3.0+
        public void openFileChooser(ValueCallback<Uri> uploadMsg) {

            mUploadMessage = uploadMsg;
            Intent i = new Intent(Intent.ACTION_GET_CONTENT);
            i.addCategory(Intent.CATEGORY_OPENABLE);
            i.setType("image/*");
            MainActivity.this.startActivityForResult(
                    Intent.createChooser(i, "File Chooser"),
                    FILECHOOSER_RESULTCODE);

        }

        // For Android 3.0+
        public void openFileChooser(ValueCallback uploadMsg,
                String acceptType) {
            mUploadMessage = uploadMsg;
            Intent i = new Intent(Intent.ACTION_GET_CONTENT);
            i.addCategory(Intent.CATEGORY_OPENABLE);
            i.setType("*/*");
            MainActivity.this.startActivityForResult(
                    Intent.createChooser(i, "File Browser"),
                    FILECHOOSER_RESULTCODE);
        }

        // For Android 4.1
        public void openFileChooser(ValueCallback<Uri> uploadMsg,
                String acceptType, String capture) {
            mUploadMessage = uploadMsg;
            Intent i = new Intent(Intent.ACTION_GET_CONTENT);
            i.addCategory(Intent.CATEGORY_OPENABLE);
            i.setType("image/*");
            MainActivity.this.startActivityForResult(
                    Intent.createChooser(i, "File Chooser"),
                    MainActivity.FILECHOOSER_RESULTCODE);

        }

    });

    setContentView(web);

}

public class myWebClient extends WebViewClient {
    @Override
    public void onPageStarted(WebView view, String url, Bitmap favicon) {
        // TODO Auto-generated method stub
        super.onPageStarted(view, url, favicon);
    }

    @Override
    public boolean shouldOverrideUrlLoading(WebView view, String url) {
        // TODO Auto-generated method stub

        view.loadUrl(url);
        return true;

    }

    @Override
    public void onPageFinished(WebView view, String url) {
        // TODO Auto-generated method stub
        super.onPageFinished(view, url);

    }
}

// flipscreen not loading again
@Override
public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);
}

// To handle "Back" key press event for WebView to go back to previous
// screen.
/*
 * @Override public boolean onKeyDown(int keyCode, KeyEvent event) { if
 * ((keyCode == KeyEvent.KEYCODE_BACK) && web.canGoBack()) { web.goBack();
 * return true; } return super.onKeyDown(keyCode, event); }
 */
     }

I aim to enable image browsing from an Android phone using input type="file".

Answer №1

If you're looking for information about handling input files, check out this link: Input file in a webview

After conducting some tests, I discovered that using document.getElementById.click works perfectly. I tested it with the following changes:

test.html

<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>JSP Page</title>
    <script src="jquery-1.11.1.min.js">    </script>
    <script>

        function img_prvw(id1,id2)/*******************show preview of  image*******************/
        {
            console.log("Call of img_prvw");
            var oFiles = document.getElementById(id1).files;
            var valid_extensions = /(.jpg|.jpeg|.png)$/i;
            if(!(valid_extensions.test(document.getElementById(id1).files[0].name)))
            {
                document.getElementById('er').innerHTML="Select jpg or png image";
            }
            else
            {
                var reader = new FileReader();
                reader.readAsDataURL(oFiles[0]);
                reader.onload=
                        function (e) {
                            document.getElementById(id2).src=e.target.result;
                        };
            }
        }

        function onAdvrtsImgPrvwClick() {
            console.log('Clickevent');
            document.getElementById('advrts_img').click();
        }

    </script>
</head>
<body>
<input type="file" style="display: none;" id="advrts_img" name="advrts_img" onclick="console.log('click on input');" onchange="img_prvw('advrts_img','advrts_img_prvw')">
<img src="images/img_place.png" id="advrts_img_prvw" alt="" class="cursor margin_top10" style="width:100px;height:100px" onClick="onAdvrtsImgPrvwClick()">
</body>
</html>

MainActivity.java

public class MainActivity extends Activity {

private WebView mWebview;
static final String TAG = "MainActivity";

@Override
public void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    mWebview = (WebView) findViewById(R.id.webView1);

    mWebview.getSettings().setJavaScriptEnabled(true); // enable javascript

    final Activity activity = this;

    mWebview.setWebViewClient(new WebViewClient() {
        public void onReceivedError(WebView view, int errorCode,
                String description, String failingUrl) {
            Toast.makeText(activity, description, Toast.LENGTH_SHORT)
                    .show();
        }
    });

    mWebview.setWebChromeClient(new WebChromeClient() {
        @Override
        public boolean onConsoleMessage(ConsoleMessage cm)
        {
            String msg = cm.message() + " -- From line " + cm.lineNumber() + " of " + cm.sourceId();
            switch (cm.messageLevel()) {
                case ERROR:
                    Log.e(TAG, msg);
                    break;
                case LOG:
                case TIP:
                    Log.i(TAG, msg);
                    break;
                case WARNING:
                    Log.w(TAG, msg);
                    break;
                case DEBUG:
                default:
                    Log.d(TAG, msg);
                    break;
            }

            return true;
        }
    });


    mWebview.loadUrl("file:///android_asset/test.html");
    //setContentView(mWebview);

}
}

It seems that the console displays the message 'click on input', indicating that the call is correct, however, the onchange event is not being triggered properly.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Positioning Elements in the Javafx Scene: A Comprehensive Guide

I was curious about the way certain elements can be centered within a scene. As I grasped how scenes work, you could: Create a search - TextField Add TextField to HBox/VBox Add HBox to the scene Show the Scene Positioning elements within a HBox ...

Unable to retrieve record with MongoJs

I am experiencing an issue with my login system connected to a MongoDB database - the result is always 0 even when searching for a record I know exists. thePass = passWord.value theUser = userName.value loginButton.onclick = function() { console.log ...

Incorporating an NPM module into a React file: Webpack encounters resolution issues

After reviewing information from this source and here, the process of publishing a react module to NPM and then using it in another project while having the component in the node_modules directory should be as follows: Create and export a module Specify ...

Can all the keys in an object be updated in an atomic manner? Is there a way to achieve this, similar to using splice for an array?

Currently in the process of implementing undo/redo functionality for a project I am working on. To ensure a smooth undo/redo feature, changes must be atomic to avoid stepping through each small change individually as if they were separate operations. Whi ...

Troubleshooting a Node.js and MongoDB issue: Document Property displays as 'Undefined' upon printing

As I delve into learning Node, Express & Mongodb, I find myself at the beginner level. Currently, my focus is on developing a form that includes a text field for users to input data. My primary objective is to validate whether this data already exists in ...

JS limits browsers to downloading only 10 images simultaneously

Is there a way to increase the number of simultaneous downloads beyond the current limit of 10 in the code below? transferFiles(){ this.checkMark = true let i = 0 this.finalImages.forEach((image) =>{ i++ saveAs(image, 'imag ...

Error encountered: Unexpected '<' token when trying to deploy

Trying to deploy a React app with React Router on a Node/Express server to Heroku, but encountering the following error... 'Uncaught SyntaxError: Unexpected token <' Suspecting the issue may lie in the 'catch all' route in the Expr ...

Acquiring and transferring parental data to a concealed form

Within a WordPress plugin called postRatings, users can add a "like" to a page by clicking on a nested image. I am looking to transfer this information to a hidden form. When the user clicks the img that triggers the plugin functionality, I aim to retriev ...

The Pro Version app apk size balloons to twice the size of the free version app when installed from the Playstore

I have developed two versions of my application: FREE and PRO. Interestingly, when I generate the APKs for these versions, they are the same size. However, once they are downloaded from Google Play, the PRO version appears to be twice as big. Below is my ...

Three.js Image Processing with Effect Composer

After reviewing the example located at: I am intrigued by the possibility of applying post-processing effects on a duplicate of the initial data set. Essentially, I am interested in showcasing the original rendering of my scene in one container while simu ...

Utilizing an object property to set the $maxDistance parameter in a mongodb query for geolocation

Can I create a $near query in MongoDB with a dynamic $maxDistance argument? For instance, I have a collection of fire stations each with a varying coverage radius, and I want to find stations that cover a specific point. In my collection, the documents fo ...

Update the link to a KML file used by Google Maps when a button is clicked

On the initial page load, I want to showcase an 8 Day Average KML file on Google Maps. However, users should have the option to click on the "1 Day" and "3 Day" buttons to switch the reference in Google Maps from the "8 Day" file. The aim is to design a s ...

Prevent anchor tags from modifying the current URL

In the realm of React, I am endeavoring to incorporate an anchor tag that directs users to an external website "https://www.google.com/". Within my code, there exist two instances of this very anchor tag. The initial tag functions as intended, effortless ...

Is it possible to load asynchronous JS and then execute functions?

Is there a way to make my script behave like the Google Analytics JavaScript snippet? Here is an example of what I have: (function(d, t) { var g = d.createElement(t), s = d.getElementsByTagName(t)[0]; g.src = 'myjs.js'; s.par ...

How can we send data from several input fields using jQuery ajax?

I have several input fields, such as <p>Filter by age</p> <select class="filter-users"> <option value="under20">Under 20</option> <option value="20to40">20 to 40</option> </select> <p& ...

The invalid `autoComplete` prop with a type of `boolean` was passed to `ForwardRef(InputBase)` instead of the expected `string`

Can anyone help me understand why a warning is being thrown when I have an autocomplete feature on this textfield? <TextField type="text" id="standard1" label="Email" ...

Progress persists despite setbacks

Having some asynchronous code that needs to halt in case of error but continues to execute: async saveCoupons({ state, rootState, dispatch, commit }) { const promises = [] state.userCoupons.forEach(coupon => { if (coupon.isNew &&am ...

ML Kit face recognition from Google is unable to detect faces from a URI

I have been utilizing Google ML Kit for face detection and using the bounding Box function to crop faces. After successfully integrating cameras, I wanted to add a "select from gallery" function. I had previously implemented this in a training app written ...

Erasing a comment creates empty spaces

I've encountered an issue with my idea whiteboard where removing comments leaves unwanted blank spaces between ideas. For example, if I have the following comments: But when I delete something: Is there a way to ensure that no gaps are left between ...

Rotating Image Viewer Display

I am in the process of developing an android widget application that showcases a series of images in a repeated loop. This widget acts as a mimic of a website image banner rotator. To achieve this, I have implemented a ScheduledExecutorService that handle ...