转自:http://blog.csdn.net/djcken/article/details/46379929#

使用openFileChooser存在的问题。当弹出选择图片/相机框之后,取消选择,就再也不能点击选择按钮了。这篇文章是为了记录这一点,为验证整个流程部署了后端,但是由于很久没接触后端,后端代码是网上的列子,所以后端代码和部署就不说了。单纯的说下Android端的解决方案。

更新:Android5.0+的方法。

自定义两个文件:

[java]  view plain  copy  
  1. /** 
  2.  * 自定义 
  3.  * 
  4.  * @Author KenChung 
  5.  */  
  6. public class ReWebViewClient extends WebViewClient {  
  7.   
  8.     @Override  
  9.     public void onPageStarted(WebView view, String url, Bitmap favicon) {  
  10.         super.onPageStarted(view, url, favicon);  
  11.     }  
  12.   
  13.     @Override  
  14.     public void onPageFinished(WebView view, String url) {  
  15.         super.onPageFinished(view, url);  
  16.     }  
  17. }  

[java]  view plain  copy  
  1. /** 
  2.  * ReWebChomeClient 
  3.  * 
  4.  * @Author KenChung 
  5.  */  
  6. public class ReWebChomeClient extends WebChromeClient {  
  7.   
  8.   
  9.     private OpenFileChooserCallBack mOpenFileChooserCallBack;  
  10.   
  11.   
  12.     public ReWebChomeClient(OpenFileChooserCallBack openFileChooserCallBack) {  
  13.         mOpenFileChooserCallBack = openFileChooserCallBack;  
  14.     }  
  15.   
  16.   
  17.     //For Android 3.0+  
  18.     public void openFileChooser(ValueCallback uploadMsg, String acceptType) {  
  19.         mOpenFileChooserCallBack.openFileChooserCallBack(uploadMsg, acceptType);  
  20.     }  
  21.   
  22.   
  23.     // For Android < 3.0  
  24.     public void openFileChooser(ValueCallback uploadMsg) {  
  25.         openFileChooser(uploadMsg, "");  
  26.     }  
  27.   
  28.   
  29.     // For Android  > 4.1.1  
  30.     public void openFileChooser(ValueCallback uploadMsg, String acceptType, String capture) {  
  31.         openFileChooser(uploadMsg, acceptType);  
  32.     }  
  33.   
  34.   
  35.     // For Android 5.0+  
  36.     @Override  
  37.     public boolean onShowFileChooser(WebView webView, ValueCallback filePathCallback, FileChooserParams   
  38.   
  39.   
  40. fileChooserParams) {  
  41.         mOpenFileChooserCallBack.showFileChooserCallBack(filePathCallback);  
  42.         return true;  
  43.     }  
  44.   
  45.   
  46.     public interface OpenFileChooserCallBack {  
  47.         void openFileChooserCallBack(ValueCallback uploadMsg, String acceptType);  
  48.   
  49.   
  50.         void showFileChooserCallBack(ValueCallback filePathCallback);  
  51.     }  
  52.   
  53. }  

选择图片弹框使用AlertDialog:

[java]  view plain  copy  
  1. public void showOptions() {  
  2.         AlertDialog.Builder alertDialog = new AlertDialog.Builder(this);  
  3.         alertDialog.setOnCancelListener(new ReOnCancelListener());  
  4.         alertDialog.setTitle(R.string.options);  
  5.         alertDialog.setItems(R.array.options, new DialogInterface.OnClickListener() {  
  6.                     @Override  
  7.                     public void onClick(DialogInterface dialog, int which) {  
  8.                         if (which == 0) {  
  9.                             mSourceIntent = ImageUtil.choosePicture();  
  10.                             startActivityForResult(mSourceIntent, REQUEST_CODE_PICK_IMAGE);  
  11.                         } else {  
  12.                             mSourceIntent = ImageUtil.takeBigPicture();  
  13.                             startActivityForResult(mSourceIntent, REQUEST_CODE_IMAGE_CAPTURE);  
  14.                         }  
  15.                     }  
  16.                 }  
  17.         );  
  18.         alertDialog.show();  
  19.     }  

关键代码:(这里的意思是取消弹框之后要告诉WebView不要再等待返回结果,设置为空就等于重置了状态)

[java]  view plain  copy  
  1. private class ReOnCancelListener implements DialogInterface.OnCancelListener {  
  2.   
  3.         @Override  
  4.         public void onCancel(DialogInterface dialogInterface) {  
  5.             if (mUploadMsg != null) {  
  6.                 mUploadMsg.onReceiveValue(null);  
  7.                 mUploadMsg = null;  
  8.             }  
  9.             if (mUploadMsg5Plus != null) {  
  10.            mUploadMsg5Plus.onReceiveValue(null);  
  11.            mUploadMsg5Plus = null;  
  12.         }  
  13.         }  
  14.     }  

完整MainActivity:

