快捷导航

×
  1. 首页
  2. 论坛
  3. WebView里调用相机/文件选取照片并上传
混合式开发收藏本版 +发表新主题

WebView里调用相机/文件选取照片并上传

发布者: 大米 发布时间: 2018-12-16 11:56[复制链接] 0 49

大米 发表于 2018-12-16 11:56:38 | 显示全部楼层 |阅读模式
拦截到H5 的 input元素
  1. webView.setWebChromeClient(new WebChromeClient() {
  2.             @Override
  3.             public void onProgressChanged(WebView view, int newProgress) {
  4.                 if (newProgress == 100) {
  5.                     progressBar.setVisibility(View.GONE);//加载完网页进度条消失
  6.                 } else {
  7.                     progressBar.setProgress(newProgress);//设置进度值
  8.                     progressBar.setVisibility(View.VISIBLE);//开始加载网页时显示进度条
  9.                 }
  10.             }

  11.             /**
  12.              * 8(Android 2.2) <= API <= 10(Android 2.3)回调此方法
  13.              */
  14.             private void openFileChooser(android.webkit.ValueCallback<Uri> uploadMsg) {
  15.                 Log.e("hl05", "运行方法 openFileChooser-1");
  16.                 // (2)该方法回调时说明版本API < 21,此时将结果赋值给 mUploadCallbackBelow,使之 != null
  17.                 mUploadCallbackBelow = uploadMsg;
  18.                 takePhoto();
  19.             }

  20.             /**
  21.              * 11(Android 3.0) <= API <= 15(Android 4.0.3)回调此方法
  22.              */
  23.             public void openFileChooser(android.webkit.ValueCallback<Uri> uploadMsg, String acceptType) {
  24.                 Log.e("hl05", "运行方法 openFileChooser-2 (acceptType: " + acceptType + ")");
  25.                 // 这里我们就不区分input的参数了,直接用拍照
  26.                 openFileChooser(uploadMsg);
  27.             }

  28.             /**
  29.              * 16(Android 4.1.2) <= API <= 20(Android 4.4W.2)回调此方法
  30.              */
  31.             public void openFileChooser(android.webkit.ValueCallback<Uri> uploadMsg, String acceptType, String capture) {
  32.                 Log.e("hl05", "运行方法 openFileChooser-3 (acceptType: " + acceptType + "; capture: " + capture + ")");
  33.                 // 这里我们就不区分input的参数了,直接用拍照
  34.                 openFileChooser(uploadMsg);
  35.             }

  36.             /**
  37.              * API >= 21(Android 5.0.1)回调此方法
  38.              */
  39.             @Override
  40.             public boolean onShowFileChooser(WebView webView, ValueCallback<Uri[]> valueCallback, FileChooserParams fileChooserParams) {
  41.                 Log.e("hl05", "运行方法 onShowFileChooser");
  42.                 // (1)该方法回调时说明版本API >= 21,此时将结果赋值给 mUploadCallbackAboveL,使之 != null
  43.                 mUploadCallbackAboveL = valueCallback;
  44.                 takePhoto();
  45.                 return true;
  46.             }
  47.         });
复制代码

到这里的java代码就是来拦截input时间的,里面做了很多api版本的判断,不同版本的api调用不同的方法,下面再贴出来其他一些方法:

调起相机/选择文件的方法:takePhoto();

  1. /**
  2.      * 调用相机
  3.      */
  4.     private void takePhoto() {
  5.         // 指定拍照存储位置的方式调起相机
  6.         String filePath = Environment.getExternalStorageDirectory() + File.separator
  7.                 + Environment.DIRECTORY_PICTURES + File.separator;
  8.         String fileName = "IMG_" + DateFormat.format("yyyyMMdd_hhmmss", Calendar.getInstance(Locale.CHINA)) + ".jpg";
  9.         imageUri = Uri.fromFile(new File(filePath + fileName));

  10. //        Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
  11. //        intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
  12. //        startActivityForResult(intent, REQUEST_CODE);


  13.         // 选择图片(不包括相机拍照),则不用成功后发刷新图库的广播
  14. //        Intent i = new Intent(Intent.ACTION_GET_CONTENT);
  15. //        i.addCategory(Intent.CATEGORY_OPENABLE);
  16. //        i.setType("image/*");
  17. //        startActivityForResult(Intent.createChooser(i, "Image Chooser"), REQUEST_CODE);

  18.         Intent captureIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
  19.         captureIntent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);

  20.         Intent Photo = new Intent(Intent.ACTION_PICK,
  21.                 android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);

  22.         Intent chooserIntent = Intent.createChooser(Photo, "Image Chooser");
  23.         chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, new Parcelable[]{captureIntent});

  24.         startActivityForResult(chooserIntent, REQUEST_CODE);
  25.     }
