moaazsidat / react-native-qrcode-scanner

A QR code scanner component for React Native.
MIT License
2.03k stars 512 forks source link

Black screen when calling modal with QRScanner on Android devices #349

Open HerickRaposo opened 3 years ago

HerickRaposo commented 3 years ago

What's happening?

Hello everyone, how are you, in my project using a webview that includes actions performed from the change of state of the url. when necessary, the qr code reading function is triggered, activating the visibility of the modal where the scanner is. Many times when loading the component, the camera screen goes black, preventing the scanner.

I've tried solutions like useIsFocusd but without success. Note that user permissions have already been granted. Usually the problem shows up on the first run after giving permission, but this is not a rule

IMG_20210819_134045

How can it be reproduced?

For to test i used Xiaomi Redmi Note 9t, Mi 8 Lite and Moto G7 Play To reproduce it will be necessary to use the following code:

App code:

 import React, { useState, useEffect, useRef } from 'react';
import { Text, View, StatusBar, Platform, TouchableOpacity, Modal } from 'react-native';
import { WebView } from 'react-native-webview';
import { ActivityIndicator } from 'react-native';
import { useNavigation } from '@react-navigation/native';
import { Permission } from '../services/AppPermissions';
import QRCodeScanner from 'react-native-qrcode-scanner';
import genericStyles from '../styles/GenericStyles';
import styles from '../styles/scanStyle'
import Icon from 'react-native-vector-icons/MaterialIcons';

export default function WebViewUsrLogado(props) {

  /* ==========================> Variaveis utilizadas <========================= */

  const propriedade = props.route.params.url
  const webViewRef = useRef(null)
  const statusBarRef = useRef(null)
  const [cameraGranted, setCameraGranted] = useState(false);
  const [newurl, setNewUrl] = useState(null);
  const navigation = useNavigation();
  const isIOS = Platform.OS === 'ios' ? true : false
  const Spinner = () => (
    <View style={genericStyles.activityContainer}>
      <ActivityIndicator size="large" color="#f29900" />
    </View>
  );
  const [state, setState] = useState({
      scan: false,
      ScanResult: false,
      result: null
  });
  const scanner = useRef(null)
  const [modalVisible, setModalVisible] = useState(false);

  /* ==============================> Controllers <============================= */

  //Verificação de permissão
  const handleMPermission = async () => {
    if (Platform.OS === 'ios') {
      const permissionCamera = await Permission.handleCameraPermission()
      setCameraGranted(permissionCamera)
      const permission = await Permission.handleMAllPermission()
    } else {
      const permission = await Permission.handleMAllPermission()
      setCameraGranted(permission)
    }
  };

  useEffect(() => {
    handleMPermission()
  }, []);

  /* ===============================> Functions <=============================== */

 function voltar(url){
    setNewUrl(url)
    if (url.includes('qrscanner') || url.includes('barcodeScanner')) {
      setModalVisible(true)
      return false;
    } else {
      console.log(url)
      return true
    }
  }

  /* ========================> Functions QRScanner <======================== */

  const onSuccess = async(e) => {
    setResultScan(e.data);

    const dadosPost = {
      uuid : uuid,
      resposta: resultScan
    }
    const jsonEnvio = JSON.stringify(dadosPost);
    setModalVisible(!modalVisible);
    apiServices.fetchResultScan(jsonEnvio).then((responseJSON)=>{
      if (responseJSON.mensagem == 'Sucesso') {
        webViewRef.current.reload();
      } else {
        setModalVisible(modalVisible);
      }
    });
  }

  /* ========================> Retorno de Visualização <======================== */
  if (cameraGranted) {
    return (
      <View style={genericStyles.container}>
        <StatusBar backgroundColor={genericStyles.colors.BlueBg} />
        {isIOS &&
          <TouchableOpacity onPress={backButtonHandler}>
            <View style={genericStyles.linha} >
              <Icon name="arrow-back-ios" size={30} color="#fff" style={genericStyles.buttonIcon}/>
              <Text style={genericStyles.textButton} >Voltar</Text>
            </View>
          </TouchableOpacity>
        }
        <WebView
          source={{ uri: propriedade }}
          ref={webViewRef}
          style={genericStyles.view}
          originWhitelist={['*']}
          allowsInlineMediaPlayback
          javaScriptEnabled
          scalesPageToFit
          mediaPlaybackRequiresUserAction={false}
          javaScriptEnabledAndroid
          useWebkit
          startInLoadingState={true}
          renderLoading={Spinner}
          onShouldStartLoadWithRequest={(event)=>{
            return voltar(event.url)
          }}
        />
        <Modal 
          animationType="slide"
          transparent={true}
          visible={modalVisible}
          onRequestClose={() => {
            setModalVisible(!modalVisible);
          }}
        >
          <QRCodeScanner
            containerStyle={styles.containerStyle}
            cameraStyle={[styles.cameraStyle]}

            markerStyle={{borderColor:'#fff', height:'95%', width:100}}
            reactivate={true}
            showMarker={true}
            ref={scanner}
            onRead={onSuccess}
            topContent={
              <Text style={{color: '#fff'}}>
                Please move your camera 
              </Text>
            }
            bottomContent={
              <View>
                <TouchableOpacity style={styles.buttonScan} 

                    onPress={() => setModalVisible(!modalVisible)}>
                    <View style={styles.buttonWrapper}>
                        <Text style={{color:genericStyles.colors.BlueBg}}>Scan QR Code</Text>
                    </View>
                </TouchableOpacity>
              </View>
            }
          />
        </Modal>
      </View>
    );
  } else {
    return <Text>No access to camera</Text>;
  }
}

