美文网首页
WebView支持拍照、录像、选择文件

WebView支持拍照、录像、选择文件

作者: 写不完的bug | 来源:发表于2018-08-14 10:44 被阅读0次

WebView支持拍照、录像、选择文件

最近因为业务需要webview支持用户录像,所以研究了一下

最重要的就是重写WebChromeClient中的几个方法

webView.setWebChromeClient(new WebChromeClient(getActivity()) {
      @Override public void onReceivedTitle(WebView view, String title) {
        if (TextUtils.isEmpty(getIntent().getStringExtra(WEB_TITLE))) {
          if (!TextUtils.isEmpty(view.getTitle())) {
            setTitle(view.getTitle());
          }
        }
      }

      //这个重新的方法是为了让js支持alert。不需要的可以去掉
      @Override
      public boolean onJsAlert(WebView view, String url, String message, JsResult result) {
        return super.onJsAlert(view, url, message, result);
      }

      // For Android  > 4.1.1
      public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType, String capture) {
        openFileChooser(uploadMsg, acceptType);
      }

      // For Android 3.0+
      public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType) {
        if (mUploadMessage != null) return;
        mUploadMessage = uploadMsg;
        if (createDefaultOpenableIntent() != null) {
          startActivityForResult(createDefaultOpenableIntent(), FILE_REQUEST);
        }
      }

      // For Android < 3.0
      public void openFileChooser(ValueCallback<Uri> uploadMsg) {
        openFileChooser(uploadMsg, "");
      }

      @Override
      public boolean onShowFileChooser(WebView webView, ValueCallback<Uri[]> filePathCallback,
          FileChooserParams fileChooserParams) {
        super.onShowFileChooser(webView, filePathCallback, fileChooserParams);
        if (mFilePathCallback != null) return false;
        mFilePathCallback = filePathCallback;
        if (createDefaultOpenableIntent() != null) {
          startActivityForResult(createCameraIntent(), FILE_REQUEST);
        }
        return true;
      }

      private Intent createDefaultOpenableIntent() {
        // Create and return a chooser with the default OPENABLE
        // actions including the camera, camcorder and sound
        // recorder where available.
        Intent i = new Intent(Intent.ACTION_GET_CONTENT);
        i.addCategory(Intent.CATEGORY_OPENABLE);
        i.setType("*/*");

        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, "File Chooser");
        return chooser;
      }

      private Intent createCameraIntent() {
        Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        mPictureUri = PickFileUtil.getCameraUri(getActivity());
        if (mPictureUri == null) {
          ToastUtil.showToast("请检查SD卡");
          return null;
        }
        intent.putExtra(MediaStore.EXTRA_OUTPUT, mPictureUri);
        intent.putExtra("return-data", true);
        intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());

        getActivity().grantUriPermission(getActivity().getPackageName(), mPictureUri,
            Intent.FLAG_GRANT_READ_URI_PERMISSION);
        intent.addFlags(
            Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
        return intent;
      }

      private Intent createCamcorderIntent() {
        return new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
      }

      private Intent createSoundRecorderIntent() {
        return new Intent(MediaStore.Audio.Media.RECORD_SOUND_ACTION);
      }
    });

上面就是需要重写的方法

接下来就是在onActivityResult方法中处理回调
@Override public void activityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == FILE_REQUEST) {
      Uri uri = (data != null && data.getData() != null) ? data.getData() : mPictureUri;
      mPictureUri = null;
      if (mFilePathCallback != null) {
        mFilePathCallback.onReceiveValue(uri == null ? null : new Uri[] { uri });
        mFilePathCallback = null;
      }
      if (mUploadMessage != null) {
        mUploadMessage.onReceiveValue(uri);
        mUploadMessage = null;
      }
    }
  }

其中需要定义这几个成员变量

private ValueCallback<Uri[]> mFilePathCallback;
private ValueCallback<Uri> mUploadMessage;
private Uri mPictureUri;

特别需要注意的

mFilePathCallback.onReceiveValue(null);
mUploadMessage.onReceiveValue(null);

这两个方法特别重要,只有执行了之后,才能继续点击

  • 如果是拍照的话,因为上面制定了返回的uri,所以onActivityResult中data会为null,需要从指定的uri中获取图片
mFilePathCallback.onReceiveValue(new Uri[] { mPictureUri });
mUploadMessage.onReceiveValue(mPictureUri);
下面是PickFileUtil内容
public class PickFileUtil {

  private static String getCacheDir(Context context) {
    if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
      File baseFile = new File(Environment.getExternalStorageDirectory(), context.getPackageName());
      if (baseFile.exists() || baseFile.mkdirs()) {
        return baseFile.getAbsolutePath();
      } else {
        return context.getCacheDir().getAbsolutePath();
      }
    } else {
      return context.getCacheDir().getAbsolutePath();
    }
  }

  public static Uri getCameraUri(Context context) {
    File pickDir = new File(getCacheDir(context), "pickDir");
    File mediaFile;
    if (pickDir.exists() || pickDir.mkdirs()) {
      mediaFile = new File(pickDir.getPath(), "IMG_" + System.currentTimeMillis() + ".jpg");
    } else {
      mediaFile = new File(getCacheDir(context), "IMG_" + System.currentTimeMillis() + ".jpg");
    }
    if (!mediaFile.exists()) {
      try {
        mediaFile.createNewFile();
      } catch (IOException e) {
        e.printStackTrace();
      }
    }
    if (Build.VERSION.SDK_INT >= 24) {
      return FileProvider.getUriForFile(context, ImagePickUtil.getAuthorities(context), mediaFile);
    } else {
      return Uri.fromFile(mediaFile);
    }
  }

  public static String getTempDir(Context context) {
    File pickDir = new File(getCacheDir(context), ".tempDir");
    if (pickDir.exists() || pickDir.mkdirs()) {
      return pickDir.getPath();
    } else {
      return getCacheDir(context);
    }
  }

  public static Uri getGalleyTempUri(Context context) {
    File mediaFile = new File(getTempDir(context), "IMG_" + System.currentTimeMillis() + ".jpg");
    return Uri.fromFile(mediaFile);
  }
}

相关文章

网友评论

      本文标题:WebView支持拍照、录像、选择文件

      本文链接:https://www.haomeiwen.com/subject/bypmbftx.html