在以前做的项目里遇到一个奇葩问题,在ios和微信都可以,但是就是在android端不行,无论你多使劲点都发现无法弹出安卓原生文件选择界面,简直要崩溃了
通过一番资料查询,发现要重写WebChromeClient类里面的方法
先说一下执行的步骤:
1.通过webview.setWebChromeClient(),传入一个WebChromeClient的实现类,在WebChromeClient实现类里面我们要重写里面的openFileChooser方法,这个方法会在文件准备上传时进行回调。
2.在openFileChooser这个方法里面我们设置Intent打开支持第三方文件的应用
3.然后在ActivityResult将第三方应用提供的内容通过ValueCallback的存储形式回传给webview。
一言不合直接贴代码..
- <span style="color:#ff6666;font-size:24px;"> </span><span style="font-size:18px;">public void openFileChooser(ValueCallback<Uri> uploadMsg) {
- Log.d(TAG, "openFileChoose(ValueCallback<Uri> uploadMsg)");
- mUploadMessage = uploadMsg;
- Intent i = new Intent(Intent.ACTION_GET_CONTENT);
- i.addCategory(Intent.CATEGORY_OPENABLE);
- i.setType("*/*");
- MainActivity.this.startActivityForResult(Intent.createChooser(i, "File Chooser"), FILECHOOSER_RESULTCODE);
- }
- public void openFileChooser( ValueCallback uploadMsg, String acceptType ) {
- Log.d(TAG, "openFileChoose( 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);
- }
- public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType, String capture){
- Log.d(TAG, "openFileChoose(ValueCallback<Uri> uploadMsg, String acceptType, String capture)");
- 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" ), MainActivity.FILECHOOSER_RESULTCODE );
- }</span>
接下来是ActivityForResult的方法实现
- if(requestCode==FILECHOOSER_RESULTCODE)
- {
- if (null == mUploadMessage && null == mUploadCallbackAboveL) return;
- Uri result = data == null || resultCode != RESULT_OK ? null : data.getData();
- if (mUploadMessage != null) {
- mUploadMessage.onReceiveValue(result);
- mUploadMessage = null;
- }
- }
你会发现安卓5.0以上的机器还是没有反应,后来发现它回调的不是openFileChooser而是onShowFileChooser!!挖槽,挖槽,挖槽。
这简直是一个大坑啊!!!~~~~直接看代码
- // For Android 5.0+
- public boolean onShowFileChooser (WebView webView, ValueCallback<Uri[]> filePathCallback, WebChromeClient.FileChooserParams fileChooserParams) {
- mUploadCallbackAboveL = filePathCallback;
- 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);
- return true;
- }
- });
- @Override
- protected void onActivityResult(int requestCode, int resultCode, Intent data) {
- super.onActivityResult(requestCode, resultCode, data);
- if(requestCode==FILECHOOSER_RESULTCODE)
- {
- if (null == mUploadMessage && null == mUploadCallbackAboveL) return;
- Uri result = data == null || resultCode != RESULT_OK ? null : data.getData();
- if (mUploadCallbackAboveL != null) {
- onActivityResultAboveL(requestCode, resultCode, data);
- }
- else if (mUploadMessage != null) {
- mUploadMessage.onReceiveValue(result);
- mUploadMessage = null;
- }
- }
- }
- @TargetApi(Build.VERSION_CODES.LOLLIPOP)
- private void onActivityResultAboveL(int requestCode, int resultCode, Intent data) {
- if (requestCode != FILECHOOSER_RESULTCODE
- || mUploadCallbackAboveL == null) {
- return;
- }
- Uri[] results = null;
- if (resultCode == Activity.RESULT_OK) {
- if (data == null) {
- } else {
- String dataString = data.getDataString();
- ClipData clipData = data.getClipData();
- if (clipData != null) {
- results = new Uri[clipData.getItemCount()];
- for (int i = 0; i < clipData.getItemCount(); i++) {
- ClipData.Item item = clipData.getItemAt(i);
- results[i] = item.getUri();
- }
- }
- if (dataString != null)
- results = new Uri[]{Uri.parse(dataString)};
- }
- }
- mUploadCallbackAboveL.onReceiveValue(results);
- mUploadCallbackAboveL = null;
- return;
- }