项目中遇到了需要在webview上传图片的需求，搜索了一把，找到几个可行的方法，同时也踩了个webview的坑，总结一下我找到的是这样的方法***首先 重写WebChromeClient 添加openFileChooser 方法 // For Android 3.0+public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType) {//最终调用的都是这个if (mUploadMessage != null) return;//坑就在这里 看后边注释mUploadMessage = uploadMsg;selectImage();}// For Android < 3.0public void openFileChooser(ValueCallback<Uri> uploadMsg) {openFileChooser(uploadMsg, "");}// For Android > 4.1.1public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType, String capture) {openFileChooser(uploadMsg, acceptType);}*** 然后自己实现selectImage()方法```private void selectImage() {//模仿IOS的弹出框List<map <String, String>> list = new ArrayList<>();HashMap ch1 = new HashMap<>();HashMap ch2 = new HashMap<>();HashMap ch3 = new HashMap<>();ch1.put("key", "从相册选择");ch2.put("key", "拍照上传");ch3.put("key", "取消"); list.add(ch1);list.add(ch2);list.add(ch3);ListAdapter ad = new SimpleAdapter(this, list, R.layout.my_simple_list_item_1, new String[]{"key"}, new int[]{android.R.id.text1});chosePicDialog = new AlertDialog.Builder(this).setAdapter(ad, new DialogInterface.OnClickListener() {@Overridepublic void onClick(DialogInterface dialogInterface, int i) {switch (i) {case 0:getImageFromAlbum();break;case 1:getImageFromCamera();break;case 2:mUploadMessage.onReceiveValue(null);//这里是坑，如果取消了 不调用这句mUploadMessage.onReceiveValue()的话 整个webview就都没有响应了mUploadMessage = null;//还有这里 上边已标出break;}}}).setCancelable(false).create();chosePicDialog.getWindow().setGravity(Gravity.BOTTOM);chosePicDialog.show();} ```然后分别实现 从图库选择和拍照上传的方法```/*** 调用相册/protected void getImageFromAlbum() {Intent intent = new Intent(Intent.ACTION_PICK);intent.setType("image/");//相片类型startActivityForResult(intent, REQUEST_CODE_PICK_IMAGE);} /*** 调用相机*/protected void getImageFromCamera() {//这里采用的是获取拍照原图的方法String state = Environment.getExternalStorageState();if (state.equals(Environment.MEDIA_MOUNTED)) {File f = FileUtil.getNewPicFilePath();Uri u = Uri.fromFile(f);Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);intent.putExtra(MediaStore.EXTRA_OUTPUT, u);intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 1);startActivityForResult(intent,REQUEST_CODE_CAPTURE_CAMEIA);} else {Toast.makeText(getApplicationContext(), "请确认已经插入SD卡", Toast.LENGTH_LONG).show();}} ```***FileUtil.class内容```public class FileUtil {private static String LastPicFilePath = null; public static File getNewPicFilePath() {String dirStr = Environment.getExternalStorageDirectory().getPath() + "/DCIM/Camera/";File dir = new File(dirStr);if (!dir.exists()) {dir.mkdirs();}SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHmmss");String nowTime = format.format(new Date());String localTempFileName = nowTime + ".jpg";File f = new File(dir, localTempFileName);setLastPicFilePath(f.getPath());Log.e("getLastPicFilePath",getLastPicFilePath());return f;}public static String getLastPicFilePath() {return LastPicFilePath;}public static void setLastPicFilePath(String lastPicFilePath) {LastPicFilePath = lastPicFilePath;} }```***再重写onActivityResult@Overrideprotected void onActivityResult(int requestCode, int resultCode, Intent data) {if (resultCode != RESULT_OK) {mUploadMessage.onReceiveValue(null);//这里防止拍照的时候取消了回来webview无响应的问题，这里是大坑mUploadMessage = null;//上边注释说了，这里是坑mWebView.requestFocus();return;}if (requestCode == REQUEST_CODE_PICK_IMAGE) {Uri uri = data.getData();//to do find the path of pic by urimUploadMessage.onReceiveValue(uri);} else if (requestCode == REQUEST_CODE_CAPTURE_CAMEIA) {Uri uri = Uri.parse(FileUtil.getLastPicFilePath());//从上边指定的地址生成urimUploadMessage.onReceiveValue(uri);}super.onActivityResult(requestCode, resultCode, data);}总结总体来说最坑的就是这个 mUploadMessage.onReceiveValue( );方法没看WebChromeClient源码 猜想是如果不回调这句的话webview会一直等着你操作，造成整个webview界面没有响应，这个问题让我纠结了一下午时间，总结出来，希望对其他人有帮助。