iT邦幫忙

2023 iThome 鐵人賽

DAY 21
0
Mobile Development

單人開發者之路:React Native 與 Expo 帶你從開發到上架系列 第 21

Day 21 - Expo Barcode Scanner實作手機QRCode掃描功能

  • 分享至 

  • xImage
  •  

相信大家對於二維條碼(QR Code)並不陌生
而在APP裡掃描QR Code
更是大幅提升使用方便性

本篇要來使用Expo官方提供的Expo BarCodeScanner
製作APP二維掃描器

※本篇只能使用實體設備測試,需要使用相機功能

Expo BarCodeScanner 簡介 & 安裝

官網說明:https://docs.expo.dev/versions/latest/sdk/bar-code-scanner/
版本:12.5.3

簡介

Expo BarCodeScanner 是 Expo 的一個功能模組,能在 React Native APP中輕鬆整合條碼掃描功能。這個模組提供了一個相對簡單的方式來掃描條碼

日常使用APP時,哪裡會看到相機掃描器?

  1. Iphone 桌面電量下滑選單就內建二維條碼掃描器
  2. 「發票+」電子發票掃描對獎
  3. Line、Instgram掃描加好友、追蹤
  4. 其他有需要一二維條碼掃描的APP

BarCode簡介、觀念

在開發前先來了解一下
日常會看到的一些條碼類型

一維條碼

https://ithelp.ithome.com.tw/upload/images/20230925/20130821sw07RS3CjN.png

  • EAN-13:這是一種廣泛使用的商品條碼,通常出現在商品包裝上。
  • CODE 128:常用於物流和倉儲管理,可識別產品、包裝和運輸訊息。
  • CODE 39:是一種常見的線性條碼,水、電、瓦斯、學費帳單皆由此條碼組成。

三種類型差別只在條碼線條編排方式與字串大小不同

二維條碼

https://ithelp.ithome.com.tw/upload/images/20230925/20130821FMcUiWf4Lt.png

  • QR Code:是一種二維條碼,可包含各種數據,如文字、URL、地理位置等。常用於支付方式,例如行動支付、電子發票等。
  • DataMatrix:又稱DM碼,是另一種二維條碼,通常用於追蹤和識別物品,並在醫療和製造行業中廣泛使用。

兩種類型差在圖示編排方法不同
(DataMatrix有明顯L型黑色實心框)

Expo官方也提供Supported formats
決定這些條碼類型是否支援
在實作功能前也請留意

BarCode 觀念

條碼的產生原理
簡單來說就是
「文字圖形化呈現」

也就是使用相機、條碼機在刷取時
其實是將條碼圖形化解析回文字
進而回傳到主機/手機端運作

Expo BarCodeScanner 安裝 & 使用方法

安裝

一樣是一行安裝指令
npx expo install expo-barcode-scanner

使用方法

引入Barcode元件

import { BarCodeScanner } from "expo-barcode-scanner";

宣告以下三項State

  • 是否打開相機
  • 條碼是否刷取完畢
  • QRCode內容是否正常
const [hasPermission, setHasPermission] = useState(null);
const [scanned, setScanned] = useState(false);
const [checkQRCodeOk, setcheckQRCodeOk] = useState(false);

監聽相機權限

useEffect(() => {
  (async () => {
    const { status } = await BarCodeScanner.requestPermissionsAsync();
    setHasPermission(status === "granted");
  })();
  
  //每次進入畫面重置相機
  setScanned(false);
  setcheckQRCodeOk(false);
}, []);

requestPermissionsAsync會要求使用者使用相機權限
若按不允許,要去應用程式設定
將APP的相機權限手動打開

https://ithelp.ithome.com.tw/upload/images/20230925/20130821o7vmiKjjgr.png
(如果是用Expo Go除錯,就是開啟Expo Go相機權限)

刷取條碼觸發事件

