olefirenko / vue-barcode-reader

A Vue.js set of components to scan barcodes and QR codes.
214 stars 75 forks source link

vue-barcode-reader doesn't work on mobile devices #14

Open AuliaAmirullah15 opened 3 years ago

AuliaAmirullah15 commented 3 years ago

I've been working on the barcode-reader plugin for my app over the last few days. It works perfectly well on browsers. However, it doesn't appear on the mobile apps (ios and android) after building them using Cordova.

IMG-20210630-WA0001

It appears on both computer and mobile browsers: https://www.awesomescreenshot.com/image/10049949?key=7a974e51dd0c86404c0bc837de82430d

Here is the chunk of my code related to the barcode-scanner plugin in case you need it:

<template>
  <q-card>
    <q-card-section>
      <p class="decode-result">
        Last result: <b>{{ text || "Nothing" }}</b>
      </p>
      <div class="hello">
        <StreamBarcodeReader
          @decode="(a, b, c) => onDecode(a, b, c)"
          @loaded="() => onLoaded()"
          style="width: 300px; height: 230px"
        ></StreamBarcodeReader>
      </div>
    </q-card-section>
</q-card>
</template>

<script>
import { StreamBarcodeReader } from "vue-barcode-reader";

export default {
  name: "ScanBarcode",
  data() {
    return {
      text: "",
    };
  },
  methods: {
    scanBarcode() {
      console.log("scanning...");
    },
    onDecode(a, b, c) {
      console.log(a, b, c);
      this.text = a;
      if (this.id) clearTimeout(this.id);
      this.id = setTimeout(() => {
        if (this.text === a) {
          this.text = "";
        }
      }, 5000);
    },
    onLoaded() {
      console.log("load");
    },
  },
  components: {
    StreamBarcodeReader,
  },
};
</script>

<style lang="scss" scoped>
@media (min-width: 420px) {
  .barcode {
    margin-left: 10px;
  }
}
</style>

Is there anyone who knows why it is happening and how I should fix it? Thank you in advance. 🙏

AuliaAmirullah15 commented 3 years ago

I eventually solved my problem but it doesn't necessarily solve the issue of why the plugin doesn't work on both android and ios devices. I thought the limitations would be pretty similar with the library ZXING in which the vue-barcode-reader plugin implements it to build the plugin. For further details, you can see the limitations on limitations section in this URL https://github.com/zxing-js/library