[java]  view plain  copy  
  1. /** 
  2.  * WebViewUpload 
  3.  * 
  4.  * @Author KenChung 
  5.  */  
  6. public class MyActivity extends Activity implements ReWebChomeClient.OpenFileChooserCallBack {  
  7.   
  8.     private static final String TAG = "MyActivity";  
  9.     private static final int REQUEST_CODE_PICK_IMAGE = 0;  
  10.     private static final int REQUEST_CODE_IMAGE_CAPTURE = 1;  
  11.     private WebView mWebView;  
  12.     private Intent mSourceIntent;  
  13.     private ValueCallback mUploadMsg;  
  14.     private ValueCallback mUploadMsg5Plus;  
  15.   
  16.   
  17.     @Override  
  18.     public void onCreate(Bundle savedInstanceState) {  
  19.         super.onCreate(savedInstanceState);  
  20.         setContentView(R.layout.main);  
  21.         mWebView = (WebView) findViewById(R.id.webview);  
  22.         mWebView.setWebChromeClient(new ReWebChomeClient(this));  
  23.         mWebView.setWebViewClient(new ReWebViewClient());  
  24.         fixDirPath();  
  25.         //这里加载自己部署的(也可加载本地资源)  
  26.         mWebView.loadUrl("file:///android_asset/input.html");  
  27.     }  
  28.   
  29.   
  30.     @Override  
  31.     public void onActivityResult(int requestCode, int resultCode, Intent data) {  
  32.         if (resultCode != Activity.RESULT_OK) {  
  33.             return;  
  34.         }  
  35.         switch (requestCode) {  
  36.             case REQUEST_CODE_IMAGE_CAPTURE:  
  37.             case REQUEST_CODE_PICK_IMAGE: {  
  38.                 try {  
  39.                     if (mUploadMsg == null && mUploadMsg5Plus == null) {  
  40.                         return;  
  41.                     }  
  42.                     String sourcePath = ImageUtil.retrievePath(this, mSourceIntent, data);  
  43.                     if (TextUtils.isEmpty(sourcePath) || !new File(sourcePath).exists()) {  
  44.                         Log.w(TAG, "sourcePath empty or not exists.");  
  45.                         break;  
  46.                     }  
  47.                     Uri uri = Uri.fromFile(new File(sourcePath));  
  48.                     if (mUploadMsg != null) {  
  49.                         mUploadMsg.onReceiveValue(uri);  
  50.                         mUploadMsg = null;  
  51.                     } else {  
  52.                         mUploadMsg5Plus.onReceiveValue(new Uri[]{uri});  
  53.                         mUploadMsg5Plus = null;  
  54.                     }  
  55.                 } catch (Exception e) {  
  56.                     e.printStackTrace();  
  57.                 }  
  58.                 break;  
  59.             }  
  60.         }  
  61.     }  
  62.   
  63.   
  64.     @Override  
  65.     public void openFileChooserCallBack(ValueCallback uploadMsg, String acceptType) {  
  66.         mUploadMsg = uploadMsg;  
  67.         showOptions();  
  68.     }  
  69.   
  70.   
  71.     @Override  
  72.     public void showFileChooserCallBack(ValueCallback filePathCallback) {  
  73.         mUploadMsg5Plus = filePathCallback;  
  74.         showOptions();  
  75.     }  
  76.   
  77.   
  78.     public void showOptions() {  
  79.         AlertDialog.Builder alertDialog = new AlertDialog.Builder(this);  
  80.         alertDialog.setOnCancelListener(new ReOnCancelListener());  
  81.         alertDialog.setTitle(R.string.options);  
  82.         alertDialog.setItems(R.array.options, new DialogInterface.OnClickListener() {  
  83.             @Override  
  84.             public void onClick(DialogInterface dialog, int which) {  
  85.                 if (which == 0) {  
  86.                     mSourceIntent = ImageUtil.choosePicture();  
  87.                     startActivityForResult(mSourceIntent, REQUEST_CODE_PICK_IMAGE);  
  88.                 } else {  
  89.                     mSourceIntent = ImageUtil.takeBigPicture(MyActivity.this);  
  90.                     startActivityForResult(mSourceIntent, REQUEST_CODE_IMAGE_CAPTURE);  
  91.                 }  
  92.             }  
  93.         });  
  94.         alertDialog.show();  
  95.     }  
  96.   
  97.   
  98.     private void fixDirPath() {  
  99.         String path = ImageUtil.getDirPath();  
  100.         File file = new File(path);  
  101.         if (!file.exists()) {  
  102.             file.mkdirs();  
  103.         }  
  104.     }  
  105.   
  106.   
  107.     private class ReOnCancelListener implements DialogInterface.OnCancelListener {  
  108.   
  109.   
  110.         @Override  
  111.         public void onCancel(DialogInterface dialogInterface) {  
  112.             if (mUploadMsg != null) {  
  113.                 mUploadMsg.onReceiveValue(null);  
  114.                 mUploadMsg = null;  
  115.             }  
  116.             if (mUploadMsg5Plus != null) {  
  117.                 mUploadMsg5Plus.onReceiveValue(null);  
  118.                 mUploadMsg5Plus = null;  
  119.             }  
  120.         }  
  121.     }  
  122. }  


有些哥们反馈没有附上html无法测试,放上html到本地即可:input.html

[html]  view plain  copy  
  1. >  
  2. <html>  
  3. <head>  
  4.     <meta name="viewport" content="user-scalable=no">  
  5.     <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">  
  6. head>  
  7. <body>  
  8. <input id="input" type="file"/>  
  9. body>  
  10. html>  

源码没有附上本地html,需自行创建。源码下载地址: CSDN下载

更多相关文章

  1. 添加android 4.0 开机音乐
  2. android studio 碰到问题
  3. Android(安卓)开关机动画显示源码分析
  4. Android单元测试思路
  5. android 、java优质资料合集
  6. Activity之生命周期
  7. 在手机上开发程序之AIDE(Android集成开发环境)介绍
  8. 使用android中自己实现可用xml配置的动画类
  9. Android(安卓)Systrace使用介绍

随机推荐

  1. Java的Char的简单工具类CharUtil2.0
  2. 使用JSP的fmt标签实现国际化支持
  3. 什么案例需要Java中的同步方法访问?
  4. 来自.Net的Zipped Streams问题并从Java读
  5. Java记录 -88- 利用反射机制调用对象的私
  6. java客户端调用 https 的webservice
  7. Java基础小常识(4)
  8. 「小程序JAVA实战」小程序头像图片上传(中
  9. 一个简单的java网络爬虫(spider)
  10. 如何修改代码,使其仅打印单元格E和F?