Android, can't upload images using WebView

时间:2016-04-04 18:20:39

标签: android image input webview crop

I'm looking for a solution for some days for my problem but I can't find a good one. So I wanted to ask here again before I start developing a native app for Android since I can't solve this problem.

As the title says, I'm trying to upload an image by using webview to a html content which NORMALLY is choosing an image, showing it on the page and allowing user to crop it. I made whole app and had tested it on normal browser of my phone so I didn't know that this woulnd't work. That's why it's damn frustrating.

Those solutions which I've found on internet are not working for my Android and I read that it's nor possible anymore.

Does anyone know if this is possible or not? It would be a great help if I could get more informtions about this (even if it's possible or not?) Thanks in Adavnce...

4 个答案:

答案 0 :(得分:6)

尝试添加这些权限。

<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引入了一种新的处理模型   权限,简化了用户安装时的流程   和升级应用程序。如果您使用的是Google 8.1或更高版本   播放服务,您可以配置您的应用程序以定位Android 6.0   Marshmallow SDK并使用新的权限模型。

     

如果您的应用支持新的权限模型,则用户没有   在安装或升级应用程序时授予任何权限。   相反,应用程序必须在需要时请求权限   运行时,系统显示一个对话框,询问用户   权限。

     

要了解详情,请参阅Android 6.0 Marshmallow和的文档   您必须对new permissions model的应用进行的更改。

Google已添加WebChromeClient.onShowFileChooser。它们甚至提供了一种自动生成文件选择器意图的方法,以便它使用输入接受mime类型。

以这种方式实施(来自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;
            }
        }
    }
}

确保使用API​​ 21+编译应用程序。当你在gradle上提到时,这将适用于所有平台。

答案 1 :(得分:3)

没有答案在这里解决这个问题..一些专家的android人正在为构建图像上传到android代码提供解决方案..这不是问这个问题..我有同样的问题打扰我..我们要问的是加载到webview应用程序的HTML / PHP页面没有触发图库或相机应用程序,因为它触发了在Mozilla或Chrome中的桌面计算机/笔记本电脑上的“从PC上传文件”。这就像在iframe中的网络类似。但是在Android应用程序的网页视图中..我想我已经说清楚了..我们不是android程序员,我们是web开发人员。

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

答案 2 :(得分:1)

这是API 11到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;

现在修改或覆盖您的onActivityResult方法

@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();

}

现在在onCreate方法中粘贴以下代码

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);
}
});

答案 3 :(得分:1)

有点晚了,上面的答案很有帮助,但是我发现Google自己做了一个很棒的实现。

inputfilesample in chromium-webview-samples

该存储库已存档,但该示例的工作原理很简单。