I tired a different way to implement qr code reading functionality and I want to share it with you. Since the general approach of using react-native-qrcode-scanner
, this package not updated recently or not maintained. So I went to try out this react-native-vision-camera package.
Package
yarn add react-native-vector-icons
yarn add react-native-vision-camera
Configuration
iOS
cd ios && pod install
info.plist
<key>NSCameraUsageDescription</key>
<string>$(PRODUCT_NAME) needs access to your Camera.</string>
Android
AndroidManifest.xml
<uses-permission android:name="android.permission.CAMERA" />
gradle.properties
VisionCamera_enableCodeScanner=true
HomePage
import React, { useState } from "react";
import {
StyleSheet,
Text,
View,
TouchableOpacity,
Dimensions,
} from "react-native";
import Ionicons from "react-native-vector-icons/Ionicons";
import QRScanner from "./qrScanner";
const dWidth = Dimensions.get("window").width;
const clr1 = "mediumseagreen";
const ScanQRPage = () => {
const [showQR, setShowQR] = useState(false);
const [qrCode, setQrCode] = useState("");
const openQRscanner = () => {
setShowQR(true);
};
const onQrRead = (qrtext) => {
setQrCode(qrtext);
setShowQR(false);
};
return (
<View style={styles.page}>
{qrCode ? (
<Text style={{ fontSize: 16, color: "black" }}>
{"QR Value \n" + qrCode}
</Text>
) : null}
<Ionicons
name={"scan-circle-outline"}
size={qrCode ? dWidth * 0.4 : dWidth * 0.75}
color={clr1}
/>
<TouchableOpacity onPress={() => openQRscanner()} style={styles.btn}>
<Text style={{ color: clr1 }}>Scan QR</Text>
</TouchableOpacity>
{showQR ? <QRScanner onRead={onQrRead} /> : null}
</View>
);
};
export default ScanQRPage;
const styles = StyleSheet.create({
page: {
flex: 1,
backgroundColor: "white",
alignItems: "center",
justifyContent: "space-evenly",
},
btn: {
backgroundColor: "transparent",
alignItems: "center",
borderRadius: 10,
paddingVertical: "3%",
width: "50%",
borderWidth: 2,
borderColor: clr1,
},
btnText: {
color: clr1,
},
});
QR Scanner / Reader Component
import React, { useState, useEffect } from "react";
import { StyleSheet, Text, TouchableOpacity, View } from "react-native";
import {
Camera,
useCameraDevice,
useCodeScanner,
} from "react-native-vision-camera";
import Ionicons from "react-native-vector-icons/Ionicons";
const QRScanner = (props) => {
const [hasPermission, setHasPermission] = useState(false);
const [refresh, setRefresh] = useState(false);
const device = useCameraDevice("back");
const codeScanner = useCodeScanner({
codeTypes: ["qr"],
onCodeScanned: (codes) => {
console.log(`onCodeScanned `, codes);
console.log(`onCodeScanned value`, codes[0].value);
props.onRead(codes[0].value);
},
});
useEffect(() => {
// exception case
setRefresh(!refresh);
}, [device, hasPermission]);
useEffect(() => {
const requestCameraPermission = async () => {
const permission = await Camera.requestCameraPermission();
console.log("Camera.requestCameraPermission ", permission);
setHasPermission(permission === "granted");
};
requestCameraPermission();
//if it is idle for 15 secs, it will be closed
setTimeout(() => {
props.onRead(null);
}, 15 * 1000);
}, []);
if (device == null || !hasPermission) {
return (
<View style={styles.page2}>
<Text style={{ backgroundColor: "white" }}>
Camera not available or not permitted
</Text>
</View>
);
}
return (
<View style={styles.page2}>
<Camera
codeScanner={codeScanner}
style={StyleSheet.absoluteFill}
device={device}
isActive={true}
/>
<View style={styles.backHeader}>
<TouchableOpacity
style={{ padding: 10 }}
onPress={() => {
props.onRead(null);
}}
>
<Ionicons name={"arrow-back-outline"} size={25} color={"snow"} />
</TouchableOpacity>
</View>
<View style={styles.footer}>
<TouchableOpacity
style={{
paddingVertical: 8,
paddingHorizontal: 10,
borderWidth: 1,
borderRadius: 5,
borderColor: "snow",
alignItems: "center",
}}
onPress={() => {
props.onRead(null);
}}
>
<Text style={{ color: "snow", fontSize: 14 }}>Close</Text>
</TouchableOpacity>
</View>
</View>
);
};
export default QRScanner;
const styles = StyleSheet.create({
page2: {
flex: 1,
position: "absolute",
top: 0,
width: 0,
height: "100%",
width: "100%",
alignItems: "center",
justifyContent: "center",
},
backHeader: {
backgroundColor: "#00000090",
position: "absolute",
top: 0,
left: 0,
right: 0,
padding: "2%",
height: "5%",
width: "100%",
alignItems: "flex-start",
justifyContent: "center",
},
footer: {
backgroundColor: "#00000090",
position: "absolute",
bottom: 0,
left: 0,
right: 0,
padding: "10%",
height: "20%",
width: "100%",
alignItems: "center",
justifyContent: "center",
},
});
On Success
Thank you.
Source code here
Tags: #javascript, #react, #react-native, #android, #ios, #qrcode, #qrscan, #qrread, #mobile
Top comments (2)
I'm getting suck with this meanwhile midnight. Thanks for saving my life and sleeping time!
i am glad