基于uni-app框架的小程序调用摄像头遇到的兼容性问题


背景:最近做的一个需求涉及到调用摄像头拍照,但是不能打开相册,原本以为按照文档使用uni.chooseImage这个方法,参数设置为{ sourceType: ['camera'] }即可,但是这种方法在安卓手机上有兼容问题,会弹出拍照、相册两种方式供选择。

下面是我的兼容方案以供参考:

1. html标签的写法

<view>
  <!-- 苹果手机 -->
  <view v-if="isIphone" class="picture__item add" @tap="chooseImage">
    <view class="iconfont iconbtn_common_addto" />
  </view>
  <!-- 安卓手机 -->
  <view v-else class="picture__item add">
    <view class="iconfont iconbtn_common_addto" />
    <view ref="input" class="input" />
  </view>
</view>

2. 如果是苹果手机,直接调用uni.chooseImage即可

methods: {
    // 苹果手机
    chooseImage (e) {
        uni.chooseImage({
          sizeType: ['original', 'compressed'], // 可以指定是原图还是压缩图,默认二者都有
          sourceType: ['camera'], // 可以指定来源是相册还是相机,默认二者都有
        }).then(res => {
          const [, data] = res
          if (!data) return
          uni.showLoading({
            title: '上传中...',
            mask: true,
          })
          if ((data.tempFilePaths.length + this.pictureList.length) <= 3) {
            // 对应业务操作
            ...
            uni.hideLoading()
          } else {
            uni.showToast({
              title: '最多只能上传3张图片',
              icon: 'none',
            })
          }
        })
    },
}

3. 如果是安卓手机,需要创建input标签


mounted () {
    // 安卓手机的时候,在mounted钩子里面创建一个input标签插入指定位置。
    if (!this.isIphone) {
      let that = this
      let input = document.createElement('input')
      input.type = 'file'
      input.accept= 'image/*'
      input.id= 'file'
      input.capture = 'camera' // 调起摄像头
      input.style = 'width:100%;height:100%;opacity: 0;'
      input.addEventListener('change', function (event) {
        const data = event.target.files
        if (!data) return
        uni.showLoading({
          title: '上传中...',
          mask: true,
        })
        if ((data.length + that.pictureList.length) <= 3) {
          const file = data[0]
          const rs = URL.createObjectURL(file) // 这个方法很有用,下面会介绍
          // 对应业务操作
          ...
          uni.hideLoading()
        } else {
          uni.hideLoading()
          setTimeout(() => {
            uni.showToast({
              title: '最多只能上传3张图片',
              icon: 'none',
              duration: 2000,
            })
          }, 0)
        }
      })
      if (this.$refs.input) this.$refs.input.$el.appendChild(input)
    }
}

其中URL.createObjectURL(file) 静态方法会创建一个DOMString,其中包含一个表示参数中给出的对象的 URL。

这个 URL的生命周期和创建它的窗口中的document 绑定。

这个新的URL 对象表示指定的 File 对象或 Blob 对象。用法用下:

objectURL = URL.createObjectURL(object)

其中,object 参数指 用于创建URLFile 对象、Blob对象或者 MediaSource对象。

对于我们的input[type=file] 而言, input.files[0]可以获取到当前选中文件的 File 对象。示例代码如下:

  <input id="inputFile" type="file" accept="image/*">
  <img src="" id="previewImage" alt="图片预览">
  <script>
    const $ = document.getElementById.bind(document);
    const $inputFile = $('inputFile');
    const $previewImage = $('previewImage');
    $inputFile.addEventListener('change', function() {
      const file = this.files[0];
      $previewImage.src = file ? URL.createObjectURL(file) : '';
    }, this);
  </script>

具体用法可以参考 MDN上的 URL.createObjectURL()

总结:以上就是在uni-app小程序中调用摄像头遇到兼容性问题的解决方案,欢迎指正。

参考:

  1. 前端图片上传那些事儿
  2. uni-app 选择和上传非图像、视频文件


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM