项目需求讨论 - WebView下拍照及图片选择功能

发表于:2019-3-20 10:55

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:青蛙要fly    来源:掘金

  前言:
    现在很多app里面,都会有这么一个需求,就是上传图片的按钮,当然按了这个按钮之后,就会出现二种选择: 1. 直接拍照,2. 相册选择现有图片。
  因为现在的app这块功能会有二个大的情况:
  全部原生的 app 来实现。
  HyBrid 的 app 来实现。
  本文先讨论HyBrid的app的实现情况,下次再讨论原生,不过其实大部分实现都是相似的。
  其实这种在WebView配合下实现这类功能的文章很多很多,但是大多数都是上传一大段代码,然后让大家自己看,千篇一律,所以本文主要是写的完整的思路。
  正文:
  我们知道用户会在网页上点击了某个按钮,然后调用起安卓方面的相关操作。然后实现完整的功能。
  1. 网页端:
  其实网页端很简单,只需要实现一个简单的<input>标签即可。
  总体思路是一个<input>标签和一个<img>标签重叠在一起(<input>在上,<img>在下,类似可以理解<img>作为背景),当选完照片后,最后把图片赋值给<img>标签。
  但是在给<img>赋值的时候我遇到过不同的情况:
  当在Android这边拍照或者进入图库选完照片后,把图片信息给了网页端后,<input>标签的onchange监听到了图片选择好了,网页端直接把图片上传到服务器并传回来一个地址,显示时把地址拼接成可以找到路径的地址放在<img>标签中就可以了。
  配合FileReader,FileReader是作为文件API的重要成员用于读取文件。可以参考: h5 实现调用系统拍照或者选择照片并预览
  2. Android端:
  2.1 WebChromeClient
  因为Android端访问网页大部分使用的是WebView,所以我们这里还是用WebView来说明。
  既然用户在网页上点击了<input>,我们肯定需要WebView能监听到,好比原生的Button点击我们要监听也要写一个OnclickListener来实现监听。我们这里使用的是WebChromeClient。
   public class ImgWebChromeClient extends WebChromeClient {
  //.......
  //.......
  public ImgWebChromeClient(Activity activity) {
  this.activity = activity;
  }
  }
  我们实现我们的类,继承WebChromeClient。然后我们就可以把这个我们自己定义的WebChromeClient设置给我们的WebView。
 webView.setWebChromeClient(new ImgWebChromeClient(this));
  

我们可以看到我们在WebChromeClient在监听<input>点击事件的时候,还要根据不同的版本来区分,主要是以Android 5.0版本来进行大的划分。
  Android 5.0及以上版本:
  Android 5.0以下版本:
  都是openFileChooser方法,不同版本的里面参数不同。
  所以我们可以看到主要是openFileChooser和onShowFileChooser方法。
   // For Android < 3.0
  public void openFileChooser(ValueCallback<Uri> valueCallback) {
  ***
  }
  // For Android  >= 3.0
  public void openFileChooser(ValueCallback valueCallback, String acceptType) {
  ***
  }
  //For Android  >= 4.1
  public void openFileChooser(ValueCallback<Uri> valueCallback,
  String acceptType, String capture) {
  ***
  }
  // For Android >= 5.0
  @Override
  public boolean onShowFileChooser(WebView webView,
  ValueCallback<Uri[]> filePathCallback,
  WebChromeClient.FileChooserParams fileChooserParams) {
  ***
  return true;
  }
  不管是什么版本,我们看到这几个方法的参数里面都有ValueCallback参数。
  
   /**
  * A callback interface used to provide values asynchronously.
  */
  public interface ValueCallback<T> {
  /**
  * Invoked when the value is available.
  * @param value The value.
  */
  public void onReceiveValue(T value);
  };
   所以我们知道了,我们最后是调用openFileChooser和onShowFileChooser方法里面的ValueCallback参数,调用它的onReceiveValue方法把我们的选择的图片的Uri传入,网页端那边就会收到信息了,就知道用户到底选择了什么图片。
  所以我们最终目标就是获取选择的图片的Uri,然后给ValueCallback.onReceiveValue方法,这就是我们整个文章的最主要的流程。
  2.2 获取相关图片的Uri
  上面我们提到了,我们最终目标是获取用户选取的图片Uri,然后传给ValueCallback就可以。
  所以我们这里就要讲二大块:
  用户怎么跳到自己想要的界面(相机 or 图库)
  用户在自己想要的界面选择好了图片后 (拍好了照片 or 在图库选择好了图片),如何获取相关图片的Uri。
  根据这二点,我们一步步来分析。
  2.2.1 相机 or 图库
  我们肯定想到是用户点击了某个按钮后,我们需要跳出一个弹框,然后上面有拍照和图库按钮:比如我使用系统自带的选择框(不同手机显示的弹框不同):
  所以我们这里知道了这个又要细分任务:
  获取相关权限
  如何点击按钮后可以跳到相应界面(拍照 or 图库)。
  如何创建弹框,把上面的按钮显示在上面
  2.2.1.1 获取相关权限
  emmm......这块我觉得应该不需要花更多的时间来说明了吧,主要就是:
  检查权限 (checkSelfPermission)
  请求权限(requestPermissions)
  回调事件处理(onRequestPermissionsResult)
  而我们要申请的权限无非就是 Camera的权限,还有读写外部存储的权限。
  2.2.1.2 如何点击按钮后可以跳到相应界面(拍照 or 图库):
  我们先来看拍照:
  2.2.1.2.1 设置打开相机Intent的Action
  我们知道打开某个界面,就是startActivity(Intent);平常比如跳到拨号界面等。只要对Intent设定相应的Action即可。
  具体我们可以看谷歌的Android官方教程网页即可:
  我们可以看到有这些:

        上文内容不用于商业目的,如涉及知识产权问题,请权利人联系博为峰小编(021-64471599-8017),我们将立即处理。
  
21/212>
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号