Class Permissions Code:

import { Platform } from 'react-native';
import {check, PERMISSIONS, request, RESULTS} from 'react-native-permissions';

class AppPermission  {
    handleCameraPermission = async () => {
        const permission = Platform.OS === 'ios' ? PERMISSIONS.IOS.CAMERA : PERMISSIONS.ANDROID.CAMERA;
        return await this.verifyPermission(permission);  
    };
    handleAcessExternalStoragePermission = async () => {
        const permission = Platform.OS === 'ios' ? PERMISSIONS.IOS.PHOTO_LIBRARY : PERMISSIONS.ANDROID.WRITE_EXTERNAL_STORAGE;
        return await this.verifyPermission(permission);  
    };

    handlePhotoLibraryAddPermission = async () => {
        return await this.verifyPermission(PERMISSIONS.IOS.PHOTO_LIBRARY_ADD_ONLY);  
    };
    handleMicrophonePermission = async () => {
        return await this.verifyPermission(PERMISSIONS.IOS.MICROPHONE);   
    };

    verifyPermission = async (permission) => {
        const res = await check(permission);
        if (res === RESULTS.GRANTED) {
            return true;
        } else if (res === RESULTS.DENIED) {
            const res2 = await request(permission);
            return (res2 === RESULTS.GRANTED) ? true : false;
        }  
    }

    handleMAllPermission = async () => {
        if (Platform.OS == `ios`) {
            return this.handleAcessExternalStoragePermission().then(()=>{
                return this.handlePhotoLibraryAddPermission().then(()=>{
                    this.handleMicrophonePermission();
                });
            });           
        } else {
            return this.handleCameraPermission().then(()=>{
                return this.handleAcessExternalStoragePermission();
            });
        }
    };
}
const Permission = new AppPermission();
export {Permission};

Build details?

OS:Android react: "17.0.1", react-native: "0.64.2", "@react-navigation/native": "^5.9.8", "@react-navigation/stack": "^5.14.9", "react-native-camera": "^4.0.3", "react-native-permissions": "^3.0.5", "react-native-qrcode-scanner": "^1.5.4", "react-native-webview": "^11.13.0"

pankajnegi1893 commented 3 years ago

Are you able to fix this issue ? I am also getting the same issue in Android 11

HerickRaposo commented 3 years ago

Unfortunately no. I did everything to solve it but didn't make any progress

kaurjvpld commented 2 years ago

Facing the same issue.

JQbss commented 2 years ago

Try android:hardwareAccelerated="true", with false it's not working

BraveEvidence commented 1 year ago

This will help you https://www.youtube.com/watch?v=sE0MEyFA7E4&list=PLQhQEGkwKZUrempLnmxjt7ZCZJu1W3p2i&index=10