Solution: I used another plugin to support "barcode-reader feature" on my company's app. It is called "cordova-plugin-qr-barcode-scanner". I also added the code for detecting platforms (either browsers or mobile devices). Here is how I did it:

  1. Enter src-cordova folder (cd src-cordova), then run the installation command (cordova plugin add cordova-plugin-qr-barcode-scanner). It will install the plugin for mobile devices.

  2. Add your mobile barcode reader method inside of methods. Here is the method:

    scanImage() {
      cordova.plugins.barcodeScanner.scan(
        (result) => {
          this.text = result.text; // fill the variable text with the text of the barcode
        },
        (error) => {
          alert("Scanning failed: " + error);
        },
        {
          preferFrontCamera: true, // iOS and Android
          showFlipCameraButton: true, // iOS and Android
          showTorchButton: true, // iOS and Android
          torchOn: true, // Android, launch with the torch switched on (if available)
          saveHistory: true, // Android, save scan history (default false)
          prompt: "Place a barcode inside the scan area", // Android
          resultDisplayDuration: 500, // Android, display scanned text for X ms. 0 suppresses it entirely, default 1500
          //formats : "QR_CODE,PDF_417", // default: all but PDF_417 and RSS_EXPANDED
          orientation: "landscape", // Android only (portrait|landscape), default unset so it rotates with the device
          disableAnimations: true, // iOS
          disableSuccessBeep: true, // iOS and Android
        }
      );
  3. Replace all of the contents in the template with this code (it will detect which button and plugin will be run depending on the platform the user is using by using quasar platform detection feature):

<template>
  <q-card>
 <q-card-section class="row">
      <q-btn
        color="primary"
        icon="search"
        label="Search"
        @click="searchItems()"
      />
      <q-btn
        v-if="$q.platform.is.desktop"
        color="secondary"
        icon="qr_code_scanner"
        label="Barcode Scanner"
        class="barcode"
        @click="showBarcode = !showBarcode"
      />
      <q-btn
        v-if="$q.platform.is.mobile"
        color="secondary"
        icon="qr_code_scanner"
        label="Mobile Barcode Scanner"
        class="barcode"
        @click="scanImage"
      />
      <q-space />
      <q-btn
        push
        label="Add Selected Item(s)"
        icon="add"
        @click="selectItems()"
      />
    </q-card-section>

    <q-card-section v-show="showBarcode">
      <div class="hello">
        <StreamBarcodeReader
          @decode="(a, b, c) => onDecode(a, b, c)"
          @loaded="() => onLoaded()"
          style="width: 300px; height: 230px"
        ></StreamBarcodeReader>
      </div>
    </q-card-section>
   </q-card>
  </template>
  1. In the data, we also need to define the variable "showBarcode" to display the Scanning Process on the Web:
data() {
    return {
      text: "",
     showBarcode: ""
    };
  },

The complete code will look like this:

<template>
  <q-card>
 <q-card-section class="row">
      <q-btn
        color="primary"
        icon="search"
        label="Search"
        @click="searchItems()"
      />
      <q-btn
        v-if="$q.platform.is.desktop"
        color="secondary"
        icon="qr_code_scanner"
        label="Barcode Scanner"
        class="barcode"
        @click="showBarcode = !showBarcode"
      />
      <q-btn
        v-if="$q.platform.is.mobile"
        color="secondary"
        icon="qr_code_scanner"
        label="Mobile Barcode Scanner"
        class="barcode"
        @click="scanImage"
      />
      <q-space />
      <q-btn
        push
        label="Add Selected Item(s)"
        icon="add"
        @click="selectItems()"
      />
    </q-card-section>

    <q-card-section v-show="showBarcode">
      <div class="hello">
        <StreamBarcodeReader
          @decode="(a, b, c) => onDecode(a, b, c)"
          @loaded="() => onLoaded()"
          style="width: 300px; height: 230px"
        ></StreamBarcodeReader>
      </div>
    </q-card-section>
   </q-card>
  </template>

<script>
import { StreamBarcodeReader } from "vue-barcode-reader";

export default {
  name: "ScanBarcode",
 data() {
    return {
      text: "",
     showBarcode: ""
    };
  },
  methods: {
    scanBarcode() {
      console.log("scanning...");
    },
    onDecode(a, b, c) {
      console.log(a, b, c);
      this.text = a;
      if (this.id) clearTimeout(this.id);
      this.id = setTimeout(() => {
        if (this.text === a) {
          this.text = "";
        }
      }, 5000);
    },
    onLoaded() {
      console.log("load");
    },
scanImage() {
      cordova.plugins.barcodeScanner.scan(
        (result) => {
          this.text = result.text; // fill the variable text with the text of the barcode
        },
        (error) => {
          alert("Scanning failed: " + error);
        },
        {
          preferFrontCamera: true, // iOS and Android
          showFlipCameraButton: true, // iOS and Android
          showTorchButton: true, // iOS and Android
          torchOn: true, // Android, launch with the torch switched on (if available)
          saveHistory: true, // Android, save scan history (default false)
          prompt: "Place a barcode inside the scan area", // Android
          resultDisplayDuration: 500, // Android, display scanned text for X ms. 0 suppresses it entirely, default 1500
          //formats : "QR_CODE,PDF_417", // default: all but PDF_417 and RSS_EXPANDED
          orientation: "landscape", // Android only (portrait|landscape), default unset so it rotates with the device
          disableAnimations: true, // iOS
          disableSuccessBeep: true, // iOS and Android
        }
      );
  },
  components: {
    StreamBarcodeReader,
  },
};
</script>

<style lang="scss" scoped>
@media (min-width: 420px) {
  .barcode {
    margin-left: 10px;
  }
}
</style>

NOTES:

  1. In case you need to deep dive into the cordova-plugin-qr-barcode-scanner plugin, I attach the link of the complete documentation of the plugin: https://www.npmjs.com/package/cordova-plugin-qr-barcode-scanner

  2. Here is how you can build the quasar project which includes the plugin, you can follow it step by step: https://www.kevin7.net/post_detail/use-quasar-to-build-an-android-app

  3. In case you don't know where to look for other cordova plugins, here is the platform which will make your day: https://cordova.apache.org/plugins/?q=scanner&platforms=cordova-android%2Ccordova-ios%2Ccordova-browser

  4. In case you run into an issue of $q is undefined or relevant, you need to import quasar as stated in this URL: https://quasar.dev/options/platform-detection

TmRAaEx commented 2 years ago

I have the same issue but im not using cordova im just running vue in development and the website dosent even ask for permission to use camera on mobile devices