问题一:
WebView文件上传问题。
在安卓里webview加载的网页标签<input type=file/>上传是不成功的,需要重写WebChromeClient的openFileChooser和onShowFileChooser,才能实现文件标签功能。那么,为什么要实现两种不同名字的方法呢。下面将给出解答以及实现。
在之前,实现openFileChooser的方法,重载此方法,参数不同,适应不同版本的安卓手机,对于绝大部分版本的安卓机子都没问题。但是自从出了LOLLIPOP,这个方式就在5.0的机子上不管用了,以至于如今的6.0手机。这是因为安卓5.0的新增的更新改进,增加了onShowFileChooser方法,在5.0以上版本手机可以使WebView
中使用输入表单字段和启动文件选择器从 Android 设备中选择图片和文件。
上代码:
重写WebChromeClient
import android.annotation.TargetApi; import android.app.Activity; import android.content.ActivityNotFoundException; import android.content.Intent; import android.net.Uri; import android.os.Build; import android.webkit.ValueCallback; import android.webkit.WebChromeClient; import android.webkit.WebView; import android.widget.Toast; /** * */ public class CustomWebChromeClient extends WebChromeClient{ private Activity activity=null; private int FILECHOOSER_RESULTCODE=0; private int REQUEST_SELECT_FILE = 0; private ValueCallback<Uri> mUploadMessage; public CustomWebChromeClient(Activity activity,int FILECHOOSER_RESULTCODE,int REQUEST_SELECT_FILE) { this.activity=activity; this.FILECHOOSER_RESULTCODE=FILECHOOSER_RESULTCODE; this.REQUEST_SELECT_FILE=REQUEST_SELECT_FILE; } public void openFileChooser(ValueCallback<Uri> uploadMsg) { if (activity.getClass()== MainActivity.class) { ((MainActivity)activity).mUploadMessage=uploadMsg; } mUploadMessage = uploadMsg; Intent i = new Intent(Intent.ACTION_GET_CONTENT); i.addCategory(Intent.CATEGORY_OPENABLE); i.setType("*/*"); activity.startActivityForResult(Intent.createChooser(i, "文件选择"), FILECHOOSER_RESULTCODE); } // For Android 3.0+ public void openFileChooser( ValueCallback uploadMsg, String acceptType ) { if (activity.getClass()== MainActivity.class) { ((MainActivity)activity).mUploadMessage=uploadMsg; } mUploadMessage = uploadMsg; Intent i = new Intent(Intent.ACTION_GET_CONTENT); i.addCategory(Intent.CATEGORY_OPENABLE); i.setType("*/*"); activity.startActivityForResult( Intent.createChooser(i, "文件选择"), FILECHOOSER_RESULTCODE); } //For Android 4.1 public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType, String capture){ if (activity.getClass()== MainActivity.class) { ((MainActivity)activity).mUploadMessage=uploadMsg; } mUploadMessage = uploadMsg; Intent i = new Intent(Intent.ACTION_GET_CONTENT); i.addCategory(Intent.CATEGORY_OPENABLE); i.setType("*/*"); activity.startActivityForResult(Intent.createChooser(i, "文件选择"), FILECHOOSER_RESULTCODE ); } // For >= Lollipop 5.0 @TargetApi(Build.VERSION_CODES.LOLLIPOP) public boolean onShowFileChooser(WebView mWebView, ValueCallback<Uri[]> filePathCallback, WebChromeClient.FileChooserParams fileChooserParams) { if (((MainActivity) activity).uploadMessage != null) { ((MainActivity) activity).uploadMessage.onReceiveValue(null); ((MainActivity) activity).uploadMessage = null; } ((MainActivity) activity).uploadMessage = filePathCallback; Intent intent = fileChooserParams.createIntent(); try { activity.startActivityForResult(intent, REQUEST_SELECT_FILE); } catch (ActivityNotFoundException e) { ((MainActivity) activity).uploadMessage = null; Toast.makeText(activity.getApplicationContext(), "不能打开文件选择器", Toast.LENGTH_LONG).show(); return false; } return true; } } MainActivity代码:import android.app.Activity; import android.content.Intent; import android.net.Uri; import android.os.Build; import android.os.Bundle; import android.view.KeyEvent; import android.webkit.ValueCallback; import android.webkit.WebChromeClient; import android.webkit.WebView; import android.widget.Toast; public class MainActivity extends Activity { public ValueCallback<Uri> mUploadMessage; public final static int FILECHOOSER_RESULTCODE=1; public ValueCallback<Uri[]> uploadMessage; public static final int REQUEST_SELECT_FILE = 100; private WebView webView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); webView = new WebView(this);webView.getSettings().setJavaScriptEnabled(true);webView.setWebChromeClient(new CustomWebChromeClient(activity, FILECHOOSER_RESULTCODE,REQUEST_SELECT_FILE)); setContentView(webView); } @Override public boolean onKeyDown(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK) { if (webView .canGoBack()) { webView .goBack(); return false; } else { return super.onKeyDown(keyCode, event); } } else { return super.onKeyDown(keyCode, event); } } @Override protected 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; Uri result = intent == null || resultCode != MainActivity.RESULT_OK ? null : intent.getData(); mUploadMessage.onReceiveValue(result); mUploadMessage = null; } else { Toast.makeText(this.getApplicationContext(), "Failed to Upload Image", Toast.LENGTH_LONG).show(); } }} 以免扰乱阅读,本例子仅仅单纯的解决的文件标签的问题。
github地址:https://github.com/xiaoyunchengzhu/AndroidAndH5