WebView上传文件

来源:互联网 发布:手机zip解压软件 编辑:程序博客网 时间:2024/06/06 12:58

android webview本身不支持文件上传,因此我们需要重写webview的WebChromeClient,对其中的onShowFileChooser(高版本会调用这个)和openFileChooser(低版本会调用这个)做相应处理,先上代码:

public class MyChromeClient extends WebChromeClient {private UrlActivity activity;public static final int FILECHOOSER_RESULTCODE = 5173;public static String mCameraFilePath = "";@SuppressWarnings("deprecation")public MyChromeClient(UrlActivity cordova) {this.activity = cordova;}@Overridepublic void onProgressChanged(WebView view, int newProgress) {super.onProgressChanged(view, newProgress);}// <input type="file" name="fileField" id="fileField" />// Android > 4.1.1@Overridepublic boolean onShowFileChooser(WebView webView, ValueCallback<Uri[]> filePathCallback,FileChooserParams fileChooserParams) {// TODO 自动生成的方法存根this.activity.setmUploadMsgList(filePathCallback);// UploadMsg2 = filePathCallback;this.activity.startActivityForResult(createDefaultOpenableIntent(), this.FILECHOOSER_RESULTCODE);// return false;// Intent intent = new Intent(Intent.ACTION_GET_CONTENT);// intent.addCategory(Intent.CATEGORY_OPENABLE);// intent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,// "image/*");// this.activity.startActivityForResult(Intent.createChooser(intent,// ""), this.FILECHOOSER_RESULTCODE);return true;                            //  如果返回false,在选择文件过程中按返回键会崩溃,不知道为啥}@SuppressWarnings("static-access")public void openFileChooser(ValueCallback<Uri> uploadMsg,String acceptType, String capture) {this.activity.setmUploadMsg(uploadMsg);this.activity.startActivityForResult(createDefaultOpenableIntent(), this.FILECHOOSER_RESULTCODE);}// 3.0 +@SuppressWarnings("static-access")public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType) {this.activity.setmUploadMsg(uploadMsg);this.activity.startActivityForResult(createDefaultOpenableIntent(), this.FILECHOOSER_RESULTCODE);}// Android < 3.0@SuppressWarnings("static-access")public void openFileChooser(ValueCallback<Uri> uploadMsg) {this.activity.setmUploadMsg(uploadMsg);this.activity.startActivityForResult(createDefaultOpenableIntent(), this.FILECHOOSER_RESULTCODE);}private Intent createDefaultOpenableIntent() {Intent i = new Intent(Intent.ACTION_GET_CONTENT);i.addCategory(Intent.CATEGORY_OPENABLE);i.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,"image/*");Intent chooser = createChooserIntent(createCameraIntent()/* *  * , *  * createCamcorderIntent *  * (), *  * createSoundRecorderIntent *  * () */);chooser.putExtra(Intent.EXTRA_INTENT, i);return chooser;}private Intent createChooserIntent(Intent... intents) {Intent chooser = new Intent(Intent.ACTION_CHOOSER);chooser.putExtra(Intent.EXTRA_INITIAL_INTENTS, intents);chooser.putExtra(Intent.EXTRA_TITLE, "选择图片");return chooser;}@SuppressWarnings("static-access")private Intent createCameraIntent() {Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);File externalDataDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM);File cameraDataDir = new File(externalDataDir.getAbsolutePath()+ File.separator + "515aaa");cameraDataDir.mkdirs();String mCameraFilePath = cameraDataDir.getAbsolutePath()+ File.separator + System.currentTimeMillis() + ".jpg";this.mCameraFilePath = mCameraFilePath;cameraIntent.putExtra(MediaStore.Images.Media.ORIENTATION, 0);cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT,Uri.fromFile(new File(mCameraFilePath)));return cameraIntent;}/* *  * private Intent createCamcorderIntent() { return new *  * Intent(MediaStore.ACTION_VIDEO_CAPTURE); } *  *  *  * private Intent createSoundRecorderIntent() { return new *  * Intent(MediaStore.Audio.Media.RECORD_SOUND_ACTION); } */public static Uri getImageContentUri(Context context, java.io.File imageFile) {String filePath = imageFile.getAbsolutePath();Cursor cursor = context.getContentResolver().query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,new String[] { MediaStore.Images.Media._ID },MediaStore.Images.Media.DATA + "=? ",new String[] { filePath }, null);if (cursor != null && cursor.moveToFirst()) {int id = cursor.getInt(cursor.getColumnIndex(MediaStore.MediaColumns._ID));Uri baseUri = Uri.parse("content://media/external/images/media");return Uri.withAppendedPath(baseUri, "" + id);} else {if (imageFile.exists()) {ContentValues values = new ContentValues();values.put(MediaStore.Images.Media.DATA, filePath);return context.getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);} else {return null;}}}}


使用时只需要Webview.setWebChromeClient(new MyChromeClient(this));

此时还需要重写加载webview的这个Activity的onActivityResult方法,在这里才是把文件传给web的


@Overrideprotected void onActivityResult(int requestCode, int resultCode, Intent data) {switch (requestCode) {case MyChromeClient.FILECHOOSER_RESULTCODE:if (null == mUploadMsg && null == mUploadMsgList) {Log.i("webview activity", "UploadMsg =null");return;}Uri result = data == null || resultCode != RESULT_OK ? null : data.getData();if (result != null) {if (null != mUploadMsg) {mUploadMsg.onReceiveValue(result);}if (null != mUploadMsgList) {mUploadMsgList.onReceiveValue(new Uri[] { result });}} else {Log.i("webview activity", "result =null");setResultNull();}break;default:break;}}

private void setResultNull() {if (null != mUploadMsg) {mUploadMsg.onReceiveValue(null);  }if (null != mUploadMsgList) {mUploadMsgList.onReceiveValue(null);}}
mUploadMsg.onReceiveValue(null); 和mUploadMsgList.onReceiveValue(null);是必须要有的,比如正在选择图片上传时按返回键,如果不回传null,
web端会一直等待结果,导致你再次点击无响应。


mUploadMsgList是ValueCallback<Uri[]> 的对象,4.1以后的版本都使用的是Uri数组回传,以前是使用Uri即只能传单个文件
 mUploadMsg是ValueCallback<Uri>的对象,这两个变量定义在WebView的activity里面,在MyChromeClient里面是有相应赋值的。

如此即可。