Android, can't upload images using WebView

Try adding these permissions.

<uses-permission android:name="android.permission.INTERNET" /> 
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> 
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

Android 6.0 Marshmallow introduces a new model for handling permissions, which streamlines the process for users when they install and upgrade apps. Provided you're using version 8.1 or later of Google Play services, you can configure your app to target the Android 6.0 Marshmallow SDK and use the new permissions model.

If your app supports the new permissions model, the user does not have to grant any permissions when they install or upgrade the app. Instead, the app must request permissions when it needs them at runtime, and the system shows a dialog to the user asking for the permission.

To learn more, see the documentation for Android 6.0 Marshmallow and the changes you must make to your app for the new permissions model.

Google has added WebChromeClient.onShowFileChooser. They even provide a way to automatically generate the file chooser intent so that it uses the input accept mime types.

Implement it in this way (from an answer by weiyin):

public class MyWebChromeClient extends WebChromeClient {
        // reference to activity instance. May be unnecessary if your web chrome client is member class.
    private MyActivity myActivity;

    public boolean onShowFileChooser(WebView webView, ValueCallback<Uri[]> filePathCallback, FileChooserParams fileChooserParams) {
        // make sure there is no existing message
        if (myActivity.uploadMessage != null) {
            myActivity.uploadMessage.onReceiveValue(null);
            myActivity.uploadMessage = null;
        }

        myActivity.uploadMessage = filePathCallback;

        Intent intent = fileChooserParams.createIntent();
        try {
            myActivity.startActivityForResult(intent, MyActivity.REQUEST_SELECT_FILE);
        } catch (ActivityNotFoundException e) {
            myActivity.uploadMessage = null;
            Toast.makeText(myActivity, "Cannot open file chooser", Toast.LENGTH_LONG).show();
            return false;
        }

        return true;
    }
}


public class MyActivity extends ... {
    public static final int REQUEST_SELECT_FILE = 100;
    public ValueCallback<Uri[]> uploadMessage;

    protected void onActivityResult(int requestCode, int resultCode, Intent data){
        if (requestCode == REQUEST_SELECT_FILE) {
                if (uploadMessage == null) return;
                uploadMessage.onReceiveValue(WebChromeClient.FileChooserParams.parseResult(resultCode, data));
                uploadMessage = null;
            }
        }
    }
}

Make sure to compile the app with API 21+. And this will work on all the platforms as you mention on your gradle.


This is the working method from API 11 to 23

static WebView mWebView;
private ValueCallback<Uri> mUploadMessage;
public ValueCallback<Uri[]> uploadMessage;
public static final int REQUEST_SELECT_FILE = 100;
private final static int FILECHOOSER_RESULTCODE = 1;

Now modify or override your onActivityResult method

@Override
public void onActivityResult(int requestCode, int resultCode, Intent intent)
{
    if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
    {
        if (requestCode == REQUEST_SELECT_FILE)
        {
            if (uploadMessage == null)
                return;
                uploadMessage.onReceiveValue(WebChromeClient.FileChooserParams.parseResult(resultCode, intent));
        uploadMessage = null;
    }
}
else if (requestCode == FILECHOOSER_RESULTCODE)
{
    if (null == mUploadMessage)
        return;
// Use MainActivity.RESULT_OK if you're implementing WebView inside Fragment
// Use RESULT_OK only if you're implementing WebView inside an Activity
    Uri result = intent == null || resultCode != MainActivity.RESULT_OK ? null : intent.getData();
    mUploadMessage.onReceiveValue(result);
    mUploadMessage = null;
}
else
    Toast.makeText(getActivity().getApplicationContext(), "Failed to Upload Image", Toast.LENGTH_LONG).show();
}

Now in the onCreate method paste the following code

mWebView.setWebChromeClient(new WebChromeClient()
{
// For 3.0+ Devices (Start)
// onActivityResult attached before constructor
protected void openFileChooser(ValueCallback uploadMsg, String acceptType)
{
    mUploadMessage = uploadMsg;
    Intent i = new Intent(Intent.ACTION_GET_CONTENT);
    i.addCategory(Intent.CATEGORY_OPENABLE);
    i.setType("image/*");
    startActivityForResult(Intent.createChooser(i, "File Browser"), FILECHOOSER_RESULTCODE);
}


// For Lollipop 5.0+ Devices
public boolean onShowFileChooser(WebView mWebView, ValueCallback<Uri[]> filePathCallback, WebChromeClient.FileChooserParams fileChooserParams)
{
    if (uploadMessage != null) {
        uploadMessage.onReceiveValue(null);
        uploadMessage = null;
    }

    uploadMessage = filePathCallback;

    Intent intent = fileChooserParams.createIntent();
    try
    {
        startActivityForResult(intent, REQUEST_SELECT_FILE);
    } catch (ActivityNotFoundException e)
    {
        uploadMessage = null;
        Toast.makeText(getActivity().getApplicationContext(), "Cannot Open File Chooser", Toast.LENGTH_LONG).show();
        return false;
    }
    return true;
}

//For Android 4.1 only
protected void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType, String capture)
{
    mUploadMessage = uploadMsg;
    Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
    intent.addCategory(Intent.CATEGORY_OPENABLE);
    intent.setType("image/*");
    startActivityForResult(Intent.createChooser(intent, "File Browser"), FILECHOOSER_RESULTCODE);
}

protected void openFileChooser(ValueCallback<Uri> uploadMsg)
{
    mUploadMessage = uploadMsg;
    Intent i = new Intent(Intent.ACTION_GET_CONTENT);
    i.addCategory(Intent.CATEGORY_OPENABLE);
    i.setType("image/*");
    startActivityForResult(Intent.createChooser(i, "File Chooser"), FILECHOOSER_RESULTCODE);
}
});

No answer is addressing the issue here.. some expert android people are giving solution for building image upload into android code.. that is not this question asking for.. I have same issue bothering me.. What we are asking is the HTML/PHP page which is loaded into webview app is not triggering gallery or camera app as it triggers 'upload file from PC' on a desktop computer/laptop in Mozilla or chrome.. It is like web from in iframe kind a thing.. but inside android app's web view.. I think I have made it clear.. We are not android programers we are web developers.

<form method="post" action="" enctype="multipart/form-data" name="form1">
<!-- this following input is not working in webview -->
<input size="25" name="file" type="file">
<input name="submit" type="submit" value="submit">
</form>