WebView中的文件上载

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了WebView中的文件上载相关的知识,希望对你有一定的参考价值。

自从过去几天以来,我一直在努力从WebView上传文件,但没有任何进展。我用谷歌搜索并实现了所有建议的解决方案,但没有一个工作,如:解决方案建议here,等等。

问题:我有一个带有以下代码的html页面来上传文件。它在Firefox等桌面浏览器和模拟器/ AVD的内置浏览器中工作正常,当我点击元素呈现的“浏览...”按钮时,浏览器会打开一个对话框,我可以在其中选择要上传的文件。

但是,在android 3.0模拟器/ AVD中,当我点击“选择文件”时,没有任何反应,没有打开文件对话框!

<form method="POST" enctype="multipart/form-data">
File to upload: <input type="file" name="uploadfile">&nbsp;&nbsp;
<input type="submit" value="Press to Upload..."> to upload the file!
</form>

有人可以最早建议一个可能的解决方案。

答案

这是所有Android版本的完整解决方案,我也很难。

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

WebView web;
ProgressBar progressBar;

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.main);

    web = (WebView) findViewById(R.id.webview01);
    progressBar = (ProgressBar) findViewById(R.id.progressBar1);

    web = new WebView(this);  
    web.getSettings().setjavascriptEnabled(true);
    web.loadUrl("http://www.script-tutorials.com/demos/199/index.html");
    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/*");  
            MyWb.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("*/*");
           MyWb.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/*");  
               MyWb.this.startActivityForResult( Intent.createChooser( i, "File Chooser" ), MyWb.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);

        progressBar.setVisibility(View.GONE);
    }
}

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

另外我想补充一点,这个例子中的“上传页面”不适用于<4个版本,因为它有图像预览功能,如果你想让它工作使用简单的php上传而不预览。

更新:

请找到棒棒糖设备here的解决方案,并感谢gauntface

更新2:

所有Android设备的完整解决方案,直到oreo herethis is more advanced version,你应该调查它,也许它可以帮助。

另一答案

这对我有用。也适用于Nougat和Marshmallow [[

import android.Manifest;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.res.Configuration;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.webkit.ValueCallback;
import android.webkit.WebChromeClient;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.Toast;

import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class MainActivity extends AppCompatActivity {
    private static final String TAG = MainActivity.class.getSimpleName();
    private final static int FCR = 1;
    WebView webView;
    private String mCM;
    private ValueCallback<Uri> mUM;
    private ValueCallback<Uri[]> mUMA;

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
        super.onActivityResult(requestCode, resultCode, intent);

        if (Build.VERSION.SDK_INT >= 21) {
            Uri[] results = null;

            //Check if response is positive
            if (resultCode == Activity.RESULT_OK) {
                if (requestCode == FCR) {

                    if (null == mUMA) {
                        return;
                    }
                    if (intent == null) {
                        //Capture Photo if no image available
                        if (mCM != null) {
                            results = new Uri[]{Uri.parse(mCM)};
                        }
                    } else {
                        String dataString = intent.getDataString();
                        if (dataString != null) {
                            results = new Uri[]{Uri.parse(dataString)};
                        }
                    }
                }
            }
            mUMA.onReceiveValue(results);
            mUMA = null;
        } else {

            if (requestCode == FCR) {
                if (null == mUM) return;
                Uri result = intent == null || resultCode != RESULT_OK ? null : intent.getData();
                mUM.onReceiveValue(result);
                mUM = null;
            }
        }
    }

    @SuppressLint({"SetJavaScriptEnabled", "WrongViewCast"})
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        if (Build.VERSION.SDK_INT >= 23 && (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED || ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED)) {
            ActivityCompat.requ

以上是关于WebView中的文件上载的主要内容,如果未能解决你的问题,请参考以下文章

在 webview_flutter 中启用捏合和缩放,在哪里添加代码片段 [this.webView.getSettings().setBuiltInZoomControls(true);]

带有 Webview 的片段利用硬件后退按钮转到上一个网页

没有带有拉动刷新的互联网消息 webview 片段

Android tv:标题片段中每个项目的 Webview

我的片段中有 webview,当滑动 webview 时, viewPager 也开始滑动

详解Android WebView加载html片段