設定掃描完成setScanned(true)
驗證圖形條碼正確性

  • 確認是QRCode,不是其他類型條碼
    若想使用一維條碼可修改判斷為type.indexOf("Code39") < 0
  • 確認QRCode內容,只能刷取上方的範例QRCode
    想限定條碼內容是網頁的話,可以修改為data.indexOf("https://") < 0)
const handleBarCodeScanned = ({ type, data }) => {
  setScanned(true);
  if (type.indexOf("QRCode") < 0) {
    //驗證QRCode類型
    Alert.alert("錯誤", "不能刷取QR Code以外的類型!!!");
  } else if (data.indexOf("Hello") < 0) {
    //驗證QRCode內容
    Alert.alert("錯誤", "只能刷取特定QR Code內容");
  } else {
    Alert.alert("刷取完成", `BarCode類型:${type} \n BarCode內容:${data}`);
  }
};

刷取QRCode完成後的動作可自行利用調整

※若想修改邏輯判斷且自製條碼,條碼產生器網站附上
https://online-barcode-generator.net/

畫面

放入BarCodeScanner、重新掃描觸碰按鈕

return (
  <View className="flex-1">
    <BarCodeScanner
      onBarCodeScanned={scanned ? undefined : handleBarCodeScanned}
      className="flex-1"
    />
    {scanned && !checkQRCodeOk && (
      <TouchableOpacity
        className="bg-neutral-500 rounded-lg m-5"
        onPress={() => setScanned(false)}
      >
        <Text className="text-white text-center text-xl px-5 py-3">
          重新掃描
        </Text>
      </TouchableOpacity>
    )}
  </View>
);

Iphone實機效果如下圖:
https://ithelp.ithome.com.tw/upload/images/20230925/20130821dtDOck2U04.jpg

※Expo官方使用style={StyleSheet.absoluteFillObject}
將相機絕對位置填滿
沒有填滿的話,相機是不會出現的

上方程式有特別使用「重新掃描」功能
在TailWind CSS框架需使用className="flex-1"
這樣觸碰按鈕才能在畫面下方顯示


功能實作結束
本篇Snack完整程式碼附上:https://snack.expo.dev/@peter_lu/expoqrcodeexample
測試時請使用實體手機試玩,Web不支援相機功能

BarCodeScanner Component not supported on the web

NativeWind無法在Snack使用,樣式部分敬請見諒

Expo BarCodeScanner 缺點

無法限制相機掃描區域

Expo BarCodeScanner完全沒有樣式功能調整
因為滿版掃描常常會造成誤刷
部分業主會要求限制相機掃描位置(遮罩)

若真的想實現相機遮罩功能
可以參考外國大神使用Expo BarCodeScanner
使用此套件完成了相機遮罩功能

https://dzone.com/articles/react-native-qr-code-scanner-using-expo-barcode-sc
原理其實是安裝了react-native-barcode-mask做到遮罩效果
程式碼有使用到一些數學公式,在理解上要多花點時間

一定要釋放相機元件

曾經被測出一項問題是
只是滑到桌面又回去點APP
相機就不見了...

必須使用useEffect重新渲染畫面
才能解決問題


結語:
第一次學習相機相關功能
從Web轉APP的我,感到非常新奇

開發過程都是以實機測試
有時功能還沒完成,手機就先充電去了😂

本篇因為使用「相機」
上架時會有權限問題
屆時會在講解相關權限設定

下一篇要來持續介紹Expo套件

  1. Expo Speech 語音功能
  2. Expo Haptics 觸覺回饋
  3. React Native Vibration 震動
    Expo沒開發震動功能😑

在你掃描發票後,往往會有中獎聲、震動
每次敲鍵盤時APP會震動一下下
將逐一解析,這些功能是怎麼做出來的

今天同時也是發票開獎日
記得開啟發票APP對發票哦,祝大家中獎。


上一篇
Day 20 - React Native Picker Select手機版下拉選單製作
下一篇
Day 22 - Expo 語音功能、觸覺回饋、震動功能應用
系列文
單人開發者之路:React Native 與 Expo 帶你從開發到上架30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言