基於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