复制代码

onActivityResult回调:

  1. @Override
  2.     protected void onActivityResult(int requestCode, int resultCode, Intent data) {
  3.         super.onActivityResult(requestCode, resultCode, data);
  4.         if (requestCode == REQUEST_CODE) {
  5.             // 经过上边(1)、(2)两个赋值操作,此处即可根据其值是否为空来决定采用哪种处理方法
  6.             if (mUploadCallbackBelow != null) {
  7.                 chooseBelow(resultCode, data);
  8.             } else if (mUploadCallbackAboveL != null) {
  9.                 chooseAbove(resultCode, data);
  10.             } else {
  11.                 Toast.makeText(this, "发生错误", Toast.LENGTH_SHORT).show();
  12.             }
  13.         }
  14.     }
复制代码
其他一些方法:
  1. /**
  2.      * Android API < 21(Android 5.0)版本的回调处理
  3.      * @param resultCode 选取文件或拍照的返回码
  4.      * @param data 选取文件或拍照的返回结果
  5.      */
  6.     private void chooseBelow(int resultCode, Intent data) {
  7.         Log.e("hl05", "返回调用方法--chooseBelow");

  8.         if (RESULT_OK == resultCode) {
  9.             updatePhotos();

  10.             if (data != null) {
  11.                 // 这里是针对文件路径处理
  12.                 Uri uri = data.getData();
  13.                 if (uri != null) {
  14.                     Log.e("hl05", "系统返回URI:" + uri.toString());
  15.                     mUploadCallbackBelow.onReceiveValue(uri);
  16.                 } else {
  17.                     mUploadCallbackBelow.onReceiveValue(null);
  18.                 }
  19.             } else {
  20.                 // 以指定图像存储路径的方式调起相机,成功后返回data为空
  21.                 Log.e("hl05", "自定义结果:" + imageUri.toString());
  22.                 mUploadCallbackBelow.onReceiveValue(imageUri);
  23.             }
  24.         } else {
  25.             mUploadCallbackBelow.onReceiveValue(null);
  26.         }
  27.         mUploadCallbackBelow = null;
  28.     }

  29.     /**
  30.      * Android API >= 21(Android 5.0) 版本的回调处理
  31.      * @param resultCode 选取文件或拍照的返回码
  32.      * @param data 选取文件或拍照的返回结果
  33.      */
  34.     private void chooseAbove(int resultCode, Intent data) {
  35.         Log.e("hl05", "返回调用方法--chooseAbove");

  36.         if (RESULT_OK == resultCode) {
  37.             updatePhotos();

  38.             if (data != null) {
  39.                 // 这里是针对从文件中选图片的处理
  40.                 Uri[] results;
  41.                 Uri uriData = data.getData();
  42.                 if (uriData != null) {
  43.                     results = new Uri[]{uriData};
  44.                     for (Uri uri : results) {
  45.                         Log.e("hl05", "系统返回URI:" + uri.toString());
  46.                     }
  47.                     mUploadCallbackAboveL.onReceiveValue(results);
  48.                 } else {
  49.                     mUploadCallbackAboveL.onReceiveValue(null);
  50.                 }
  51.             } else {
  52.                 Log.e("hl05", "自定义结果:" + imageUri.toString());
  53.                 mUploadCallbackAboveL.onReceiveValue(new Uri[]{imageUri});
  54.             }
  55.         } else {
  56.             mUploadCallbackAboveL.onReceiveValue(null);
  57.         }
  58.         mUploadCallbackAboveL = null;
  59.     }

  60.     private void updatePhotos() {
  61.         // 该广播即使多发(即选取照片成功时也发送)也没有关系,只是唤醒系统刷新媒体文件
  62.         Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
  63.         intent.setData(imageUri);
  64.         sendBroadcast(intent);
  65.     }
复制代码
相关的全局变量:

  1.     private android.webkit.ValueCallback<Uri[]> mUploadCallbackAboveL;
  2.     private android.webkit.ValueCallback<Uri> mUploadCallbackBelow;
  3.     private Uri imageUri;
  4.     private int REQUEST_CODE = 1234;
复制代码
最后说下,别忘了加一些相应的网络权限什么的。否则无法运行的。
扫描二维码,手机查看
声明:本文来源于互联网,观点仅代表作者本人,不代表hl05.,真实性请妥善甄别。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

×
HL05微信
在微信上关注我们