解决这个问题花了很长时间搜索了解,网上大部分使用openFileChooser但都没解决一个存在的问题。就是当弹出选择图片/相机框之后,取消选择,就再也不能点击选择按钮了。这篇文章是为了记录这一点,为验证整个流程部署了后端,但是由于很久没接触后端,后端代码是网上的列子,所以后端代码和部署就不说了。单纯的说下Android端的解决方案。
自定义两个文件:
/** * 自定义 * * @Author KenChung */ public class ReWebViewClient extends WebViewClient { @Override public void onPageStarted(WebView view, String url, Bitmap favicon) { super.onPageStarted(view, url, favicon); } @Override public void onPageFinished(WebView view, String url) { super.onPageFinished(view, url); } }
/** * ReWebChomeClient * * @Author KenChung */ public class ReWebChomeClient extends WebChromeClient { private OpenFileChooserCallBack mOpenFileChooserCallBack; public ReWebChomeClient(OpenFileChooserCallBack openFileChooserCallBack) { mOpenFileChooserCallBack = openFileChooserCallBack; } //For Android 3.0+ public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType) { mOpenFileChooserCallBack.openFileChooserCallBack(uploadMsg, acceptType); } // For Android < 3.0 public void openFileChooser(ValueCallback<Uri> uploadMsg) { openFileChooser(uploadMsg, ""); } // For Android > 4.1.1 public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType, String capture) { openFileChooser(uploadMsg, acceptType); } public interface OpenFileChooserCallBack { void openFileChooserCallBack(ValueCallback<Uri> uploadMsg, String acceptType); } }
public void showOptions() { AlertDialog.Builder alertDialog = new AlertDialog.Builder(this); alertDialog.setOnCancelListener(new ReOnCancelListener()); alertDialog.setTitle(R.string.options); alertDialog.setItems(R.array.options, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { if (which == 0) { mSourceIntent = ImageUtil.choosePicture(); startActivityForResult(mSourceIntent, REQUEST_CODE_PICK_IMAGE); } else { mSourceIntent = ImageUtil.takeBigPicture(); startActivityForResult(mSourceIntent, REQUEST_CODE_IMAGE_CAPTURE); } } } ); alertDialog.show(); }
private class ReOnCancelListener implements DialogInterface.OnCancelListener { @Override public void onCancel(DialogInterface dialogInterface) { if (mUploadMsg != null) { mUploadMsg.onReceiveValue(null); mUploadMsg = null; } } }
/** * WebViewUpload * * @Author KenChung */ public class MyActivity extends Activity implements ReWebChomeClient.OpenFileChooserCallBack { private static final String TAG = "MyActivity"; private static final int REQUEST_CODE_PICK_IMAGE = 0; private static final int REQUEST_CODE_IMAGE_CAPTURE = 1; private WebView mWebView; private Intent mSourceIntent; private ValueCallback<Uri> mUploadMsg; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); mWebView = (WebView) findViewById(R.id.webview); mWebView.setWebChromeClient(new ReWebChomeClient(this)); mWebView.setWebViewClient(new ReWebViewClient()); fixDirPath(); //这里加载自己部署的(也可加载本地资源) mWebView.loadUrl("file:///android_asset/input.html"); } @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { if (resultCode != Activity.RESULT_OK) { return; } switch (requestCode) { case REQUEST_CODE_IMAGE_CAPTURE: case REQUEST_CODE_PICK_IMAGE: { try { if (mUploadMsg == null) { return; } String sourcePath = ImageUtil.retrievePath(this, mSourceIntent, data); if (TextUtils.isEmpty(sourcePath) || !new File(sourcePath).exists()) { Log.w(TAG, "sourcePath empty or not exists."); break; } Uri uri = Uri.fromFile(new File(sourcePath)); mUploadMsg.onReceiveValue(uri); } catch (Exception e) { e.printStackTrace(); } break; } } } @Override public void openFileChooserCallBack(ValueCallback<Uri> uploadMsg, String acceptType) { mUploadMsg = uploadMsg; showOptions(); } public void showOptions() { AlertDialog.Builder alertDialog = new AlertDialog.Builder(this); alertDialog.setOnCancelListener(new ReOnCancelListener()); alertDialog.setTitle(R.string.options); alertDialog.setItems(R.array.options, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { if (which == 0) { mSourceIntent = ImageUtil.choosePicture(); startActivityForResult(mSourceIntent, REQUEST_CODE_PICK_IMAGE); } else { mSourceIntent = ImageUtil.takeBigPicture(); startActivityForResult(mSourceIntent, REQUEST_CODE_IMAGE_CAPTURE); } } } ); alertDialog.show(); } private void fixDirPath() { String path = ImageUtil.getDirPath(); File file = new File(path); if (!file.exists()) { file.mkdirs(); } } private class ReOnCancelListener implements DialogInterface.OnCancelListener { @Override public void onCancel(DialogInterface dialogInterface) { if (mUploadMsg != null) { mUploadMsg.onReceiveValue(null); mUploadMsg = null; } } } }
有些哥们反馈没有附上html无法测试,放上html到本地即可:input.html
<!DOCTYPE html> <html> <head> <meta name="viewport" content="user-scalable=no"> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> </head> <body> <input id="input" type="file"/> </body> </html>